如何让BroadcastReceiver在MIUI系统手机休眠状态下正常工作
适配MIUI熄屏触发闹钟的解决步骤
MIUI对后台应用启动行为、设备唤醒权限做了比原生安卓严格得多的限制,你需要按以下步骤修改配置和代码即可实现熄屏触发点亮屏幕:
1. 新增必要权限到AndroidManifest.xml
把以下权限添加到<application>标签的外层:
<!-- 唤醒设备权限 --> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- 解锁锁屏权限 --> <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <!-- 悬浮窗权限(MIUI要求后台启动Activity必须拥有) --> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 安卓12+后台启动Activity专属权限 --> <uses-permission android:name="android.permission.SYSTEM_EXEMPT_FROM_ACTIVITY_RESTRICTION" />
2. 修改AlarmActivity的Manifest配置
给AlarmActivity新增锁屏显示、唤醒屏幕的专属属性:
<activity android:name=".AlarmActivity" android:screenOrientation="portrait" android:theme="@style/Theme.NoActioBar" android:windowSoftInputMode="adjustResize" <!-- 新增下面三个属性 --> android:showOnLockScreen="true" android:turnScreenOn="true" android:showWhenLocked="true"> </activity>
3. AlarmActivity中添加点亮屏幕代码
在AlarmActivity的onCreate方法的setContentView之前加入以下代码:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { // 安卓8.1及以上直接调用系统API setShowWhenLocked(true) setTurnScreenOn(true) // 解除锁屏 val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager keyguardManager.requestDismissKeyguard(this, null) } else { // 低版本用窗口Flag实现 window.addFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD ) }
4. 优化AlarmReceiver唤醒逻辑
添加唤醒锁保证广播触发时CPU保持唤醒,直到Activity启动完成:
class AlarmReceiver : BroadcastReceiver() { private val WAKE_LOCK_TAG = "AlarmApp:AlarmWakeLock" override fun onReceive(context: Context, intent: Intent) { Toast.makeText(context,"Ready to wake up?", Toast.LENGTH_LONG).show() // 申请唤醒锁,最多持有10秒,超时自动释放避免耗电 val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager val wakeLock = powerManager.newWakeLock( PowerManager.PARTIAL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP, WAKE_LOCK_TAG ) wakeLock.acquire(10*1000L) val myIntent = Intent(context,AlarmActivity::class.java) myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP) context.startActivity(myIntent) } }
5. 适配安卓12+的PendingIntent规则
如果你的App目标版本是安卓12及以上(targetSdkVersion >=31),需要修改MainActivity里创建PendingIntent的代码:
val mPendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { PendingIntent.getBroadcast(this, 0, mIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) } else { PendingIntent.getBroadcast(this, 0, mIntent, PendingIntent.FLAG_UPDATE_CURRENT) }
6. 开启MIUI专属权限
你需要引导用户手动打开以下权限,否则MIUI会禁止后台触发闹钟:
- 自启动权限:MIUI设置 -> 应用设置 -> 找到你的App -> 权限管理 -> 自启动 -> 允许
- 悬浮窗权限:同样在权限管理页面找到「显示在其他应用上层」/「悬浮窗」 -> 允许
- 电量无限制:MIUI设置 -> 省电与电池 -> 电池 -> 应用智能省电 -> 找到你的App -> 设置为「无限制」
内容的提问来源于stack exchange,提问作者Syed Suhail
相关产品推荐
相关产品推荐

