This commit is contained in:
lunaticbum 2024-11-18 17:35:40 +09:00
parent caf5601a71
commit 53a267424a
11 changed files with 325 additions and 43 deletions

View File

@ -105,6 +105,7 @@ dependencies {
implementation("com.github.delight-im:Android-AdvancedWebView:v3.2.1")
implementation(project(":library"))
implementation(project(":utils"))
implementation ("androidx.media:media:1.7.0")
// implementation ("me.everything:providers-android:1.0.1")
// implementation ("me.everything:providers-core:1.0.1")
// implementation ("androidx.window:window:1.0.0")

View File

@ -52,7 +52,8 @@
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
@ -120,7 +121,22 @@
</intent-filter>
</activity>
<receiver android:name=".helpers.HeadsetActionButtonReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter
android:priority="10000">
<action android:name="android.intent.action.MEDIA_BUTTON"/>
</intent-filter>
</receiver>
<!-- <service android:name=".MediaButtonService"-->
<!-- android:exported="true">-->
<!-- <intent-filter>-->
<!-- <action android:name="android.intent.action.MEDIA_BUTTON" />-->
<!-- <action android:name="android.media.browse.MediaBrowserService" />-->
<!-- </intent-filter>-->
<!-- </service>-->
<service
android:name=".feeds.rss.RssService"

View File

@ -43,6 +43,8 @@ import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.telephony.TelephonyManager
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.WindowInsets
import android.view.WindowManager
@ -86,6 +88,7 @@ import bums.lunatic.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_FIRST_LAUNCH
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
import bums.lunatic.launcher.helpers.Constants.Companion.widgetHostId
import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver
import bums.lunatic.launcher.helpers.PrefBoolean
import bums.lunatic.launcher.helpers.PrefHelper
import bums.lunatic.launcher.helpers.PrefLong
@ -299,6 +302,17 @@ internal class LauncherActivity : AppCompatActivity() {
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(LocationGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
LocationGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<LocationGetter>(PrefLong.locationTimePeriod.get(), TimeUnit.MINUTES)
.addTag(LocationGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
}
@ -321,6 +335,51 @@ internal class LauncherActivity : AppCompatActivity() {
BLog.LOGE("onConfigurationChanged newConfig?.screenHeightDp >> ${newConfig?.screenHeightDp}")
isOpendFold = (newConfig.screenWidthDp * 1.1f) > newConfig.screenHeightDp
}
var actionButtonPressX = 0f
var actionButtonPressY = 0f
override fun dispatchGenericMotionEvent(ev: MotionEvent?): Boolean {
if (ev?.device?.name?.contains("BLE-M3") == true) {
BLog.LOGE("keyEvent >>>>> dispatchGenericMotionEvent ${ev}")
ev?.action?.let { action ->
when(action) {
MotionEvent.ACTION_HOVER_ENTER -> {
return false
}
MotionEvent.ACTION_HOVER_MOVE ->{return false}
MotionEvent.ACTION_BUTTON_PRESS ->{
if (actionButtonPressX * actionButtonPressY == 0f) {
actionButtonPressX = ev.x ?: 0f
actionButtonPressY = ev.y ?: 0f
}
return true
}
MotionEvent.ACTION_BUTTON_RELEASE ->{
if (actionButtonPressY == ev.y) {
if (actionButtonPressX.minus(ev.x ?: 0f) > 0f) {
BLog.LOGE("Arrow Right Click")
} else {
BLog.LOGE("Arrow Left Click")
}
} else {
if (actionButtonPressY.minus(ev.y ?: 0f) > 0f) {
BLog.LOGE("Arrow Down Click")
} else {
BLog.LOGE("Arrow Up Click")
}
}
return false
}
MotionEvent.ACTION_HOVER_EXIT ->{
actionButtonPressX = 0f
actionButtonPressY = 0f
return false
}
else -> {return false}
}
}
}
return super.dispatchGenericMotionEvent(ev)
}
override fun onNewIntent(intent: Intent?) {
@ -415,6 +474,7 @@ internal class LauncherActivity : AppCompatActivity() {
appWidgetManager = AppWidgetManager.getInstance(applicationContext)
appWidgetHost = WidgetHost(applicationContext, widgetHostId)
appWidgetHost?.startListening()
HeadsetActionButtonReceiver.register(this)
/* if this is the first launch,
then remember the event and show the welcome dialog */
@ -568,25 +628,10 @@ internal class LauncherActivity : AppCompatActivity() {
}
}
val feeds by lazy { Feeds() }
val appDrawer by lazy { AppDrawer() }
fun switchFeeds(){
if(supportFragmentManager.findFragmentByTag("Feeds") == null){
val transaction = supportFragmentManager.beginTransaction()
transaction.add(R.id.feeds, feeds,"Feeds")
transaction.commit()
}
if(binding.feeds.visibility == View.GONE) {
binding.home.visibility = View.GONE
binding.feeds.visibility = View.VISIBLE
supportFragmentManager.beginTransaction().show(feeds).commit()
} else {
binding.feeds.visibility = View.GONE
binding.home.visibility = View.VISIBLE
supportFragmentManager.beginTransaction().hide(feeds).commit()
}
}
fun switchAppDrawer() {
if(supportFragmentManager.findFragmentByTag("AppDrawer") == null){
val transaction = supportFragmentManager.beginTransaction()
@ -639,9 +684,10 @@ internal class LauncherActivity : AppCompatActivity() {
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (binding.feeds.visibility == View.VISIBLE) {
switchFeeds()
} else if (binding.appDrawer.visibility == View.VISIBLE) {
// if (binding.feeds.visibility == View.VISIBLE) {
// switchFeeds()
// } else
if (binding.appDrawer.visibility == View.VISIBLE) {
switchAppDrawer()
} else if (binding.home.visibility == View.VISIBLE) {
// switchAppDrawer()
@ -900,6 +946,10 @@ internal class LauncherActivity : AppCompatActivity() {
}
}
fun switchFeeds() {
Feeds().show(supportFragmentManager, "Feeds")
}
inner class MyJavaScriptInterface(val webView: WebView) {
@JavascriptInterface
fun sendValueFromHtml(result: String) {
@ -998,7 +1048,18 @@ fun openNews(schemeString : String) {
lActivity?.startActivity(mapIntent)
}
fun openClient(url : String){
val browserIntent = Intent(
Intent.ACTION_VIEW, Uri.parse(
url
)
)
browserIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
// browserIntent.setPackage("org.chromium.webapk.a74a80967bc356126_v2")
// org.chromium.webapk.a74a80967bc356126_v2/org.chromium.webapk.shell_apk.h2o.H2OOpaqueMainActivity
// browserIntent.setComponent(ComponentName("org.chromium.webapk.a74a80967bc356126_v2","org.chromium.webapk.shell_apk.h2o.H2OOpaqueMainActivity"))
lActivity?.startActivity(browserIntent)
}
fun openYouTube(schemeString : String) {
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
@ -1022,11 +1083,11 @@ fun openReddit(schemeString : String) {
fun openDotax(schemeString : String) {
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW)
// mapIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
// mapIntent.addCategory(Intent.CATEGORY_BROWSABLE)
// mapIntent.setPackage("net.daum.android.cafe")
mapIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
mapIntent.addCategory(Intent.CATEGORY_BROWSABLE)
mapIntent.setPackage("net.daum.android.cafe")
mapIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
mapIntent.setPackage("com.android.chrome")
// mapIntent.setPackage("com.android.chrome")
mapIntent.setData(gmmIntentUri)
lActivity?.startActivity(mapIntent)
}

View File

@ -33,6 +33,7 @@ import bums.lunatic.launcher.R
import bums.lunatic.launcher.apps.IconPackManager.Companion.getDrawableIconForPackage
import bums.lunatic.launcher.databinding.AppsChildBinding
import bums.lunatic.launcher.model.AppInfo
import bums.lunatic.launcher.utils.BLog
import bums.lunatic.launcher.workers.WorkersDb
import io.realm.kotlin.ext.query
import kotlinx.coroutines.MainScope
@ -80,6 +81,8 @@ internal class AppsAdapter(
setOnClickListener {
WorkersDb.getRealm().apply {
writeBlocking {
BLog.LOGE("item.pkgName >>>> ${item.pkgName
}")
var result = query<AppInfo>("pkgName == $0",item.pkgName).find()
if(result.size > 0) {
val app = result.first()

View File

@ -46,6 +46,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.PopupMenu
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
@ -99,12 +100,19 @@ import java.nio.charset.Charset
import java.util.Base64
internal class Feeds : Fragment() , CommadCallabck {
internal class Feeds : DialogFragment() , CommadCallabck {
private lateinit var binding: FeedsBinding
private val requestCodeString = "requestCode"
var mRssAdapter : RssAdapter<RssDataInterface>? = null
var mRssAdapter2 : RssAdapter<jGuruTag>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.FilterFullScreenDialog)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = FeedsBinding.inflate(inflater, container, false)
mRssAdapter = RssAdapter(requireContext())
@ -261,13 +269,18 @@ internal class Feeds : Fragment() , CommadCallabck {
home?.queryInfos(keyword = cmd[1])
}
"jf" -> {
CoroutineScope(Dispatchers.IO).launch {
consoleLog("${cmd[0]} Start ${cmd[1]}")
String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9qYXZtb3N0LnRvL2xhdGVzdC11cGRhdGVzCg==".toByteArray())).getJ().let { doc -> FeedParseManager.parse(doc){consoleLog(it)} }
consoleLog("current j req() ${WorkersDb.getRealm().query<RssData>("category == $0", RssDataType.GURU.name).find().size}")
consoleLog("${cmd[0]} END ${cmd[1]}")
}
CoroutineScope(Dispatchers.IO).launch {
consoleLog("${cmd[0]} Start ${cmd[1]}")
String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9qYXZtb3N0LnRvL3NlYXJjaC9tb3ZpZS8lcw==".toByteArray())),cmd[1]).getJ().let { doc -> FeedParseManager.parse(doc){consoleLog(it)} }
consoleLog("current j req() ${WorkersDb.getRealm().query<RssData>("category == $0", RssDataType.GURU.name).find().size}")
consoleLog("${cmd[0]} END ${cmd[1]}")
}
CoroutineScope(Dispatchers.IO).launch {
consoleLog("on Cmd JF with MOST")
consoleLog("${cmd[0]} Start ${cmd[1]}")

View File

@ -0,0 +1,68 @@
package bums.lunatic.launcher.helpers
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.view.KeyEvent
import bums.lunatic.launcher.utils.BLog
import java.util.Timer
import java.util.TimerTask
class HeadsetActionButtonReceiver : BroadcastReceiver() {
interface Delegate {
fun onMediaButtonSingleClick()
fun onMediaButtonDoubleClick()
}
override fun onReceive(context: Context?, intent: Intent?) {
BLog.LOGE("HeadsetActionButtonReceiver keyEvent >>>>> ${intent}")
if (intent == null || delegate == null || Intent.ACTION_MEDIA_BUTTON != intent.action) return
val keyEvent = intent.extras!![Intent.EXTRA_KEY_EVENT] as KeyEvent?
if (keyEvent == null || keyEvent.action != KeyEvent.ACTION_DOWN) return
BLog.LOGE("HeadsetActionButtonReceiver keyEvent >>>>> ${keyEvent}")
counter++
if (doublePressTimer != null) {
doublePressTimer!!.cancel()
}
doublePressTimer = Timer()
doublePressTimer!!.schedule(object : TimerTask() {
override fun run() {
if (counter == 1) {
delegate!!.onMediaButtonSingleClick()
} else {
delegate!!.onMediaButtonDoubleClick()
}
counter = 0
}
}, doublePressSpeed.toLong())
}
companion object {
var delegate: Delegate? = null
private var mAudioManager: AudioManager? = null
private var mRemoteControlResponder: ComponentName? = null
private const val doublePressSpeed = 300 // double keypressed in ms
private var doublePressTimer: Timer? = null
private var counter = 0
fun register(context: Context) {
mAudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager?
mRemoteControlResponder = ComponentName(context, HeadsetActionButtonReceiver::class.java)
mAudioManager?.registerMediaButtonEventReceiver(mRemoteControlResponder)
}
fun unregister(context: Context?) {
mAudioManager?.unregisterMediaButtonEventReceiver(mRemoteControlResponder)
if (doublePressTimer != null) {
doublePressTimer!!.cancel()
doublePressTimer = null
}
}
}
}

View File

@ -61,6 +61,7 @@ import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
import bums.lunatic.launcher.R
import bums.lunatic.launcher.behavior.Behavior
import bums.lunatic.launcher.databinding.LauncherHomeBinding
import bums.lunatic.launcher.feeds.Feeds
import bums.lunatic.launcher.helpers.Constants.Companion.BOTTOM_SHEET_TAG
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_LOCK_METHOD
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_TODO_LOCK
@ -865,7 +866,7 @@ internal class LauncherHome : Fragment() {
/* show weather */
// WeatherExecutor(settingsPrefs).generateWeatherString(binding.weather)
}
// binding.root.visibility = View.VISIBLE
}
@ -873,6 +874,7 @@ internal class LauncherHome : Fragment() {
super.onPause()
/* unregister battery changes */
if (shouldResume) requireContext().unregisterReceiver(batteryReceiver)
// binding.root.visibility = View.GONE
}
@ -985,7 +987,11 @@ internal class LauncherHome : Fragment() {
if(targetView.equals(binding.functionLayer)){
targetView?.performHapticFeedback(HapticFeedbackConstants.CONFIRM)
when(fingers) {
1->lActivity?.switchFeeds()
1-> {
lActivity?.switchFeeds()
return true
}
//
else ->{}
}
} else if (targetView.equals(binding.time) && fingers == 2) {
@ -1089,7 +1095,7 @@ internal class LauncherHome : Fragment() {
// searchData()
// }
else {
QuickAccess().show(fragManager, BOTTOM_SHEET_TAG)
// QuickAccess().show(fragManager, BOTTOM_SHEET_TAG)
}
}
}
@ -1175,6 +1181,8 @@ internal class LauncherHome : Fragment() {
)
}
/* authentication callback for TodoManager lock */
private val authenticationCallback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {

View File

@ -35,6 +35,8 @@ import bums.lunatic.launcher.home.RssViewer
import bums.lunatic.launcher.model.RssData
import bums.lunatic.launcher.model.RssDataInterface
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.openClient
import bums.lunatic.launcher.openDotax
import bums.lunatic.launcher.openReddit
import bums.lunatic.launcher.openYouTube
import bums.lunatic.launcher.utils.BLog
@ -102,17 +104,16 @@ internal class RssItemAdapter (
}
}
RssDataType.REDDIT -> {
AwesomeWebView.Builder(lActivity!!)
.showIconClose(true).showIconBack(false).showProgressBar(true).webViewMixedContentMode(0)
.show(rss.originPage!!)
openReddit(rss.originPage())
}
RssDataType.DOTAX -> {
AwesomeWebView.Builder(lActivity!!)
.showIconClose(true).showIconBack(false).showProgressBar(true).webViewMixedContentMode(0)
.show(rss.originPage!!)
openDotax(rss.originPage())
}
RssDataType.YOUTUBE -> { openYouTube(rss.originPage())
}
RssDataType.CLIEN -> {
openClient(rss.originPage())
}
else -> {
AwesomeWebView.Builder(lActivity!!)
.showIconClose(true).showIconBack(false).showProgressBar(true).webViewMixedContentMode(0)

View File

@ -0,0 +1,110 @@
//package bums.lunatic.launcher.workers
//
//import android.annotation.SuppressLint
//import android.app.Notification
//import android.app.NotificationChannel
//import android.app.NotificationManager
//import android.content.Context
//import android.content.Intent
//import androidx.media.session.MediaButtonReceiver
//import android.support.v4.media.session.PlaybackStateCompat
//import android.util.Log
//import android.widget.Toast
//import androidx.media.MediaBrowserServiceCompat
//import androidx.core.app.NotificationCompat
//import bums.lunatic.launcher.utils.BLog
//
//
//class MediaButtonService : MediaBrowserServiceCompat() {
//
// @SuppressLint("ForegroundServiceType")
// override fun onCreate() {
// super.onCreate()
//
// val CHANNEL_ID = "media_button_channel"
// val channel = NotificationChannel(
// CHANNEL_ID, "MediaButtonClick",
// NotificationManager.IMPORTANCE_DEFAULT
// )
// (getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager)?.createNotificationChannel(channel)
//
// val notification: Notification = NotificationCompat.Builder(this, CHANNEL_ID)
// .setContentTitle("")
// .setContentText("").build()
// startForeground(MEDIA_BUTTON_NOTIFICATION_ID, notification)
//
// // Create a MediaSessionCompat
// mediaSession = MediaSessionCompat(getBaseContext(), TAG)
//
// // Enable callbacks from MediaButtons and TransportControls
// mediaSession?.setFlags(
// MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or
// MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
// )
//
// // Set an initial PlaybackState with ACTION_PLAY, so media buttons can start the player
// stateBuilder = NotificationCompat.Builder(this,CHANNEL_ID)
// stateBuilder?.setActions(
// PlaybackStateCompat.ACTION_PLAY or
// PlaybackStateCompat.ACTION_PLAY_PAUSE
// )
// mediaSession?.setPlaybackState(stateBuilder.build())
//
// // MySessionCallback() has methods that handle callbacks from a media controller
// mediaSession?.setCallback(mediaSessionCallback)
//
// // Set the session's token so that client activities can communicate with it.
// setSessionToken(mediaSession?.getSessionToken())
// mediaSession?.setActive(true)
// }
//
// override fun onDestroy() {
// super.onDestroy()
// }
//
//// @Nullable
//// fun onGetRoot(
//// clientPackageName: String,
//// clientUid: Int,
//// @Nullable rootHints: Bundle?
//// ): BrowserRoot? {
//// return null
//// }
////
//// fun onLoadChildren(parentId: String, result: Result<List<MediaItem?>?>) {
//// }
////
//// fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
//// MediaButtonReceiver.handleIntent(mediaSession, intent)
//// return super.onStartCommand(intent, flags, startId)
//// }
//
// var mediaSessionCallback: MediaSessionCompat.Callback = object : MediaSessionCompat.Callback() {
// override fun onMediaButtonEvent(mediaButtonEvent: Intent?): Boolean {
// Log.i(TAG, "❤️ XIO, media button event!!!! ")
// try {
// mediaButtonEvent?.extras?.keySet()?.forEach {
// BLog.LOGE()
// }
// } catch (e : Exception) {
//
// }
//// if (controlPanel == null) return false
//// isFirstServiceCall = !isFirstServiceCall
//// if (isFirstServiceCall) controlPanel.onDoubleTap()
// Toast.makeText(getBaseContext(), "MEDIA BUTTON EVENT", Toast.LENGTH_SHORT).show()
// return false
// }
// }
//
// companion object {
// private const val TAG = "MediaButtonService"
// private const val MEDIA_BUTTON_NOTIFICATION_ID = 2
//
//// private var controlPanel: AcControlPanel? = null
////
//// fun setControlPanel(controlPanel: AcControlPanel?) {
//// Companion.controlPanel = controlPanel
//// }
// }
//}

View File

@ -4,6 +4,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
android:orientation="vertical">
<com.google.android.material.button.MaterialButtonToggleGroup

View File

@ -20,12 +20,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<FrameLayout
android:id="@+id/feeds"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<!-- <FrameLayout-->
<!-- android:id="@+id/feeds"-->
<!-- android:visibility="gone"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent" >-->
<!-- </FrameLayout>-->
<FrameLayout
android:visibility="gone"