First, instead of calling the service directly, AlarmManagercall the broadcast receiver, which then calls the service.
The broadcast receiver should distribute WakefulBroadcastReceiverinstead of the usual one BroadcastReceiver.
And then, let the broadcast receiver schedule a new Alarm, start the service using startWakefulService()insteadstartService()
public class MyAwesomeReceiver extends WakefulBroadcastReceiver {
int interval=2*60*60*1000;
@Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context, MyAwesomeService.class);
Intent receiverIntent = new Intent(context, MyAwesomeReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 11, receiverIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+interval,alarmIntent);
startWakefulService(context, serviceIntent);
}
}
WakefulBroadcastReceiverand startWakefulService()let your application open a 10 second window to do what it needs.
Moreover,
You can always ask the user to let your application ignore the battery optimization functionality with -
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
Intent intent=new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
if (powerManager.isIgnoringBatteryOptimizations(getPackageName())) {
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
}
else {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
and in the manifest
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"></uses-permission>
source
share