I'm using WorkManager to keep my foreground service running even after my app is killed. When I run my app, WorkManager starts my service immediately. But when I kill my app, WorkManager takes ~3 minutes to starts my service. I can't afford any delay, as my service has a broadcast receiver to receive SMS, and my functionality requires that I don't miss even a single SMS - I might miss some SMS if my work manager starts my foreground service after a delay.
How do I make work manager start my service immediately after killing the app?
This is the code I'm using for WorkManager:
public class DemoSyncJob extends Worker {
public static final String TAG = ">>>> job_demo_tag";
public DemoSyncJob(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@Override
@NonNull
public Worker.Result doWork() {
// run your job here
Log.d(TAG, "onRunJob: ");
if(!isMyServiceRunning(getApplicationContext(), MessageReceiverService.class)){
Intent intent=new Intent(getApplicationContext(),MessageReceiverService.class);
getApplicationContext().startService(intent);
}
scheduleJob();
return Worker.Result.success();
}
public static WorkRequest scheduleJob() {
return new OneTimeWorkRequest.Builder(DemoSyncJob.class)
.build();
}
public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
try {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
}catch (Exception e){
Log.e(TAG, "isMyServiceRunning: ",e );
}
return false;
}
}
I'm using the following version of WorkManager:
implementation 'androidx.work:work-runtime:2.4.0'
And this:
implementation "com.google.android.gms:play-services-gcm:17.0.0"
This is the code for MessengeReceiverService.java:
public class MessageReceiverService extends Service
{
private static BroadcastReceiver br_ScreenOffReceiver;
private static MessageListener mListener;
SharedPreferences sharedPreferences;
SharedPreferences.Editor myEdit;
public static final String CHANNEL_ID = "ForegroundServiceChannel";
@Override
public IBinder onBind(Intent arg0)
{
return null;
}
@Override
public void onCreate()
{
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText("Hi, Sparsh Contento Dutta here")
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build();
startForeground(100, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
registerScreenOffReceiver();
return START_STICKY;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
"100",
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
@Override
public void onDestroy()
{
unregisterReceiver(br_ScreenOffReceiver);
}
private void registerScreenOffReceiver()
{
br_ScreenOffReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Entered onReceive()", Toast.LENGTH_LONG).show();
Log.i(TAG, "Entered onReceive");
sharedPreferences= context.getSharedPreferences("MySharedPref", MODE_PRIVATE);
myEdit=sharedPreferences.edit();
Bundle data = intent.getExtras();
Object[] pdus = (Object[]) data.get("pdus");
String recMsgString = "";
for(int i=0; i<pdus.length; i++){
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
byte[] userData = smsMessage.getUserData();
if (userData!=null){
for(int index=0; index<userData.length; ++index)
{
recMsgString += Character.toString((char)userData[index]);
}
}
String message =
"Service center address: " + smsMessage.getServiceCenterAddress()+
"\nPseudo object: " + smsMessage.getPseudoSubject() +
"\nDisplay originating address : " + smsMessage.getDisplayOriginatingAddress()
+ "\nOriginating address : " + smsMessage.getOriginatingAddress()
+"\nUser data : " + recMsgString
+ "\nEmail From: " + smsMessage.getEmailFrom()
+ "\nEmail Body: " + smsMessage.getEmailBody()
+ "\nDisplay message body: " + smsMessage.getDisplayMessageBody()
+ "\nTime in millisecond: " + smsMessage.getTimestampMillis()
+ "\nMessage: " + smsMessage.getMessageBody();
if (mListener!=null)
mListener.messageReceived(message);
myEdit.putString("message", message);
myEdit.apply();
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(br_ScreenOffReceiver, filter);
}
public static void bindListener(MessageListener listener){
mListener = listener;
}
}
How do I solve this issue?