屏幕关闭时,警报活动无法启动

时间:2019-02-26 02:00:14

标签: android kotlin

我正在开发一个Intent警报应用程序,该警报应用程序会在警报触发时启动并显示Activity,即使关闭了设备屏幕。该应用的目标是SDK 16+。
我可以通过自定义日志确认AlarmBroadcastReceiver正在按时触发,然后依次启动AlarmActivity。通过自定义日志记录,AlarmActivity不能在正确的时间进行切换。而是延迟启动或在用户再次打开屏幕时启动。

我不知道为什么会这样。我已经尝试过解决SO上发布的其他类似问题的多种解决方案。

您对我的问题有什么建议吗?谢谢您的帮助!
请参见下面的AlarmBroadcastReceiverAlarmActivityAndroidManifest代码。

我正在以下设备上进行测试:
Samsung Galaxy II,Android 4.1.2,API 16-(这是从不触发AlarmActivity或等到屏幕打开时最糟糕的情况。)
LG Nexus 5,Android 6.0.1,API 23
LG Harmony,Android 7.0,API 24

AndroidManifest

...
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity android:name=".view.AlarmActivity">
        </activity>
        <activity android:name=".view.TimerActivity">
        </activity>
        <activity android:name=".view.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity> 

        <!-- Register the BroadcastReceiver -->
        <receiver android:name=".AlarmBroadcastReceiver"/>
        <receiver android:name=".TimerBroadcastReceiver"/>
    </application>

</manifest>

AlarmBroadcastReceiver

class AlarmBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent?) {

        // ***** CUSTOM LOGGING HERE *****
        // This code logs at the correct alarm time

        val newIntent = Intent(context, AlarmActivity::class.java)
        newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        ContextCompat.startActivity(context, newIntent, null)
    }

}

AlarmActivity

class AlarmActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(com.devbygc.toddlertimer.R.layout.activity_alarm)

        // ***** CUSTOM LOGGING HERE *****
        // This code does NOT log until either
        // - user turns on the devices screen
        // - some lapse in time making the alarm "late" by 1 min to 1+ 

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setTurnScreenOn(true)
            setShowWhenLocked(true)
            val k = this.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
            k.requestDismissKeyguard(this, null)
        } else {
            @Suppress("DEPRECATION")
            window.addFlags(
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY or
                    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
            )
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我在药物提醒项目中使用了此代码。

权限

$Args

代码

$Args

用法(这是Java的缩写)

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> 

答案 1 :(得分:0)

在调查了谷歌自己的代码库之前的警报-AlarmClock-我想出了如何使用WakeLock来解决此问题的方法。
AlarmBroadcastReceiveronReceive()中获得了部分唤醒锁。然后在我的onDestroy()的{​​{1}}中发布。
新的类AlarmActivity处理所有唤醒锁功能。
清单没有更改,请参阅原始问题以获取权限。
该代码未能在停机时间超过12小时的多次测试的多个设备上成功触发警报。

值得称赞的是,我仍然发现WindSekirun代码很有帮助,如果发现类似问题,建议考虑使用它。

请参见下面的代码:

AlarmBroadcastReceiver

AlertWakeLock

AlarmActivity

class AlarmBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent?) 

        AlertWakeLock.acquireWakeLock(context)

        val newIntent = Intent(context, AlarmActivity::class.java)
        newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        ContextCompat.startActivity(context, newIntent, null)
    }

}

AlertWakeLock

class AlarmActivity : AppCompatActivity() {

    override fun onDestroy() {
        super.onDestroy()
        AlertWakeLock.releaseWakeLock()
    }

}