How to detect application exit on android?

28,011

Solution 1

I don't know if that help, but if you kill your app, then service that runs in background calls method:

@Override
public void onTaskRemoved(Intent rootIntent){

    super.onTaskRemoved(rootIntent);
}

For example I had once app that was running service. When I killed app - service died too, but I wanted it to stay alive. By using onTaskRemoved I was able to schedule restart of service:

@Override
public void onTaskRemoved(Intent rootIntent){
    Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
    restartServiceIntent.setPackage(getPackageName());

    PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarmService.set(
            AlarmManager.ELAPSED_REALTIME,
            SystemClock.elapsedRealtime() + 1000,
            restartServicePendingIntent);

    super.onTaskRemoved(rootIntent);
}

Effect was -> I am killing my app -> Service see that tasks are being removed and calls onTaskRemoved -> I am scheduling restart of service in 1 sec -> Service dies -> After one sec it wakes up -> RESULT: App is killed, i executed code that restarted my service so it is still running in background (visible only in preferences -> applications as process)

http://developer.android.com/reference/android/app/Service.html

void     onTaskRemoved(Intent rootIntent)

This is called if the service is currently running and the user has removed a task that comes from the service's application.

Solution 2

My experience shows that most apps do not really need an exit-callback of the sort you are describing.

The Android way, which usually works fine, is of component-level (Activity, Service..) lifecycle management.

Some apps allow for an 'Exit' functionality (via button, menu etc.) that, when activated by the user, allows the app to close all open components and basically go down.

But, if exit-callback is really what you want, the closest thing to it would probably be to create a dedicated service with no logic other than onDestroy() function and to activate it at app startup without ever closing it!

class ExitListenerService extends Service {
    @Override
    public void onDestroy() {
        super.onDestroy();
        // App exit logic here. Not deterministic!
    }       
}

The odds are such a service will probably be the last component to be reclaimed by the operating system. This should work in most cases, it worked fine for me. But it is not 100% guaranteed.

But.. if you must have a bullet proof solution the only other way I know is to create a peer application, call it watchdog, that will periodically wake up to check weather or not your main app is still running and, if not running, will activate the exit logic.

To run this last check you will need to call

  List<RunningAppProcessInfo> runningApps = activityManager.getRunningAppProcesses();

and iterate over runningApps looking for your own.

Share:
28,011
Xzil0
Author by

Xzil0

Updated on July 09, 2022

Comments

  • Xzil0
    Xzil0 almost 2 years

    How to execute some code on application exit? I want to delete temp data on application exit. By application exit i mean that app is not running minimized in background and its totally gone.

    I tried to make service that runs in separate process, the service is checking if app process is not running it should delete temp folder. With this approach temp folder is not always deleted because process is still running with the lowest priority.

    I can't do this in OnDestroy().

    Service code:

    [Service(Process = "com.lobomonitor")]
    [IntentFilter(new string[] { "com.androidgui.ProcessMonitorService" })]
    public class ProcessMonitorService : Service
    {
        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            Thread processThread = new Thread(() =>
                {
                    ActivityManager actManager = (ActivityManager) this.GetSystemService(ActivityService);
                    while (true)
                    {
                        Thread.Sleep(1000);
                        IList<ActivityManager.RunningAppProcessInfo> procList = actManager.RunningAppProcesses;
                        procList.Any(i => i.ProcessName.Equals("com.androidgui"));
                        if (!procList.Any(i => i.ProcessName.Equals("com.androidgui")))
                        {
                                FolderManager.Singleton.DeleteTempFolder();
                                break;
                        }
                    }
                });
            processThread.Start();
            return StartCommandResult.RedeliverIntent;
        }
    
        public override IBinder OnBind(Intent intent)
        {
            return null;
        }
    }
    
  • Xzil0
    Xzil0 about 10 years
    Thank you. This is the behavior i wanted. i just called FolderManager.Singleton.DeleteTempFolder(); in OnTaskRemoved().
  • takluiper
    takluiper almost 8 years
    Thank you, I was searching for something like this