You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Android Nougat屏幕关闭时以编程方式重启应用

解决Android Nougat熄屏时应用无法重启的问题

这问题我之前帮不少开发者排查过类似的,核心原因是Android 7.0(Nougat)引入的Doze模式和更严格的后台电源管理机制——当屏幕关闭后,设备会快速进入Doze状态,系统会限制应用的后台启动行为,直接打断了你原本的重启逻辑。下面给你几个针对性的解决思路:

  • 改用高优先级AlarmManager触发重启
    如果之前是用普通的startActivity()startService()触发重启,熄屏时Doze模式会直接阻止这些操作。你需要换成AlarmManagersetExactAndAllowWhileIdle()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_IMMUTABLEFLAG_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

火山引擎 最新活动