【问题标题】:PeriodicWorkRequest not working after device reboot in android oreo在android oreo中设备重启后PeriodicWorkRequest不起作用
【发布时间】:2018-12-28 14:00:03
【问题描述】:

我需要根据以下逻辑向用户推送应用通知。

  • A 类通知将在每 24 小时后显示一次。
  • B 类通知将在每 7 天后显示一次。
  • C 类通知将在每 15 天后显示一次。

我使用PeriodicWorkRequest工作管理器如下,它工作正常,直到设备重新启动。 设备重启后,我的工作不会被触发。

build.gradle ---

implementation 'android.arch.work:work-runtime:1.0.0-alpha04'

Java 代码

PeriodicWorkRequest showNotification =
                new PeriodicWorkRequest.Builder(ShowNotificationWorkManager.class, interval,
                        TimeUnit.HOURS)
                        .addTag(notificationType)
                        .setInputData(myData)
                        .build();

getWorkManger().enqueue(showNotification);

【问题讨论】:

  • 你得到答案了吗。如果有,请发布。我也面临同样的问题
  • @Suresh 您找到解决方案了吗?请发布答案,因为我也面临同样的问题
  • 确保您的应用没有进行电池优化,所有应用似乎都默认开启了电池优化github.com/googlecodelabs/android-workmanager/issues/…

标签: android android-workmanager


【解决方案1】:

我已经尝试过这段代码并与我一起处理旧 API 和新 API: 此代码在设备重新启动时每 15 分钟执行一次服务(workmanager)。 对于 AndroidManifest.xml 文件:

<receiver android:name=".WorkManagerStartReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

在 WorkManagerStartReceiver 类上:

public class WorkManagerStartReceiver extends BroadcastReceiver {
    WorkManager mWorkManager;

    @Override
    public void onReceive(Context context, Intent intent) {

        PeriodicWorkRequest.Builder myWorkBuilder =
                new PeriodicWorkRequest.Builder(TestWorker.class,
                        PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS,
                        TimeUnit.MILLISECONDS);

        PeriodicWorkRequest myWork = myWorkBuilder.build();
        mWorkManager = WorkManager.getInstance(context);
        mWorkManager.enqueue(myWork);

    }
}

而 TestWorker.class 是扩展 Worker 的类:

public class TestWorker extends Worker {

    public TestWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {

        //your work that you want to execute here
        return null;
    }
}

如果您希望服务在应用打开时开始工作,这个 sn-p(在 MainActivity 上)会在应用打开时打开。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    PeriodicWorkRequest.Builder myWorkBuilder =
            new PeriodicWorkRequest.Builder(TestWorker.class,
                                            PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS,
                                            TimeUnit.MILLISECONDS);
    PeriodicWorkRequest myWork = myWorkBuilder.build();
    WorkManager.getInstance(MainActivity.this)
            .enqueueUniquePeriodicWork("testworker", ExistingPeriodicWorkPolicy.KEEP, myWork);
}

【讨论】:

  • WorkManager 已经在 Manifest 合并中请求 BOOT_COMPLETED。您不必自己声明此意图。
【解决方案2】:

你打电话给getWorkManger().enqueue(showNotification)。相反,您应该将周期性工作加入队列,因为您的工作是周期性操作

workManager = WorkManager.getInstance(this)
workManager.enqueueUniquePeriodicWork(
   WORKER_NAME, ExistingPeriodicWorkPolicy.KEEP, workRequest
 )

【讨论】:

    【解决方案3】:

    我已经尝试过了,也适用于 HTC 手机。

    <receiver android:name=".WorkManagerStartReceiver" android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                    <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
                    <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
                </intent-filter>
    </receiver>
    

    【讨论】:

      【解决方案4】:

      请在您的 android manifest 中添加以下权限

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

      【讨论】:

      • 为什么需要这个权限?
      【解决方案5】:

      如果 PeriodicWorkRequest 在设备重启后无法正常工作,您可以通过执行以下步骤来解决此问题。

      只需定义一个 BroadcastReceiver 并在 onReceive(-) 方法中安排您的 WorkManager。

      public class WorkManagerStartReceiver extends BroadcastReceiver {
      
      @Override
      public void onReceive(Context context, Intent intent) {
      
          Constraints constraints = new Constraints.Builder()
                  .setRequiresCharging(false)
                  .build();
      
          PeriodicWorkRequest saveRequest =
                  new PeriodicWorkRequest.Builder(ToastWorker.class, 15, TimeUnit.MINUTES)
                          .setConstraints(constraints)
                          .build();
      
          WorkManager.getInstance(context)
                  .enqueue(saveRequest);
       } }
      

      现在在 manifest.xml 文件中定义您的 BroadcastReceiver

      <application
         ----
             >
          <activity android:name=".MainActivity"/>
      
          <receiver android:name=".WorkManagerStartReceiver">
              <intent-filter>
                  <action android:name="android.intent.action.BOOT_COMPLETED"/>
              </intent-filter>
          </receiver>
      
      </application>
      

      别忘了在你的清单文件中添加启动权限android.permission.RECEIVE_BOOT_COMPLETED

      【讨论】:

      • ~"WorkManager 在设备重启后无法真正工作。" 谁说的?它绝对有效。
      • @IgorGanapolsky 在你的情况下,它可能有效。你不认为没有投票可以质疑。似乎这是反复出现的问题。无论如何,我会检查的。也有可能,Android 人在较新版本的 WorkManager 中修复了这个问题
      【解决方案6】:

      可以在设备上首次启动应用程序时安排一次定期工作请求。我们可以使用共享偏好来识别应用程序是否是第一次启动。此外,为了在启动后重复该工作,我们可以在一个 BroadcastReceiver 中启动该工作,该广播接收器将在设备重启后触发。

      【讨论】:

        猜你喜欢
        • 2019-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-22
        相关资源
        最近更新 更多