Alarms
Your should read how Doze and Standby are impacting alarms on devices with Android 6.0 and up. When phone goes to Doze state, all alarms and background jobs are stopped until maintenance period comes in. There is new alarms which can run in those states, setAndAllowWhileIdle() and setExactAndAllowWhileIdle()
So basicly you should create new method where you will call different alarms methods based on platform version:
public void setExactAlarm(int alarmType, long triggerTime, PendingIntent operation) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(alarmType, triggerTime, operation);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(alarmType, triggerTime, operation);
} else {
alarmManager.set(alarmType, triggerTime, operation);
}
}
}
And please note how alarms can be deferred in doze state:
Under normal system operation, it will not dispatch these alarms more
than about every minute (at which point every such pending alarm is
dispatched); when in low-power idle modes this duration may be
significantly longer, such as 15 minutes.
Services
Things were changed in the latest SDK APIs. If you are running application on platform 26+ there is restriction on background services.
If your app targets API level 26 or higher, the system imposes restrictions on using or creating background services unless the app itself is in the foreground. If an app needs to create a foreground service, the app should call startForegroundService(). That method creates a background service, but the method signals to the system that the service will promote itself to the foreground. Once the service has been created, the service must call its startForeground() method within five seconds.
So, if you need some background service, now you must inform user that there is some service which executes in background via notification.
This is some sample code for your broadcast receiver when alarm fires up:
Intent service= new Intent(this, ExampleService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
context.startForegroundService(service);
else
context.startService(intent);
And last, inside of a service in onStartCommand() you must again check SDK version, and if version is 26+ you should call startForeground();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification notification = new NotificationCompat.Builder(context, channalId);
startForeground(NOTIFICATION_ID, notification);
}