锁定屏幕触发不同活动的应用程序生命周期事件

Jim*_*nts 6 android lockscreen android-lifecycle

当我在扩展FirebaseMessagingService的服务中收到Push消息并在此类中启动Activity时,将执行以下生命周期事件/方法:

  • Push Message启动VideoRingingActivity
  • 启动VideoRingingActivity
  • 的onCreate
  • disableLockScreen
  • 屏幕从黑色切换到锁定屏幕,因此它不显示VideoRingingActivity
  • 在onStart
  • 的onResume
  • 在onPause
  • 的onStop
  • 现在显示了实际的VideoRingingActivity?我期待在setContentView(R.layout.activity_video_ringing)之后出现这个问题
  • onRestart
  • 在onStart
  • 的onResume

我开发了下面的解决方案,我在其中添加一个布尔值,以确定屏幕是否打开/关闭.但这很麻烦,当屏幕在锁定模式下打开时,它不起作用.

因为当屏幕未关闭且显示MainActivity,并且接收到推送消息时,该行为是默认的生命周期行为,因此是正确的.打开屏幕并显示MainActivity时,这是相同的流程:

  • 的onCreate
  • 在onStart
  • 的onResume

这是正确的,也是可以预期的.

class VideoRingingActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        if (ViewUtils.isScreenActive(activity)) {
            screenIsNotLocked = true
        }
        ViewUtils.disableLockScreen(this)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_video_ringing)
    }

    override fun onStart() {
        super.onStart()
        if (screenIsNotLocked) {
        }
    }

    override fun onResume() {
        super.onResume()
        if (screenIsNotLocked) {
        }
    }

    override fun onPause() {
        super.onPause()
        if (screenIsNotLocked) {
        }
    }

    override fun onStop() {
        super.onStop()
        if (screenIsNotLocked) {
        }
        screenIsNotLocked = true
    }
}

open class ViewUtils {

    @JvmStatic
    @Suppress("DEPRECATION")
    fun disableLockScreen(activity: Activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            activity.setShowWhenLocked(true)
            activity.setTurnScreenOn(true)
        }
        val lock = (activity.getSystemService(Activity.KEYGUARD_SERVICE) as KeyguardManager).newKeyguardLock(Context.KEYGUARD_SERVICE)
        val powerManager = activity.getSystemService(Context.POWER_SERVICE) as PowerManager
        val wake = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP or PowerManager.ON_AFTER_RELEASE, "BusSnoozeAlarm")

        lock.disableKeyguard()
        wake.acquire(TIMEOUT)

        activity.window.addFlags(
                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                        or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                        or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                        or WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON)
    }

    @Suppress("DEPRECATION")
    fun isScreenActive(context: Context): Boolean {
        val powerManager = context.getSystemService(POWER_SERVICE) as PowerManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
            return powerManager.isInteractive
        } else {
            return powerManager.isScreenOn
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:有另一个SO线程有类似的问题,但解决方案已过时,并没有考虑屏幕在锁定屏幕模式下处于活动状态时的角落情况:

启动活动后立即调用OnPause和OnStop()

为什么在onCreate之后立即调用onPause方法