Start activity even when screen is turned off

2020-06-30 04:41发布

问题:

I'm trying to start an activity with an alarm. The PendingIntent starts a receiver and the receiver starts the activity. My current issue is that the activity starts in the background and it's impossible to hear the alarm sound. Most of the flags from older SO questions are deprecated for Oreo and newer devices. Does anyone have a good approach how to handle this?

Thank you in advance

Alarm creation:

alarmManager.setExact(AlarmManager.RTC_WAKEUP, intervalFinished, pendingIntent)

Receiver

class OnAlarmReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        val intent = Intent(context, AlarmActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

        context.startActivity(intent)
    }
}

Activity:

private var wake: PowerManager.WakeLock? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
    wake = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK
            or PowerManager.ACQUIRE_CAUSES_WAKEUP, "App:wakeuptag")
    wake?.acquire(10*60*1000L /*10 minutes*/)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
        setShowWhenLocked(true)
        setTurnScreenOn(true)
    } else {
        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)
    }
    setContentView(R.layout.activity_layout)
}

override fun onPause() {
    super.onPause()
    if(wake != null && wake!!.isHeld){
        wake!!.release()
    }
}

回答1:

You should have in your AndroidManifest.xml

<activity
    android:name=".AlarmActivity"
    android:showOnLockScreen="true"
    android:turnScreenOn="true"/>

Also the following check should be after the setContentView(). Since at the time you adding the flags there is not view that can make use of them.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
    setShowWhenLocked(true)
    setTurnScreenOn(true)
} else {
    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)
}