API 23 后警报管理器未按预期启动服务
Alarm manager not starting service as expected after API 23
最近我将我的项目升级到 26 Api 级别。在那个警报管理器不为我工作之后。我不知道出了什么问题,但我猜警报根本不起作用,只要应用程序在 lolipop(>=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();' 终于做了一些计算和多个网络请求
更改您的 if 条件:
if(Build.VERSION.SDK_INT > 23)
至:
if(Build.VERSION.SDK_INT >= 23)
使用这个库解决了它
Evernote job scheduler library
它使用 JobScheduler
、GcmNetworkManager
或 AlarmManager
,具体取决于您的 android os 版本。
AndroidOreo 的所有功能都向后兼容 Ice Cream Sandwich。
JobRequest.Builder
class 有很多额外的选项,例如您可以指定所需的网络连接,使作业定期进行,通过捆绑包传递一些额外内容,在重新启动后恢复作业或 运行 在准确的时间恢复作业。
示例
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();
最近我将我的项目升级到 26 Api 级别。在那个警报管理器不为我工作之后。我不知道出了什么问题,但我猜警报根本不起作用,只要应用程序在 lolipop(>=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();' 终于做了一些计算和多个网络请求
更改您的 if 条件:
if(Build.VERSION.SDK_INT > 23)
至:
if(Build.VERSION.SDK_INT >= 23)
使用这个库解决了它 Evernote job scheduler library
它使用 JobScheduler
、GcmNetworkManager
或 AlarmManager
,具体取决于您的 android os 版本。
AndroidOreo 的所有功能都向后兼容 Ice Cream Sandwich。
JobRequest.Builder
class 有很多额外的选项,例如您可以指定所需的网络连接,使作业定期进行,通过捆绑包传递一些额外内容,在重新启动后恢复作业或 运行 在准确的时间恢复作业。
示例
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();