我正在开发一个Intent
警报应用程序,该警报应用程序会在警报触发时启动并显示Activity
,即使关闭了设备屏幕。该应用的目标是SDK 16+。
我可以通过自定义日志确认AlarmBroadcastReceiver
正在按时触发,然后依次启动AlarmActivity
。通过自定义日志记录,AlarmActivity
不能在正确的时间进行切换。而是延迟启动或在用户再次打开屏幕时启动。
我不知道为什么会这样。我已经尝试过解决SO上发布的其他类似问题的多种解决方案。
您对我的问题有什么建议吗?谢谢您的帮助!
请参见下面的AlarmBroadcastReceiver
,AlarmActivity
和AndroidManifest
代码。
我正在以下设备上进行测试:
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
...
<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>
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)
}
}
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
)
}
}
}
答案 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来解决此问题的方法。
AlarmBroadcastReceiver
在onReceive()
中获得了部分唤醒锁。然后在我的onDestroy()
的{{1}}中发布。
新的类AlarmActivity
处理所有唤醒锁功能。
清单没有更改,请参阅原始问题以获取权限。
该代码未能在停机时间超过12小时的多次测试的多个设备上成功触发警报。
值得称赞的是,我仍然发现WindSekirun代码很有帮助,如果发现类似问题,建议考虑使用它。
请参见下面的代码:
AlertWakeLock
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)
}
}
class AlarmActivity : AppCompatActivity() {
override fun onDestroy() {
super.onDestroy()
AlertWakeLock.releaseWakeLock()
}
}