You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 12中OneTimeWorkRequest熄屏未充电时无法运行问题

问题分析与解决方案

问题根源

Android 12(API 31)引入了更严苛的后台执行限制:当设备熄屏且未充电时,系统会大幅限制后台任务的执行时长(通常约1分钟),即便WorkManager的约束设置为无需充电,也会被系统省电机制强制打断。而充电状态下系统会放宽后台限制,因此任务能正常运行。其他低版本Android系统无此严格限制,所以表现正常。

解决方案

1. 用前台服务提升任务优先级

在PeriodicSync Worker内部启动前台服务,通过持有前台通知让系统判定任务为用户可见的重要任务,避免被后台限制杀死。

修改PeriodicSync类的doWork()方法:

@Override
public Result doWork() {
    // Android 12及以上需前台服务权限,先构建通知
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        Notification notification = new NotificationCompat.Builder(getApplicationContext(), "SYNC_CHANNEL_ID")
                .setContentTitle("数据同步中")
                .setContentText("正在执行周期性同步任务")
                .setSmallIcon(R.drawable.ic_sync_notify)
                .setPriority(NotificationCompat.PRIORITY_LOW) // 低优先级减少用户打扰
                .build();

        // 启动前台服务,通知ID需唯一
        startForeground(1001, notification);
    }

    // 执行你的核心同步逻辑
    performSyncOperation();

    // 重新调度下一次任务
    scheduleNextSync();

    // 任务完成后停止前台服务(无需持续显示通知时)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        stopForeground(STOP_FOREGROUND_REMOVE);
    }

    return Result.success();
}

private void scheduleNextSync() {
    Constraints constraints = new Constraints.Builder()
            .setRequiredNetworkType(NetworkType.NOT_REQUIRED)
            .setRequiresCharging(false)
            .setRequiresBatteryNotLow(false)
            .build();

    OneTimeWorkRequest nextRequest = new OneTimeWorkRequest.Builder(PeriodicSync.class)
            .setInitialDelay(10, TimeUnit.SECONDS)
            .addTag("sendData")
            .setConstraints(constraints)
            .build();

    WorkManager.getInstance(getApplicationContext()).enqueue(nextRequest);
}

注意事项:

  • 在AndroidManifest.xml中声明权限:
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <!-- Android 13及以上需通知权限 -->
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" android:maxSdkVersion="33" />
    
  • 需提前创建通知渠道(Android 8.0及以上要求)。

2. 使用加急任务提高执行优先级

Android 12及以上支持加急任务,这类任务拥有更高的执行优先级,可绕过部分后台限制。适合高频但需及时执行的场景,但注意系统对加急任务有调用频率限制,避免过度使用。

修改任务调度代码:

OneTimeWorkRequest sendWorkRequest = new OneTimeWorkRequest.Builder(PeriodicSync.class)
        .setInitialDelay(10, TimeUnit.SECONDS)
        .addTag("sendData")
        .setConstraints(constraints)
        // 配置加急任务,配额耗尽时自动转为普通任务
        .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
        .build();

3. 关闭应用电池优化

引导用户关闭应用的电池优化,减少系统对后台任务的限制。可通过代码跳转至电池优化设置页面:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    Intent intent = new Intent();
    String packageName = getApplicationContext().getPackageName();
    PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
    if (!pm.isIgnoringBatteryOptimizations(packageName)) {
        intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        intent.setData(Uri.parse("package:" + packageName));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getApplicationContext().startActivity(intent);
    }
}

需在AndroidManifest.xml中声明权限:

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

内容的提问来源于stack exchange,提问作者Amir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 00:05:26