Search code examples
androidandroid-workmanagerandroid-backgroundandroid-doze

Need to have one background task to run for every minute in android


In one of my android applications, I need to run a task for every minute. It should run even if the app closes and when device is in Idle state also.

  1. I have tried handler, it is working fine when device is active, but not working when device is in idle state.
  2. I have tried workmanager(one time and repeated ) as well. Document says this works even when the device is in Idle mode, but this is stops working after 3/4 repeats.Workmanager is inconsitent, its working sometimes and not working most of the cases till i reboot device.

Can anyone suggest better way to handle the situation?

Thanks bhuvana


Solution

  • Work manager can only work within 15 minutes of interval, if you do not define a longer time. To run something every minute, you need a Foreground Service with a sticky notification in it. There is no other way to run something every minute.

    To start a foreground service, create a service as usual, and in its onStartCommand, call startForeground and from the method, return START_STICKY. These should achieve what you need.

    Edit: Sample code for handler thread (this is Java btw, should be similar on Xamarin):

    private HandlerThread handlerThread;
    private Handler backgroundHandler;
    
    @Override
    public int onStartCommand (params){
    
        // Start the foreground service immediately.
        startForeground((int) System.currentTimeMillis(), getNotification());
    
        handlerThread = new HandlerThread("MyLocationThread");
        handlerThread.setDaemon(true);
        handlerThread.start();
        handler = new Handler(handlerThread.getLooper())
    
        // Every other call is up to you. You can update the location, 
        // do whatever you want after this part.
    
        // Sample code (which should call handler.postDelayed()
        // in the function as well to create the repetitive task.)
        handler.postDelayed(() => myFuncToUpdateLocation(), 60000);
    
        return START_STICKY;
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        handlerThread.quit();
    }