init
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package com.dcntrlized.alarm
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.KeyguardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.WindowManager
|
||||
import com.facebook.react.ReactActivity
|
||||
import com.facebook.react.ReactActivityDelegate
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
|
||||
import com.facebook.react.defaults.DefaultReactActivityDelegate
|
||||
|
||||
/**
|
||||
* The full-screen alarm takeover.
|
||||
*
|
||||
* Launched by a full-screen intent from the alarm notification, so it appears
|
||||
* over the lock screen and turns the screen on. It reuses the main JS bundle
|
||||
* and is pointed at the `LiveAlarm` route via the intent extras, so the takeover
|
||||
* is the same React screen whether the app was foreground, background or dead.
|
||||
*
|
||||
* Manifest requirements that make this work (see AndroidManifest.xml):
|
||||
* `launchMode=singleTask`, `excludeFromRecents=true`, `showWhenLocked` and
|
||||
* `turnScreenOn` on the activity, and `USE_FULL_SCREEN_INTENT`.
|
||||
*/
|
||||
class AlarmActivity : ReactActivity() {
|
||||
|
||||
override fun getMainComponentName(): String = "AlarmClient"
|
||||
|
||||
override fun createReactActivityDelegate(): ReactActivityDelegate =
|
||||
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
// Order matters: the flags must be set before the window is shown.
|
||||
showOverLockScreen()
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
private fun showOverLockScreen() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||
setShowWhenLocked(true)
|
||||
setTurnScreenOn(true)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
window.addFlags(
|
||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
|
||||
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
|
||||
)
|
||||
}
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
// Dismiss the keyguard where the OS permits it (a secure lock screen is
|
||||
// still honoured — we never try to bypass a PIN).
|
||||
val km = getSystemService(Context.KEYGUARD_SERVICE) as? KeyguardManager
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && km?.isKeyguardLocked == true) {
|
||||
km.requestDismissKeyguard(this, null)
|
||||
}
|
||||
}
|
||||
|
||||
/** Hardware back is consumed: the takeover's only exits are in-app actions. */
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onBackPressed() {
|
||||
// Intentionally swallowed — see the Live alarm takeover spec.
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
AlarmPlayer.stop(this)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EXTRA_ALERT_ID = "alarm.alertId"
|
||||
const val EXTRA_MESSAGE = "alarm.message"
|
||||
const val EXTRA_AUTO_STOP = "alarm.autoStopSeconds"
|
||||
|
||||
fun intent(context: Context, alertId: String, message: String, autoStopSeconds: Int): Intent =
|
||||
Intent(context, AlarmActivity::class.java).apply {
|
||||
addFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK or
|
||||
Intent.FLAG_ACTIVITY_SINGLE_TOP or
|
||||
Intent.FLAG_ACTIVITY_CLEAR_TOP or
|
||||
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
|
||||
)
|
||||
putExtra(EXTRA_ALERT_ID, alertId)
|
||||
putExtra(EXTRA_MESSAGE, message)
|
||||
putExtra(EXTRA_AUTO_STOP, autoStopSeconds)
|
||||
}
|
||||
|
||||
/** The alert id this launch is for, if any — read by the JS bridge. */
|
||||
fun alertIdOf(activity: Activity?): String? =
|
||||
activity?.intent?.getStringExtra(EXTRA_ALERT_ID)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user