androidalarmmanagerandroid-workmanagerandroid-jobschedulerperiodic-task

Periodic task killed when app is stopped on Android 8+


Hello everyone i'm trying to implement a periodic task on Android but i'm stuck on some devices.

I need to run a task in background every 15 or 30 minutes. This works well on Android pre 8.0. But on 8+, it works only when app is in background or foreground. When app is swiped out of recent , scheduled task are killed on real devices (Ulefone note 7(Android 8.1), Tecno LC7(Android 10), itel A56 (Abdroid 9)) but works well on emulators(Android 10). I've tried several ways:

1.Workmanager (works only when app is in background or foreground)

build.gradle

implementation "androidx.work:work-runtime:2.4.0"

MainActivity

PeriodicWorkRequest periodicSyncDataWork =
                    new PeriodicWorkRequest.Builder(NotificationWorker.class, 15,TimeUnit.MINUTES)
                            .addTag("TAG_SYNC_DATA")
                            .setBackoffCriteria(BackoffPolicy.LINEAR,PeriodicWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
                            .build();
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
                    "NOTIFICATION_WORKER",
                    ExistingPeriodicWorkPolicy.REPLACE, //Existing Periodic Work policy
                     periodicSyncDataWork //work request
            );

NotificationWorker

public class NotificationWorker extends Worker {
public NotificationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) 
{
    super(context, workerParams);
}


@NonNull
@Override
public Result doWork() {
    Log.d("MYWORKER", "LLLLLLLLLLL");
    //My code here
    return Result.success();
}

}

2.JobScheduler (works only when app is in background or foreground)

ComponentName serviceComponent = new ComponentName(context, NotifJobService.class);
    JobInfo.Builder builder = new JobInfo.Builder(1880, serviceComponent);
    builder.setPersisted(true);
    builder.setPeriodic(16*60*1000, 20*60 *1000);
    JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
    jobScheduler.schedule(builder.build());

3.Alarm Manager (Doesn't fire the BroadcastReceiver)

The main code

Intent intent = new Intent(getApplicationContext(), MyIntentService.class);
    final PendingIntent pIntent = PendingIntent.getBroadcast(this, 100,intent, PendingIntent.FLAG_UPDATE_CURRENT);
    long firstMillis = System.currentTimeMillis();
    AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
    alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis, AlarmManager.INTERVAL_FIFTEEN_MINUTES, pIntent);

The BroadcastReceiver

public class NotificationBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

    Intent in = new Intent(context, MyIntentService.class);
    context.startService(in);
}
}

The IntentService

public class MyIntentService extends IntentService {
    public MyIntentService(String name) {
        super(name);
    }
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d("NotifIntentService", "Starting");
        //My task here
    }
}

I can't figure out what i'm doing wrong here. Please help


Solution

  • I have been stuck on the same issue for days and eventually found out that there is no proper way to do it yet but to ask users to give some permissions (auto start, batter saver optimizations etc..)

    you can find more information here: https://dontkillmyapp.com

    This question is asked in many different ways with no good answers, but here you can probably find some answers which it's abstract will be what I just told you. Work Manager on chinese ROMs like Xiaomi and oppo, when under battery optimization, increase the scheduled delay of work by several hours