2

I have a service that starts in my Application class in my android app.

The service runs every hour, and I do not want it to start every time the app is opened, which seems to be what its doing now. I want to check if it is running, and if it isnt, then run it.

I found this code in another answer that I thought would work, but if I run the app twice I still get the message 'Service is not running, Job Scheduled' from the below code:

public class App extends Application {

    public static final String TAG = "Application";
    public static final int JOB_NUMBER = 3007;

    @Override
    public void onCreate() {
        super.onCreate();
        if(!isMyServiceRunning(DevotionalService.class)) {
            ComponentName componentName = new ComponentName(this, DevotionalService.class);
            JobInfo info = new JobInfo.Builder(JOB_NUMBER, componentName)
                    .setRequiresCharging(false)
                    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
                    .setPersisted(true)
                    .setPeriodic(60 * 60 * 1000)
                    .build();
            JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
            int resultCode = scheduler.schedule(info);
            if (resultCode == JobScheduler.RESULT_SUCCESS) {
                Log.d(TAG, "Service is not running, Job Scheduled.");
            } else {
                Log.d(TAG, "Service is not running, However job scheduling failed.");
            }
        } else {
            Log.d(TAG, "Service is already running.");
        }
    }

    private boolean isMyServiceRunning(Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

    public void cancelJob() {
        JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
        scheduler.cancel(JOB_NUMBER);
        Log.d(TAG, "Job Cancelled.");
    }
}

Does anyone have any insight as to why this might be?

Markus Kauppinen
  • 3,025
  • 4
  • 20
  • 30
Chud37
  • 4,907
  • 13
  • 64
  • 116

1 Answers1

10

To check if a service is running:

class MyService extends Service {
   private static boolean isRunning;
   public int onStartCommand (Intent intent, 
                int flags, 
                int startId) {
        isRunning = true;
        ...
   }
   public void onDestroy() {
       isRunning = false;
   }
   public static boolean isRunning() { 
       return isRunning;
   }
}

Then to check if its running, just check MyService.isRunning().

To check if a service is scheduled:

if(JobScheduler.getPendingJob(jobID) == null) {
   //job notscheduled
}
Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • Hmm, interesting!! Your answer makes me think I've phrased my question incorrectly. I dont want to know if its *running*, just if its already been scheduled to run in the future, as in, "Have I already scheduled this service?" – Chud37 Aug 28 '18 at 08:52
  • @Chud37 Ok, yes that's a different question altogether. But your code sample you posted isn't going to do that either, its also looking at what's currently running. ActivityManager.getRunningServices() knows nothing about what's scheduled in the future. – Gabe Sechan Aug 28 '18 at 08:53
  • 1
    @Chud37 For what you want, try JobScheduler.getPendingJob(int jobID). That will return non null if already scheduled. – Gabe Sechan Aug 28 '18 at 09:00
  • Thank you, If you want to post an alternative answer I'll mark it as correct. I can't delete this thread now! Sorry for the confusion! – Chud37 Aug 28 '18 at 09:02