For making a Service run continuously, start a Job scheduler to make this job be a part of android system jobs.
package com.xxx;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class XXJobService extends JobService {
private String TAG = "XXJobService";
private Context context;
public XXJobService() {
}
@Override
public boolean onStartJob(JobParameters params) {
context = this;
try {
if (!MyApp.isServiceRunning(context, MainService.class.getName())) {
Log.i(TAG, "onStartJob : MainService not running so start");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.getApplicationContext()
.startForegroundService(new Intent(context, MainService.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
} else {
context.getApplicationContext()
.startService(new Intent(context, MainService.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
}
} catch (Exception e) {
Log.e(TAG, "Exception - MainService not running: " + e.getLocalizedMessage());
}
Log.i(TAG, "onStartJob, returnValue = " + returnValue);
return returnValue;
}
@Override
public boolean onStopJob(JobParameters params) {
boolean returnValue = true;
Log.i(TAG, "onStopJob, returnValue = " + returnValue);
return returnValue;
}
}
Create an Application class in your project that extends Application and define it in your manifest also.
import android.app.ActivityManager;
import android.app.Application;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import java.util.Arrays;
import java.util.List;
public class MyApp extends Application {
Context context;
private static MyApp instance;
static String TAG = "MyApp";
MainService mainService;
JobScheduler jobScheduler;
private static final int JOB_ID = 1;
public static MyApp getInstance() {
return instance;
}
@Override
public void onCreate() {
super.onCreate();
context = this;
instance = this;
Log.i(TAG, "onCreate: ");
// Job scheduler for android version Lolipop(Android 5.0) and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
ComponentName jobService = new ComponentName(getPackageName(), XXJobService.class.getName());
Log.e(TAG, "onCreate: ComponentName : " + jobService );
JobInfo jobInfo = new JobInfo.Builder(JOB_ID, jobService)
.setPersisted(true)
.setPeriodic(5000)
.build();
int jobId = jobScheduler.schedule(jobInfo);
if (jobId == JobScheduler.RESULT_SUCCESS) {
Log.e(TAG, "JobScheduler RESULT_SUCCESS");
// Toast.makeText(context, "Successfully scheduled job : " + jobId, Toast.LENGTH_SHORT).show();
} else {
Log.e(TAG, "JobScheduler RESULT_FAILURE: " + jobId);
// Toast.makeText(context, "RESULT_FAILURE: " + jobId, Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Log.e(TAG, "JobScheduler Exception : " + e.getLocalizedMessage());
}
}
if (!isServiceRunning(context, MainService.class.getName())) {
try {
Intent intent = new Intent(context, MainService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent);
} else {
startService(intent);
}
} catch (Exception e) {
Log.e(TAG, "Exception startService : " + e.getLocalizedMessage());
}
}
mainService = MainService.getInstance();
Log.e(TAG," MainSerivice : " + mainService);
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
handleUncaughtException(t, e);
}
});
}
public static boolean isServiceRunning(Context context, String serviceClassName) {
if (context == null || serviceClassName.equalsIgnoreCase("")) {
Log.i(TAG, "isServiceRunning called with context = null or service name blank");
return false;
}
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
for (ActivityManager.RunningServiceInfo runningServiceInfo : services) {
if (runningServiceInfo.service.getClassName().equals(serviceClassName))
return true;
}
return false;
}
}
Finally, put a BootUpReceiver to automatically start the notofication and services whenever the phone is restarted. It should have the permission
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<receiver
android:name=".StartupReceiver"
android:enabled="true">
<intent-filter>
<action android:name="com.xx.MainService" />
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>