【问题标题】:How to show something when an android app is not active/focused?如何在 Android 应用程序未激活/未聚焦时显示内容?
【发布时间】:2022-11-15 18:06:03
【问题描述】:

我想打开我的应用程序并从中查看随处可用的内容(例如小部件),而不仅仅是在打开应用程序时
例子:

请注意,我在桌面页面上,应用程序未打开,但在后台处于活动状态,并在各处显示带有 Hello 文本的“小部件”

【问题讨论】:

    标签: android kotlin android-jetpack-compose android-view


    【解决方案1】:

    为AndroidManifest.xml添加android.permission.SYSTEM_ALERT_WINDOW权限

    // AndroidManifest.xml
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        package="com.freephoenix888.savemylife"> 
        // Something else
    
        <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
        // Something else
    </manifest>
    
    

    注意:不要忘记向用户请求此权限 Documentation

    创建一个实现 SavedStateRegistryOwner 的类

    internal class MyLifecycleOwner : SavedStateRegistryOwner {
    
        private var mLifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
        private var mSavedStateRegistryController: SavedStateRegistryController = SavedStateRegistryController.create(this)
    
        val isInitialized: Boolean
            get() = true
        override val savedStateRegistry: SavedStateRegistry
            get() = mSavedStateRegistryController.savedStateRegistry
    
        override fun getLifecycle(): Lifecycle {
            return mLifecycleRegistry
        }
    
        fun setCurrentState(state: Lifecycle.State) {
            mLifecycleRegistry.currentState = state
        }
    
        fun handleLifecycleEvent(event: Lifecycle.Event) {
            mLifecycleRegistry.handleLifecycleEvent(event)
        }
    
        fun performRestore(savedState: Bundle?) {
            mSavedStateRegistryController.performRestore(savedState)
        }
    
        fun performSave(outBundle: Bundle) {
            mSavedStateRegistryController.performSave(outBundle)
        }
    }
    

    在活动或服务中添加您的视图

    val layoutFlag: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
    } else {
        WindowManager.LayoutParams.TYPE_PHONE
    }
    
    val params = WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        layoutFlag,
        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT
    )
    
    /* For views (not compose views)
    val floatView = (getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater).inflate(R.layout.view_service_float, null)
    */
    
    val composeView = ComposeView(this)
    composeView.setContent {
        Text(
            text = "Hello",
            color = Color.Black,
            fontSize = 50.sp,
            modifier = Modifier
                .wrapContentSize()
                .background(Color.Green)
        )
    }
    
    val viewModelStore = ViewModelStore()
    val lifecycleOwner = MyLifecycleOwner()
    lifecycleOwner.performRestore(null)
    lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
    ViewTreeLifecycleOwner.set(composeView, lifecycleOwner)
    ViewTreeViewModelStoreOwner.set(composeView) { viewModelStore }
    composeView.setViewTreeSavedStateRegistryOwner(lifecycleOwner)
    
    windowManager.addView(composeView, params)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-07
      相关资源
      最近更新 更多