问题
Recently i have upgraded my project to 26 Api level. after that alarm manager is not working for me. I don't know what's the problem but i guess the alarm is not at all working, whenever app is in background for all device above lolipop(>=M). i have gone through other questions and and have followed some suggestion like 'WakefulBroadcastReceiver',
Below is my code and flow of the same
Scenario
- setting a repeative alarm for every 15 minutes.
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);
- which is invoking a '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);
}
}
- above code is calling '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();' is finally doing a some calculation and multiple network request
回答1:
Change your if condition from:
if(Build.VERSION.SDK_INT > 23)
to:
if(Build.VERSION.SDK_INT >= 23)
回答2:
Resolved it using this library Evernote job scheduler library
It uses JobScheduler
, GcmNetworkManager
or AlarmManager
depending on your android os version.
All features from Android Oreo are backward compatible back to Ice Cream Sandwich.
The JobRequest.Builder
class has many extra options, e.g. you can specify a required network connection, make the job periodic, pass some extras with a bundle, restore the job after a reboot or run the job at an exact time.
Example
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();
来源:https://stackoverflow.com/questions/49623785/alarm-manager-not-starting-service-as-expected-after-api-23