visit
public class NavigineReceiverExample extends BroadcastReceiver {
// here you need to receive some action from intent and depending on this action start service or set repeating alarm
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
try{
if (action.equals("START")) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, 0,
new Intent("WAKE"),
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmService = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (alarmService != null)
alarmService.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, 60 * 1000, pendingIntent);
} else if (action.equals("WAKE")) {
context.startService(new Intent(context, NavigineService.class));
}
} catch (Throwable e) {
Logger.d(TAG, 1, Log.getStackTraceString(e));
}
}
}
Periodic J.
Job Scheduler could be used starting from Android API level 23 and replaced Service + Alarm Manager for running background tasks. Periodic Job Scheduler could be waked up at least every 15 minutes and has a lot of opportunities if you need some conditions for your job scheduler like requiring to run only if the device has an internet connection, should be charging, etc. For using this method you should extend the JobService class and override onStartJob method for starting your task. And start Job Scheduler to run a periodic job. Do not forget to add your service to your manifest file. Here is the code example of how to start periodic job scheduler:
JobScheduler jobShedulerService = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobShedulerService.schedule(new JobInfo.Builder(ID, new ComponentName(context, NavigineJobService.class.getName()))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) // any network type
.setPeriodic(15 * 60 * 1000) // every 15 minutes
.setRequiresCharging(false) // if device should be charging
.build());
Alarm with .setAndAllowWhileIdle() and JobScheduler.
Common Alarm Managers with .set() or .setRepeating() will work well only when the device is not in Doze mode because Android will ignore them and reschedule for next time. Using .setAndAllowWhileIdle() will allow the alarm to be called, but the job scheduler will be ignored even in this case.
However, you can add . setOverrideDeadline(time in milliseconds) method to your job scheduler and it will run this scheduled job when the device exits Doze mode. Here is the code example for the onReceive method of our BroadcastReceiver extension:
public class NavigineBroadcastReceiverExample extends BroadcastReceiver {
// here you need to receive some action from intent and depending on this action start service or set repeating alarm
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
try{
if (action.equals("START")) {
Intent wakeIntent = new Intent("WAKE");
wakeIntent.setClass(context, YourReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, 0,
wakeIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmService = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (alarmService != null)
alarmService.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 15 * 60 * 1000, pendingIntent);
} else if (action.equals("WAKE")) {
JobScheduler jobShedulerService = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobShedulerService.schedule(new JobInfo.Builder(1, new ComponentName(context, YourJobClass.class))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setMinimumLatency(0L)
.setOverrideDeadline(15 * 60 * 1000)
.build());
Intent wakeIntent = new Intent("WAKE");
wakeIntent.setClass(context, YourReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, 0,
wakeIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmService = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (alarmService != null)
alarmService.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + Default.NAVIGINE_JOB_SERVICE_WAKEUP_TIME * 1000, pendingIntent);
}
} catch (Throwable e) {
Logger.d(TAG, 1, Log.getStackTraceString(e));
}
}
}
Running foreground service.
Foreground services will run without any cancels and without entering Doze mode, so your background tasks will run infinitely. But this solution has one disadvantage, your app will always have pinned notification in the devices’ status bar.
As you can see in this screenshot, the user will always see this notification which could not be canceled. Using foreground service will increase the chances that your application will be removed faster than it could be. Also, it’s worth noting that your application will use more power and device resources.
Here is the foreground service code example:
public class ForegroundService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
createNotificationChannel();
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, YourActivity.class), 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
// here is the code you wanna run in background
return START_NOT_STICKY;
}
private void createNotificationChannel() {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT);
getSystemService(NotificationManager.class).createNotificationChannel(serviceChannel);
}
}
Using push notifications.
Another way to run background tasks even in Doze mode to send notifications to your application from the server. These notifications will force your application to exit Doze mode and yourи job could be done. But in this case, you will need to spend more resources on running and maintaining your service. You can find more info about using Firebase Cloud Messaging to run your background services by .