93

I need to know when the user kills my app (Force stop). I've been reading the android lifecycle, which has the onStop() and onDestroy() functions, these are related to each activity the user ends on my app, but not when the user forces stop or kills my app.

Is there any way to know when the user kills the app?

CopsOnRoad
  • 175,842
  • 51
  • 533
  • 380
Darknoe
  • 1,150
  • 1
  • 9
  • 11
  • 1
    It's simply not possible. See http://stackoverflow.com/questions/16013578/how-to-detect-if-android-app-is-force-stopped-or-uninstalled – transporter_room_3 Jan 10 '14 at 09:23
  • Why do you need to know when they kill the app? If your app is coded well, you really wouldn't care if they killed it. – npace Jan 10 '14 at 09:30
  • 2
    Project specifications need to know when a user kills this app. I don't like this approach, but i have to code what they ask me to. – Darknoe Jan 10 '14 at 09:34
  • 9
    No matter if an app is well coded or not, you may want to know when it is suspended, killed or any other state change for information purposes @npace. – Vicenç Gascó Jan 10 '14 at 09:35
  • 3
    Yes, you may want to know. But it's not really possible - by "well coded" I mean "coded in a way that does not depend on functionality that does not exist in Android at this time" – npace Jan 10 '14 at 09:37

7 Answers7

146

I have found one way to do this.....

  1. Make one service like this

    public class OnClearFromRecentService extends Service {
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d("ClearFromRecentService", "Service Started");
            return START_NOT_STICKY;
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.d("ClearFromRecentService", "Service Destroyed");
        }
    
        @Override
        public void onTaskRemoved(Intent rootIntent) {
            Log.e("ClearFromRecentService", "END");
            //Code here
            stopSelf();
        }
    }
    
  2. Register this service in Manifest.xml like this

    <service android:name="com.example.OnClearFromRecentService" android:stopWithTask="false" />
    
  3. Then start this service on your splash activity

    startService(new Intent(getBaseContext(), OnClearFromRecentService.class));
    

And now whenever you will clear your app from android recent Then this method onTaskRemoved() will execute.

NOTE: In Android O+ this solution only works when the app is full-time in foreground. After more than 1 minute with the app in background, the OnClearFromRecentService (and all other Services running) will be automatically force-killed by the system so the onTaskRemoved() will not be executed.

user3429953
  • 332
  • 2
  • 15
Faisal Khan
  • 2,474
  • 3
  • 18
  • 35
  • great use of the Service class to achieve this. – Paul John Parreno Apr 22 '16 at 11:07
  • great solution, thumbs up – User42590 Sep 23 '16 at 06:02
  • Have u any solution when user force close app from setting our service runs automatically? – Manisha Oct 14 '16 at 14:26
  • 13
    I recently added onTaskRemoved() in a way similar to the way described here and it worked. Except on HUAWEI and XIOMI devices. For some reason this method is never called on those devices. Any ideas why? – Alon Minski Nov 17 '16 at 15:28
  • Clicking "Force Stop" explicitly doesn't trigger onDestroy for all devices. – stdout Dec 22 '16 at 09:53
  • 2
    This works great. Any reason onTaskRemoved is not declared as an override? – Florian Doyon Jan 19 '17 at 23:13
  • 1
    Is it possible to save data in that? example to sqlite. – K.Sopheak Jan 20 '17 at 06:53
  • Yes it is possible @K.Sopheak – Faisal Khan Jan 21 '17 at 13:13
  • No i just forgot to override it. @FlorianDoyon – Faisal Khan Jan 21 '17 at 13:16
  • can i set a Alarm in the `onTaskRemoved()` and will it gets canceled immediately because App will be Killed after execution of `onTaskRemoved()` ? – Kunal Awasthi Aug 08 '17 at 08:44
  • 1
    I recently added onTaskRemoved() in a way similar to the way described here and it worked. Except on HUAWEI and XIOMI devices. For some reason this method is never called on those devices. Any ideas why? me also have the same problem plese help me – Rajaji subramanian Oct 25 '17 at 13:42
  • i try i working for me for some time but than after it stop working onStartCommand() called every time but onTaskRemoved() not called what is the problem? – nilesh prajapati Feb 20 '18 at 09:54
  • On API 26, most of the background services are killed by system even though the app is still on recent apps and clicking recent apps try to continue savedInstanceState. – fthdgn Mar 26 '18 at 21:45
  • @AlonMinski It's because those manufacturers add custom apps for battery saving that kill your background services once you clear your app from the recents list. You have to manually protect your app against this system. Or else, your services will only be restarted when user opens the app again – joao2fast4u Apr 11 '18 at 13:55
  • 2
    very helpful, but any one test with HUWAI or XIOMI phone. as per @Alon Minski said – Vrajesh Apr 25 '18 at 09:22
  • @Vrajesh Yes i have tested it. It is working fine with one change. Service that you are starting from onTaskRemoved, You need to add on Toast in oncreate method. it will work fine. – Faisal Khan Apr 26 '18 at 09:20
  • @FaisalKhan i dont think so for toast. this process / service is totally invisible for user. but thanks for comment. right now i put onTaskRemoved() code in onDestroy() as well for safety or ANR exception. is it good ? – Vrajesh Apr 27 '18 at 06:34
  • I have a object reference that should be saved while user killing app. I used onTaskRemoved method, this method is calling as expected, but the object reference is cleared(null). Is there any other callback there i can save the reference before it is cleared. – Anbarasu Chinna Jan 17 '19 at 14:11
  • @AnbarasuChinna Objects in Android shares the same memory with the app so once the app is killed it means everything is cleared. But you can do one thing here, convert the object into JSON and pass into the service. I hope this will work for you. – Faisal Khan Jan 17 '19 at 21:29
  • 1
    @FaisalKhan I've pretty much implemented your solution verbatim. while `onStatCommand()` is called, `onDestroy()` and `onTaskRemoved()` never get called. any thoughts on what i might be doing wrong? – El Sushiboi Feb 20 '20 at 17:53
  • I've implemented this solution but not working.Can you please tell me am i doing any wrong? – Surekha May 12 '20 at 11:39
  • No this will not work on API > 26 with the new restriction of google on background services. – Faisal Khan May 29 '21 at 19:48
  • For the win! Thank you very much for this answer. – topherPedersen Apr 07 '22 at 23:05
29

there's no way to determine when a process is killed. From How to detect if android app is force stopped or uninstalled?

When a user or the system force stops your application, the entire process is simply killed. There is no callback made to inform you that this has happened.

When the user uninstalls the app, at first the process is killed, then your apk file and data directory are deleted, along with the records in Package Manager that tell other apps which intent filters you've registered for.

Community
  • 1
  • 1
Taranfx
  • 10,273
  • 15
  • 75
  • 95
  • 18
    Fine. Great. It is not possible. Then what can we do as developers to anticipate to out app being killed? My app is experiencing weird behaviors when I reopen it after being inactive for +30 min aprox. – Josh Oct 25 '17 at 10:20
5

Create a Application class

onCreate()
Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created.
onLowMemory()
This is called when the overall system is running low on memory, and actively running processes should trim their memory usage.
onTerminate()
This method is for use in emulated process environments.

Even if you are application Killed or force stop, again Android will start your Application class

rajahsekar
  • 916
  • 1
  • 11
  • 25
1

After digging into this problem I found a solution that might help you:

All you need to do is check on the onDestroy method of your BaseActivity that is extended by all your activities whether the last running activity of the stack is from your package or not with the following code:

ActivityManager activityManager = (ActivityManager) getSystemService( ACTIVITY_SERVICE );

List<ActivityManager.RunningTaskInfo> taskList = activityManager.getRunningTasks( 10 );

if ( !taskList.isEmpty() )
    {
     ActivityManager.RunningTaskInfo runningTaskInfo = taskList.get( 0 );
      if ( runningTaskInfo.topActivity != null && 
              !runningTaskInfo.topActivity.getClassName().contains(
                    "com.my.app.package.name" ) )
         {
        //You are App is being killed so here you can add some code
         }
    }
1

for some cases, you can create splash screen page to determine if app has been killed previously by system.

it basically a screen with intent filter main/launcher, and will be finished, and changed to main activity.

so, every time user visit splashScreen, it shows that the app has been killed before, and you can do anything you want to handle.

sample code:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="id.gits.yourpackage">

    <application
        android:name=".App">
        <activity android:name=".SplashActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

SplashActivity:

class SplashActivity : AppCompatActivity() {
    override fun onCreate() {
        super.onCreate()
        doSomethingAfterAppKilled()
    }
}
nashihu
  • 275
  • 2
  • 10
-1

This might help many, who wants to know if the app is terminated or not The best way is to keep data in one static variable for eg: public static string IsAppAvailable;

the specialty about the static variable is that the data in the static variable contains till the app is in foreground or background, once the app is killed the data in the static variable is erased. Basically, the static variable is reinitialized when the app is freshly created

Create one static class file say Const

namespace YourProject
{
    public static class Const
    {
        public static string IsAppAvailable;
     }
}

In MainActivity

   protected override void OnResume()
    {
       if(string.IsNullOrWhiteSpace(Const.IsAppAvailable))
       {
          //Your app was terminated
       }
       Const.IsAppAvailable = "Available" 
    }

Hope this is helpful to the developers :) Happy coding

-5

I have alternate idea.i have same problem like you.above methods not fix.my problem : "i want to clear all saved data entire app,when user completely close the app"

So, i added clear() & clear saved data(from shared preference or tinyDB) in Application class.