如何在Android Nougat屏幕关闭时以编程方式重启应用
这问题我之前帮不少开发者排查过类似的,核心原因是Android 7.0(Nougat)引入的Doze模式和更严格的后台电源管理机制——当屏幕关闭后,设备会快速进入Doze状态,系统会限制应用的后台启动行为,直接打断了你原本的重启逻辑。下面给你几个针对性的解决思路:
改用高优先级AlarmManager触发重启
如果之前是用普通的startActivity()或startService()触发重启,熄屏时Doze模式会直接阻止这些操作。你需要换成AlarmManager的setExactAndAllowWhileIdle()或setAndAllowWhileIdle()方法,这两个API允许在Doze模式下触发PendingIntent,是目前最稳妥的方案。示例代码如下:AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent restartIntent = new Intent(this, YourLauncherActivity.class); // 确保启动全新的应用实例 restartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity( this, 0, restartIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // Doze模式下允许触发的精确闹钟 alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, pendingIntent ); } else { // 低版本用普通精确闹钟 alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, pendingIntent); }注意:Android 12+要求PendingIntent必须设置
FLAG_IMMUTABLE或FLAG_MUTABLE,这里用FLAG_IMMUTABLE更安全。申请电池优化白名单权限(谨慎使用)
如果你的应用确实需要长期在熄屏后台保持操作,可以引导用户将应用加入系统电池优化的白名单,避免被Doze模式限制。代码中可以检查权限状态并跳转设置页面:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { String packageName = getPackageName(); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); if (!pm.isIgnoringBatteryOptimizations(packageName)) { Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); intent.setData(Uri.parse("package:" + packageName)); startActivity(intent); } }提醒:Google Play对这个权限的审核很严格,必须在应用描述中明确说明使用场景,否则容易被拒审,非必要不建议用。
测试Doze模式下的行为
你可以通过ADB命令手动让设备进入Doze模式,快速验证修复效果:# 强制进入Doze模式 adb shell dumpsys deviceidle force-idle # 退出Doze模式 adb shell dumpsys deviceidle unforce不用等设备自然进入Doze,节省测试时间。
避免依赖JobScheduler或普通广播触发重启
如果之前是用JobScheduler实现的重启逻辑,Doze模式下普通Job会被延迟执行,即使设置setOverrideDeadline(0)也不如AlarmManager可靠。另外,Nougat之后普通后台广播的触发也会被限制,尽量不要依赖这类方式。
内容的提问来源于stack exchange,提问作者Tejas




