I am currently developing an email application which relies on a background service
in order to be able to automatically fetch new emails. This works perfectly when the application is open (or in the running list of apps) but as soon as I close the app / remove it from the recent apps list, the service
is also stopped. This can be confirmed by going into the 'Developer Settings' on the device and seeing that there are no processes or services running for my application.
I have read countless threads on StackOverflow but none of them seem to be doing the trick. Sometimes onTaskRemoved
() is called and the service is restarted but then other times it isn't called at all or it is called, the logs show that the OS has scheduled a restart of the service
but then the service
gets forced closed
by the OS whereas I always need to have this service running to retrieve new emails.
My current code can be seen below:
My Service:
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.i(TAG, "onStartCommand()");
...
Log.d(TAG, "SERVICE IS RUNNING");
if (host != null) {
Log.d(TAG, "STARTING PUSH SERVICE");
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
Log.d(TAG, "BR: " + ((BugReporting) getApplication()));
sharedRunnable = ((BugReporting) getApplication()).getSharedRunnable();
MailPush mailPush = new MailPush(getApplicationContext(), sharedRunnable);
Log.d(TAG, "sharedRunnable 1: " + sharedRunnable);
mailPush.checkInboxEmail(host, email, password);
//mailPush.checkSentEmail(host, email, password);
}
};
handler.postDelayed(runnable, 5000);//0.5 seconds
}
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate()");
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(TAG, "onTaskRemoved()");
PendingIntent service = PendingIntent.getService(
getApplicationContext(),
1001,
new Intent(getApplicationContext(), MyService.class),
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
startService(new Intent(this, MyService.class));
}
Reboot Receiver:
public class AutoStart extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, MyService.class));
}
}
Manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<receiver
android:name="uk.co.tundracorestudios.securemail.notification.AutoStart"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="uk.co.tundracorestudios.securemail.notification.MyService"
android:enabled="true"
android:exported="true"
android:label="@string/mail_service"
android:stopWithTask="false"/>
I did attempt to run MyService
as a different process
but this then restricted me from getting the sharedRunnable
that I have saved in the application class which can otherwise be access through:
updateListRunnable = ((BugReporting) getApplication()).getSharedRunnable();
Therefore, I am asking, how can I ensure that my service
continuously runs / works even when the application is closed or when the device is rebooted
whilst still having access to the components located in getApplication()
?
As when I attempted to run MyService
as a separate process
, the above updateListRunnable
would always return null whereas when the application and service
were running in the same process
, it would return the correct runnable
.
If your Service is started by your app then actually your service is running on main process. so when app is killed service will also be stopped. So what you can do is, send broadcast from onTaskRemoved method of your service as follows: Intent intent = new Intent("com.
See below how to do these: Call Thread. setDefaultUncaughtExceptionHandler() in order to catch all uncaught exception, in which case uncaughtException() method will be called. "Force close" will not appear and the application will be unresponsive, which is not a quite good thing.
I faced a similar issue a while back and used this in the onDestroy() method of my service:
public void onDestroy() {
Intent restartService = new Intent(getApplicationContext(),this.getClass());
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(),1,restartService,PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME,5000,pendingIntent);
super.onDestroy();
}
When the service is being destoyed I set an alarm of 5 second, which will start my service aagain. This way your service will stop when user remove it from recent but it will start again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With