What is the best practice to start a service that never stops? I have to be able to send a notification at specific times. As stated Here work manager, alarm manager, jobintent service(or any other service) wont work properly on custom OS devices such as Xiaomi. Some methods like this may be good for anroid O+ (considering the restrictions on background services) but does not work on custom OS devices with battery optimizations such as Xiaomi. I even raised this Issue tracker and they confirmed that this problem is real with custom OS devices! (They said they are talking to them to do something about it!)
Any way, I found an app that managed to send notification on very exact times. It works perfectly on all devices. Out of curiosity, I decompiled their app. Most of the code was unreadable, but I found a class names WakeFulBroadcasReceiver that seems like it is starting many services and instantiating many wakelocks. But I couldn't figure out how they are actually doing it. Here is the part of code that was intact:
public abstract class WakefulBroadcastReceiver extends BroadcastReceiver {
public static final String EXTRA_WAKE_LOCK_ID = "androidx.contentpager.content.wakelockid";
public static int mNextId = 1;
public static final SparseArray<PowerManager.WakeLock> sActiveWakeLocks = new SparseArray<>();
public static boolean completeWakefulIntent(Intent intent) {
int intExtra = intent.getIntExtra(EXTRA_WAKE_LOCK_ID, 0);
if (intExtra == 0) {
return false;
}
synchronized (sActiveWakeLocks) {
PowerManager.WakeLock wakeLock = sActiveWakeLocks.get(intExtra);
if (wakeLock != null) {
wakeLock.release();
sActiveWakeLocks.remove(intExtra);
return true;
}
Log.w("WakefulBroadcastReceiv.", "No active wake lock id #" + intExtra);
return true;
}
}
public static ComponentName startWakefulService(Context context, Intent intent) {
synchronized (sActiveWakeLocks) {
int i2 = mNextId;
int i3 = mNextId + 1;
mNextId = i3;
if (i3 <= 0) {
mNextId = 1;
}
intent.putExtra(EXTRA_WAKE_LOCK_ID, i2);
ComponentName startService = context.startService(intent);
if (startService == null) {
return null;
}
PowerManager.WakeLock newWakeLock = ((PowerManager) context.getSystemService("power")).newWakeLock(1, "androidx.core:wake:" + startService.flattenToShortString());
newWakeLock.setReferenceCounted(false);
newWakeLock.acquire(OpenStreetMapTileProviderConstants.ONE_MINUTE);
sActiveWakeLocks.put(i2, newWakeLock);
return startService;
}
}
}
It seems like they are having an array of Wakelocks which is very weird. Do you have any Idea what might be the work around to have a background service that always work in this cusomt OS devices?