0

I am using work manager Onetime Request to perform the task. First the alarm manager gets call in given frequency and from alarm manager receiver class, work manager class gets called. All code was working fine, but suddenly the work manager doWork is not getting called. Flow is coming till alarm manager receiver but not proceeding further.

Alarm Manager Receiver class

public class WorkAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    final String TAG = "WorkAlarmReceiver";
    if (BuildConfig.DEBUG) {
        Log.i(TAG, "onReceive: intent=" + intent);
    }
    OneTimeWorkRequest startWork = new OneTimeWorkRequest.Builder(WorkManagerForTools.class).build();
    WorkManager.getInstance(context).enqueueUniqueWork("Validate Tool", ExistingWorkPolicy.APPEND_OR_REPLACE , startWork);

}

This Receiver is calling fine in given time interval

        //checking if alarm is working with pendingIntent
        Intent workIntent = new Intent(mContext,
                WorkAlarmReceiver.class)
                .setAction(Long.toString(System.currentTimeMillis()
        PendingIntent workPendingIntent = PendingIntent.getBroadcast(mContext, 1001,
                workIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        Log.e(TAG, "New data of pending intent: " + workSpecId + " local work id, " + localWorkId +
                " tools id list " + updatedMobileAppToolIds);
        if(BuildConfig.DEBUG) {
            Log.d(TAG, "New data of pending intent: " + workSpecId + " local work id, " + localWorkId +
                    " tools id list " + updatedMobileAppToolIds);
        }
        boolean isWorking = (PendingIntent.getBroadcast(mContext, 1001, workIntent, PendingIntent.FLAG_NO_CREATE) != null);//just changed the flag
        if (isWorking) {
            alarmManager.cancel(workPendingIntent);
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
                    10 * (minFrequency / 10), workPendingIntent);
        } else {
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
                    10 * (minFrequency / 10), workPendingIntent);
        }

The alarm manager receiver class then call workmanager class. Here is the work manager class

    @SuppressLint("WrongThread")
@NonNull
@Override
public Result doWork() {
    // Code to be execute

}

Any help on this Appreciated.

  • Do you want to call doWork() method repeatedly based on scheduled time ? – nethra gowda Jun 21 '22 at 07:43
  • Yes, it should call repeatedly, but only when the previous request gets completed in doWork method. – Ali Chandorewala Jun 21 '22 at 08:03
  • I believe you can make use of periodic work request instead of enqueueUniqueWork. Refer this https://medium.com/swlh/periodic-tasks-with-android-workmanager-c901dd9ba7bc – nethra gowda Jun 21 '22 at 08:08
  • Thanks for the suggestion, but I want to trigger the work manager in 5min of interval and I saw here https://medium.com/androiddevelopers/workmanager-periodicity-ff35185ff006 that minimum 15 min start time is expected with work manager. So I am triggering alarm manager in 5 minutes interval ( Interval will be configurable) and from receiver class, I am triggering work manager. – Ali Chandorewala Jun 21 '22 at 08:29
  • I only want that what could be the reason for not calling of doWork(), whether it is a one time request or periodic. – Ali Chandorewala Jun 21 '22 at 08:32
  • What is your workPendingIntent here ? – nethra gowda Jun 21 '22 at 08:42
  • workPendingIntent is Pending Intent for alarm manager parameters. – Ali Chandorewala Jun 21 '22 at 08:48
  • Can you post the entire code starting from initialization of Alarmanager & where exactly you're calling the above code for alarmManager – nethra gowda Jun 21 '22 at 09:05

2 Answers2

0

You can achieve scheduled tasks using periodic work requests. Here's how you can do it:

  • Define constraints like if device should be connected or should have sufficient battery.

  • Now create a periodic request with constraints & if required define a tag name. Also set a delay this which will set a initial delay for your work to start.

  • And create a enqueueUniquePeriodicWork by providing unique work name & the ExistingPeriodicWorkPolicy which you can read here ExistingPeriodicWorkPolicy Enum values

  • By default periodic work will take 15 minutes to execute the work request.

    Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).setRequiresBatteryNotLow(true).build();
    
    PeriodicWorkRequest periodicRequest = new PeriodicWorkRequest.Builder(MyWorkerClass.class, 15, TimeUnit.MINUTES)
              .addTag("myPeriodicRequest")
              .setConstraints(constraints)
              .setInitialDelay(5, TimeUnit.MINUTES)
              .build();
    WorkManager.getInstance(context).enqueueUniquePeriodicWork("myPeriodicRequest", ExistingPeriodicWorkPolicy.APPEND_OR_REPLACE, periodicRequest);
    
nethra gowda
  • 290
  • 1
  • 4
  • 23
  • The 15min means only that the TIME CONSTRAIN will be satisfied in 15 minutes. In no way this guarantees any execution. Also, what is the point of code to have a 5min interval as you have mentioned that the minimum is 15min. What will happen is that the WM will log an error saying that it is changing the time to 15min. – Yavor Mitev Jun 21 '22 at 15:13
  • Also be carefull with chinese rom like on Xiaomi phones, the workManager doesn't seems to work if you close the app. Check this [question](https://stackoverflow.com/questions/59906497/work-manager-on-chinese-roms-like-xiaomi-and-oppo-when-under-battery-optimizati) – ScottexBoy Jul 13 '22 at 08:27
0

You are missing the point on how the WorkManager should be used. You can be exact with AalarmManager, but then you pass your execution to something inexact - the WorkManager. So no point in using the AlarmManager at all. Just use the WorkManager directly with either Periodic Request or maybe some Trigger. You can check more here in my answer comparing the different APIs.

Background processing in modern Android

Yavor Mitev
  • 1,363
  • 1
  • 10
  • 22
  • If I use only work manager with Periodic work request it will not meets to my requirement of EVERY 5 MINUTES. The one time request was running in every 5 minutes of alarm manager. All the codes I have posted was working as expected but then the the receiver class is not calling the work manager class so my flow is not moving ahead. I tried clean build, invalid cache of android studio in order to make things work, but it could not work. – Ali Chandorewala Jun 21 '22 at 09:51
  • Please read my other comment. "Every 5min is totally going against the system". You can't achieve for sure with WorkManager in a consistent way. Just have a Service running constantly – Yavor Mitev Jun 21 '22 at 10:15
  • I have resolved the service calling timer challenge (Call my work in 5 minutes of interval) using JobIntentService. In WorkAlarmReceiver class, instead of calling WorkManager I called JobIntentService class and enqueue it. – Ali Chandorewala Jul 06 '22 at 07:32