如何使用Kotlin实现设备解锁时启动Activity?
解决设备解锁时自动启动Activity的问题
看起来你在实现解锁设备启动Activity的功能时遇到了问题,我帮你梳理下代码里的问题和对应的修复方案:
1. 先修正低级拼写错误
你的Receiver类名声明的是.ScreenReceiver,但代码文件命名成了ScreenRececiver.kt(多了一个c),这会导致系统找不到这个Receiver类,直接把文件名改成ScreenReceiver.kt就好。
2. 清理Manifest里的重复配置
你在intent-filter里重复写了两次USER_PRESENT的action,而且Android 12及以上要求显式声明android:exported属性,不然会抛出安装错误。修正后的Manifest配置如下:
<receiver android:name=".ScreenReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.SCREEN_ON" /> <action android:name="android.intent.action.USER_PRESENT" /> </intent-filter> </receiver>
3. 添加必要的权限
别忘了在Manifest里添加开机广播的权限,如果是Android 10+还需要悬浮窗权限来绕过后台启动限制:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
4. 处理Android版本的后台启动限制
从Android 10(API 29)开始,系统严格限制了后台应用启动Activity的行为,直接在USER_PRESENT广播里启动Activity会被系统拦截。你需要先在应用前台(比如主Activity)动态请求悬浮窗权限:
// 在你的主Activity中添加权限请求逻辑 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) { val overlayIntent = Intent( Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName") ) startActivityForResult(overlayIntent, 1001) }
5. 优化Receiver的逻辑
建议只在ACTION_USER_PRESENT(用户解锁成功)时启动Activity,SCREEN_ON可能在锁屏亮屏时触发,这时候启动会被系统拦截。同时优化Intent的Flag设置:
class ScreenReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { intent?.takeIf { it.action == Intent.ACTION_USER_PRESENT }?.let { context?.run { val launchIntent = Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) // 适配Android 10+的启动规则 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT) } } startActivity(launchIntent) } } } }
测试小提示
- 尽量用真机测试,模拟器的解锁广播触发逻辑和真机有差异;
- 把应用加入系统后台白名单,避免被系统清理导致Receiver无法触发。
内容的提问来源于stack exchange,提问作者boomboxarcade
相关产品推荐
相关产品推荐

