9

i am trying to write a periodic workmanager script but it just run when i open the app and it just run one time (not periodic) !

here is my main activity :

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_work);

    Intent intent = new Intent();
    PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,0,intent,0);
    NotifyWorker.pendingIntent = pendingIntent;
    NotifyWorker.context = this;

    PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(NotifyWorker.class, 1, TimeUnit.MINUTES).build();
    WorkManager.getInstance().enqueue(periodicWorkRequest);
}

}

and this is my dowork method :

public Result doWork() {
    Log.i("wd","wd");

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context,"ctx")
            .setSmallIcon(R.mipmap.ic_launcher)
            .setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_launcher))
            .setSmallIcon(R.drawable.logo)
            .setContentTitle("Title")
            .setContentText("Desc")
            .setContentIntent(pendingIntent);

    android.app.NotificationManager notificationManager =
            (android.app.NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(0 , notificationBuilder.build());

    return Result.SUCCESS;
}

why its not run every 1 minute ? what i miss ?

Qasem Salehy
  • 165
  • 2
  • 2
  • 10

2 Answers2

42

Per the PeriodicWorkRequest.Builder documentation:

The intervalMillis must be greater than or equal to PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS

That value is currently set to 900000 - i.e, 15 minutes.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • 4
    oh ! my bad . next question : why my work manager trigger 3 or 4 time then stop working ! its not keep going after i close the app ! it should work after closing the app , isn't it ?!?! – Qasem Salehy Jul 01 '18 at 20:00
  • 1
    If you just mean hitting the system back button to leave your app, that shouldn't affect WorkManager. Keep in mind that WorkManager doesn't run with exact timing and won't run in doze mode. – ianhanniballake Jul 01 '18 at 21:00
  • 2
    @ianhanniballake is Work Manager runs even if we killed the app? – ysfcyln Aug 07 '18 at 16:51
  • @ysfcyln - nothing from an app runs if the app is forced stopped, but the next time the app is started any work that still needs to be run is run. – ianhanniballake Aug 11 '18 at 23:04
  • 1
    was testing it setting it to run every few seconds, did not notice this in the documentation. Thanks – Arnav Rao Sep 21 '18 at 06:46
  • Thanks a lot, IDE could give some info on this though ;/ am I right? :) – Krzysztof Kubicki May 09 '19 at 14:50
  • @ianhanniballake-> what about WorkRequest that run on KitKat ? WorkManager should use BroadcastReceiver and Service, this should be permanent even if app is killed, right? – Krzysztof Kubicki May 09 '19 at 14:51
  • @KrzysztofKubicki - alarms are also cleared when your app is force stopped. – ianhanniballake May 09 '19 at 16:24
  • @ianhanniballake - Are you sure that WorkManager won't work in doze mode? – Rasool Mohamed May 22 '19 at 13:04
  • @RasoolMohamed yes normally work manager will not work in doze mode, tested it using logs. – humble_wolf Jan 08 '20 at 07:19
  • @humble_wolf : Is there any solution to make this work even in Doze mode? – AndroidGuy Feb 27 '20 at 06:29
  • @AndroidGuy this might help, https://developer.android.com/training/monitoring-device-state/doze-standby#using_fcm – humble_wolf Feb 27 '20 at 12:21
  • my problem is is that in emulator it works fine. but in real devices, i do not get any notification. is it possible the system ignores running the periodic work in some cases? – chitgoks Jun 05 '20 at 05:07
1

First of all, you can disagree with my answer but here is the hack which I used in my project and this work very accurately without gives any problem. It's time to see the code. One thing I pointed later and must read this point after the code. SECTION IMP

//this code in your activity, fragment or any other class
notify_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked)
                {
                    OneTimeWorkRequest track_share_market = new OneTimeWorkRequest.Builder(NotificationWorker.class).setInitialDelay(1,TimeUnit.MINUTES).addTag("Stock_Market").build();
                    WorkManager.getInstance().enqueue(track_share_market);
                    Log.d("RishabhNotification","SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSs");
                }
                else {
                    Log.d("RishabhNotification","FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
                    WorkManager.getInstance().cancelAllWorkByTag("Stock_Market");
                }
            }
        });

Now your Worker class Code

public class NotificationWorker extends Worker {

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

    @NonNull
    @Override
    public Result doWork() {
        try {
         //Some heavy operation as you want there is no need to make another thread here 
          //track some website for weather changes or stock market changes
         //In my case doWork takes only 10sec for executing this method  

            ShowNotification("Market Up","Gold Price goes upto ₹25,000 ","Check the app for the new update");
            StartNewRequest();
            return Result.success();

        } catch (Exception e) {
            e.printStackTrace();
            StartNewRequest();
            Log.d("RishabhNotification","ERERERERERERERERERERERERERERERERERERERERERERERERERERERE");
            return Result.failure();
        }
    }

 private void StartNewRequest()
    {
        OneTimeWorkRequest track_market = new OneTimeWorkRequest.Builder(NotificationWorker.class).setInitialDelay(1,TimeUnit.MINUTES).addTag("Stock_Market").build();
        WorkManager.getInstance().enqueue(track_market);
    }

    private void ShowNotification(String Message, String name, String Information)
    {
        NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
        String NOTIFICATION_CHANNEL_ID = "my_channel_id_01";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Stock Market", NotificationManager.IMPORTANCE_HIGH);

            // Configure the notification channel.
            notificationChannel.setDescription("Channel description");
            notificationChannel.enableLights(true);
            notificationChannel.setLightColor(Color.GREEN);
            notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
            notificationChannel.enableVibration(true);
            notificationChannel.setSound(null,null );
            notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            notificationManager.createNotificationChannel(notificationChannel);
        }


        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), NOTIFICATION_CHANNEL_ID);

        Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        notificationBuilder.setAutoCancel(false)
                .setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_VIBRATE|Notification.DEFAULT_LIGHTS)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setSound(uri)
                .setVisibility(Notification.VISIBILITY_PUBLIC)
                .setPriority(Notification.PRIORITY_MAX)
                .setContentTitle(Message)
                .setContentText(name)
                .setContentInfo(Information);

        notificationManager.notify(/*notification id*/1, notificationBuilder.build());
    }
}

Now Read the SECTION IMP point This Code perfectly working in Emulator, Pixel phone, Samsung phone, Moto phone, Asus Phone, One plus phone but this same code I tested in the Xioami Devices and Huawei devices they both devices not run the code for every specific time interval(They both run the code but time may be changed) which I define in my code. I don't know why is this happen on both devices. Maybe some optimization. Check this link for more https://www.reddit.com/r/androiddev/comments/9ra0iq/workmanager_reliability_for_periodic_tasks_on/ I have not tested this code in vivo and Oppo devices.

Rishabh Rawat
  • 1,083
  • 9
  • 15