From 53a267424a7d9f225245cf535a8ca6ce75f919ec Mon Sep 17 00:00:00 2001 From: lunaticbum <> Date: Mon, 18 Nov 2024 17:35:40 +0900 Subject: [PATCH] ... --- app/build.gradle.kts | 1 + app/src/main/AndroidManifest.xml | 18 ++- .../bums/lunatic/launcher/LauncherActivity.kt | 111 ++++++++++++++---- .../bums/lunatic/launcher/apps/AppsAdapter.kt | 3 + .../bums/lunatic/launcher/feeds/Feeds.kt | 17 ++- .../helpers/HeadsetActionButtonReceiver.kt | 68 +++++++++++ .../lunatic/launcher/home/LauncherHome.kt | 14 ++- .../launcher/home/adapters/RssItemAdapter.kt | 13 +- .../launcher/workers/MediaButtonService.kt | 110 +++++++++++++++++ app/src/main/res/layout/feeds.xml | 1 + app/src/main/res/layout/launcher_activity.xml | 12 +- 11 files changed, 325 insertions(+), 43 deletions(-) create mode 100644 app/src/main/kotlin/bums/lunatic/launcher/helpers/HeadsetActionButtonReceiver.kt create mode 100644 app/src/main/kotlin/bums/lunatic/launcher/workers/MediaButtonService.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ab0df177..17ae02e3 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -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") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0b792183..0ab8b876 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -52,7 +52,8 @@ - + + @@ -120,7 +121,22 @@ + + + + + + + + + + + + (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) } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/apps/AppsAdapter.kt b/app/src/main/kotlin/bums/lunatic/launcher/apps/AppsAdapter.kt index 3f3ee817..c8865ebf 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/apps/AppsAdapter.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/apps/AppsAdapter.kt @@ -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("pkgName == $0",item.pkgName).find() if(result.size > 0) { val app = result.first() diff --git a/app/src/main/kotlin/bums/lunatic/launcher/feeds/Feeds.kt b/app/src/main/kotlin/bums/lunatic/launcher/feeds/Feeds.kt index 0e1d5667..0ad618b5 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/feeds/Feeds.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/feeds/Feeds.kt @@ -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? = null var mRssAdapter2 : RssAdapter? = 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("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("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]}") diff --git a/app/src/main/kotlin/bums/lunatic/launcher/helpers/HeadsetActionButtonReceiver.kt b/app/src/main/kotlin/bums/lunatic/launcher/helpers/HeadsetActionButtonReceiver.kt new file mode 100644 index 00000000..21a16e74 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/helpers/HeadsetActionButtonReceiver.kt @@ -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 + } + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome.kt index 2da93e07..13069422 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome.kt @@ -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) { diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt index b6755b58..b11ef8ea 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt @@ -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) diff --git a/app/src/main/kotlin/bums/lunatic/launcher/workers/MediaButtonService.kt b/app/src/main/kotlin/bums/lunatic/launcher/workers/MediaButtonService.kt new file mode 100644 index 00000000..633ad71b --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/workers/MediaButtonService.kt @@ -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?>) { +//// } +//// +//// 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 +//// } +// } +//} \ No newline at end of file diff --git a/app/src/main/res/layout/feeds.xml b/app/src/main/res/layout/feeds.xml index ff9779bf..e24b818f 100644 --- a/app/src/main/res/layout/feeds.xml +++ b/app/src/main/res/layout/feeds.xml @@ -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"> - - + + + + + +