I am having a little issue.
In my application, a Service is started after user is logged in successfully. Previously, the service needed to stop if application was killed. (say, removed from Recent application list by swiping.) So we had used android:stopWithTask="true"
. Now we need the Service to run as it is, even if the Task which started it, is removed from Recent app list. So I changed the Service to include android:stopWithTask="false"
. But that doesn't seem to work.
Related code:
Here is manifest part related to Service:
<service android:enabled="true" android:name=".MyService" android:exported="false" android:stopWithTask="false" />
In MyService.java:
public class MyService extends AbstractService { @Override public void onStartService() { Intent intent = new Intent(this, MyActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); Notification notification = new Notification(R.drawable.ic_launcher, "My network services", System.currentTimeMillis()); notification.setLatestEventInfo(this, "AppName", "Message", pendingIntent); startForeground(MY_NOTIFICATION_ID, notification); } @Override public void onTaskRemoved(Intent rootIntent) { Toast.makeText(getApplicationContext(), "onTaskRemoved called", Toast.LENGTH_LONG).show(); System.out.println("onTaskRemoved called"); super.onTaskRemoved(rootIntent); } }
AbstractService.java is custom class that extends Sevrice
:
public abstract class AbstractService extends Service { protected final String TAG = this.getClass().getName(); @Override public void onCreate() { super.onCreate(); onStartService(); Log.i(TAG, "onCreate(): Service Started."); } @Override public final int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStarCommand(): Received id " + startId + ": " + intent); return START_STICKY; // run until explicitly stopped. } @Override public final IBinder onBind(Intent intent) { return m_messenger.getBinder(); } @Override public void onDestroy() { super.onDestroy(); onStopService(); Log.i(TAG, "Service Stopped."); } public abstract void onStartService(); public abstract void onStopService(); public abstract void onReceiveMessage(Message msg); @Override public void onTaskRemoved(Intent rootIntent) { Toast.makeText(getApplicationContext(), "AS onTaskRemoved called", Toast.LENGTH_LONG).show(); super.onTaskRemoved(rootIntent); } }
Now if I login in the application, MyService is started. After that I press Home button, so application is moved to background. Now I remove the application from Recent Application's list. At that time, I should see the Toast and console message, as per this method's description:
public void onTaskRemoved (Intent rootIntent)
Added in API level 14
This is called if the service is currently running and the user has removed a task that comes from the service's application. If you have set ServiceInfo.FLAG_STOP_WITH_TASK then you will not receive this callback; instead, the service will simply be stopped.
Parameters rootIntent The original root Intent that was used to launch the task that is being removed.
But I am not seeing any of that. Service is returning START_STICKY in onStartCommand
, So I think onTaskRemoved
should be fired along with flag android:stopWithTask="false"
.
Am I missing anything?
Let me know in case I need to add some code which might be important to figure out what's wrong.
P.S.: I tested this on 4.2.2 till now.
P.S.: I just tested the same code in 4.1.2, on which Service keeps running, and I get the message "onTaskRemoved called" in log, too.
What should I do to make this work in all versions?
The Recents screen (also referred to as the Overview screen, recent task list, or recent apps) is a system-level UI that lists recently accessed activities and tasks. The user can navigate through the list and select a task to resume, or the user can remove a task from the list by swiping it away.
onTaskRemoved(rootIntent); // This method is called when user removed the app from Recents. // By default, the service will be killed and recreated immediately after that. // However, all managed devices will be lost and devices will be disconnected. stopSelf(); } origin: kevalpatel2106/android-hidden-camera.
The general rule is that either onDestroy() is called, or your process is terminated, or your code crashed.
If you bind to your service from a subclass of Application class and hold on to your IBinder connection, the service will remain alive even after the application is removed from the recent apps. Show activity on this post.
When an app is installed this directory and file are automatically created. When an app is uninstalled this directory is deleted along with its parent /data/data/package_name UNLESS the app is uninstalled in order to update it. From command line this is done using the flag -k or -r that is
When an app is uninstalled this directory is deleted along with its parent /data/data/package_name UNLESS the app is uninstalled in order to update it. From command line this is done using the flag -k or -r that is adb uninstall -k package_name - Keep the data and cache directories around after removal
When an app is installed this directory and file are automatically created. When an app is uninstalled this directory is deleted along with its parent /data/data/package_name UNLESS the app is uninstalled in order to update it.
Just follow these scenarios, your service and processes (Threads run inside your service) will remain continuous.
Create service and use START_STICKY as return value in onStartCommand method like below:
@Override public int onStartCommand(final Intent intent, final int flags, final int startId) { //your code return START_STICKY; }
Above code will Restart the service if destroyed and always remain running but the process(Threads) run from the service will stop working if your app is removed from the recent apps. To ensure that your processes(Threads) remains always in running condition you have to Override onTaskRemoved() method and add code to restart Tasks like below.
@Override public void onTaskRemoved(Intent rootIntent){ Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass()); restartServiceTask.setPackage(getPackageName()); PendingIntent restartPendingIntent =PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT); AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); myAlarmService.set( AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartPendingIntent); super.onTaskRemoved(rootIntent); }
startService(new Intent(this, YourService.class));
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