API 23之后,闹钟管理器无法按预期启动服务

3
最近我将项目升级到了26 Api级别。升级后,我的闹钟管理器不能正常工作了。我不知道问题出在哪里,但我猜测闹钟根本没有起作用,无论是在后台还是针对所有设备(> = M)。我查看了其他的问题并遵循了一些建议,例如“WakefulBroadcastReceiver”。
下面是我的代码和流程:
情景
- 每15分钟设置一个重复的闹钟。
     Intent dil = new Intent(getApplicationContext(), LocationSyncTaskReceiver.class);
        PendingIntent dlpi = PendingIntent.getBroadcast(getApplicationContext(), 225566, dil, 0);
        AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

            lFreq = 15;

        if(Build.VERSION.SDK_INT>23)
            am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,(System.currentTimeMillis()+5 * 60 * 1000L),dlpi);
        else
            am.setRepeating(AlarmManager.RTC_WAKEUP, 5 * 60 * 1000L, lFreq * 60 * 1000L, dlpi);

- 调用“WakefulBroadcastReceiver”的操作。
  public class LocationSyncTaskReceiver extends WakefulBroadcastReceiver {

private static final String TAG = LocationSyncTaskReceiver.class.getSimpleName();

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

    WakefulIntentService.acquireStaticLock(context);
    Intent locationSync = new Intent(context, SyncLocationTracker.class);
    startWakefulService(context,locationSync);
}

以上代码调用了“WakefulIntentService-SyncLocationTracker”。

    @Override
public void doWakefulWork(Intent intent) {
    userService = UserServiceImpl.getInstance();
    Log.d(TAG, "Data Tracker : doWakefulWork called");
    if (userService.getLoggedInUser() != null) {
        Log.d(TAG, "User is logged in so continuing sync ....");
        WakefulIntentService.acquireStaticLock(getApplicationContext());
        syncService = DataSyncServiceImpl.getInstance();
        syncService.syncLocation();
    } else {
        Log.d(TAG, "User is not logged in so discarding sync ....");
        stopSelf();
    }
    stopSelf();
}

- 'syncService.syncLocation();' 最终会执行一些计算和多次网络请求。


嗨,Uday,这是我的答案,可能会帮助你正确启动警报 https://stackoverflow.com/a/49042254/3894930 - Dhaval Solanki
@DhavalSolanki,它适用于23以下的版本,但不适用于23以上的版本,我正在使用setExactAndAllowWhileIdle,但仍然无法正常工作。 - Uday Ramjiyani
Google在API 23中改变了行为并引入了“Doze”。API 24有更多的限制。请参见https://developer.android.com/about/versions/nougat/android-7.0-changes.html#perf - momo
是的我知道,但系统会发出正常的警报,您可以阅读下面链接中的Doze限制部分。 https://developer.android.com/training/monitoring-device-state/doze-standby.html - Dhaval Solanki
如果您需要在Doze模式下触发警报,请使用setAndAllowWhileIdle()或setExactAndAllowWhileIdle()。 - Dhaval Solanki
2个回答

0

将您的if条件更改为:

if(Build.VERSION.SDK_INT > 23)

to:

if(Build.VERSION.SDK_INT >= 23)

0

使用此库解决了这个问题 Evernote工作调度程序库

它根据您的Android操作系统版本使用JobSchedulerGcmNetworkManagerAlarmManager

从Android Oreo开始的所有功能都向后兼容到Ice Cream Sandwich。

JobRequest.Builder类具有许多额外选项,例如您可以指定所需的网络连接,使作业周期性,通过捆绑包传递一些额外信息,在重新启动后恢复作业或在精确时间运行作业。

示例

     int jobId = new JobRequest.Builder(DemoSyncJob.TAG)
        .setExecutionWindow(30_000L, 40_000L)
        .setBackoffCriteria(5_000L, JobRequest.BackoffPolicy.EXPONENTIAL)
        .setRequiresCharging(true)
        .setRequiresDeviceIdle(false)
        .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
        .setExtras(extras)
        .setRequirementsEnforced(true)
        .setUpdateCurrent(true)
        .build()
        .schedule();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接