Android保持屏幕常亮:Activity A启动的Activity B如何强制常亮
实现方案(无需唤醒锁,无额外权限)
你之前用android:keepScreenOn="true"的方案本身是官方推荐的屏幕常亮实现,比唤醒锁安全得多,不需要申请权限,也不会出现忘记释放导致的异常耗电问题,下面两种方案都基于该特性实现,不会影响其他模块启动Activity B的原有逻辑:
方案1:跳转传参标记(改造成本最低,推荐)
适合你可以修改Activity B代码的场景:
- 第一步:在Activity A启动B时,给Intent添加专属标记
// Activity A中启动B的代码 val intent = Intent(this, ActivityB::class.java).apply { putExtra("FORCE_KEEP_SCREEN_ON_FROM_A", true) } startActivity(intent)
- 第二步:在Activity B的
onCreate中判断标记,动态设置常亮
// Activity B的onCreate方法中 if (intent.getBooleanExtra("FORCE_KEEP_SCREEN_ON_FROM_A", false)) { // 效果和XML中配置android:keepScreenOn="true"完全一致 window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) }
如果需要在A销毁后自动取消B的常亮,可以在B的onResume中增加栈检查:
override fun onResume() { super.onResume() // 检查Activity A是否还在当前任务栈中 val taskInfo = (getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) .getRunningTasks(1)[0] val hasActivityA = taskInfo.baseActivity?.className == ActivityA::class.java.name if (!hasActivityA) { window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) } }
方案2:全局生命周期监听(无需修改Activity B代码)
适合Activity B属于第三方模块、你无法修改其源码的场景:
- 在你项目的Application类
onCreate中注册全局Activity生命周期回调:
class MyApp : Application() { override fun onCreate() { super.onCreate() registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks { override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { // 仅对从Activity A启动的Activity B生效 if (activity.javaClass.name == "com.xxx.xxx.ActivityB") { val taskInfo = (getSystemService(ACTIVITY_SERVICE) as ActivityManager) .getRunningTasks(1)[0] // 判断当前任务栈根Activity是A,说明是从A启动的B val isFromA = taskInfo.baseActivity?.className == ActivityA::class.java.name if (isFromA) { activity.window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) } } } // 其余生命周期方法留空实现即可 override fun onActivityStarted(activity: Activity) = Unit override fun onActivityResumed(activity: Activity) = Unit override fun onActivityPaused(activity: Activity) = Unit override fun onActivityStopped(activity: Activity) = Unit override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) = Unit override fun onActivityDestroyed(activity: Activity) = Unit }) } }
注意:查询自身应用的Activity栈不需要申请额外权限,Android 11及以上版本也可正常使用。
方案优势
两种方案都完全基于Android官方提供的屏幕常亮API实现,不需要申请WAKE_LOCK权限,系统会自动在Activity销毁时清除常亮标记,不会出现唤醒锁容易忘记释放导致的后台耗电问题。
内容的提问来源于stack exchange,提问作者idrkwhatsgoingon
相关产品推荐
相关产品推荐

