Android checking whether the app is closed

后端 未结 6 1492
孤独总比滥情好
孤独总比滥情好 2020-12-03 12:52

I have an android application i need one function or any broadcast receiver that can check if the app is closed.. i don\'t need to call on destroy in every activity (there i

相关标签:
6条回答
  • 2020-12-03 13:31

    Basically looking at your problem, you want to track the state changes in an app.

    It can be quite difficult to get it right taking care of all the use cases. But there is an amazing library which works very well and is super-easy to use - RxAppState.

    I have been using this library for quite a long time now and it works very well in all cases. I highly recommend you to try this.

    0 讨论(0)
  • 2020-12-03 13:37

    This answer uses ProcessLifecycleOwner to detect application visibility.

    which is a part of Android Architecture Component .


    1. add this lib to your project

    implementation "android.arch.lifecycle:extensions:1.1.1"

    2. Extend an application class that implements LifecycleObserver

    public class AppController extends Application implements LifecycleObserver {
    
    
    ///////////////////////////////////////////////
        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        public void onEnterForeground() {
            Log.d("AppController", "Foreground");
            isAppInBackground(false);
        }
        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        public void onEnterBackground() {
            Log.d("AppController", "Background");
            isAppInBackground(true);
        }
    ///////////////////////////////////////////////
    
    
    
        // Adding some callbacks for test and log
        public interface ValueChangeListener {
            void onChanged(Boolean value);
        }
        private ValueChangeListener visibilityChangeListener;
        public void setOnVisibilityChangeListener(ValueChangeListener listener) {
            this.visibilityChangeListener = listener;
        }
        private void isAppInBackground(Boolean isBackground) {
            if (null != visibilityChangeListener) {
                visibilityChangeListener.onChanged(isBackground);
            }
        }
        private static AppController mInstance;
        public static AppController getInstance() {
            return mInstance;
        }
    
       
       
        @Override
        public void onCreate() {
            super.onCreate();
    
            mInstance = this;
    
            // addObserver
            ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
        }
    
    }
    

    And use it like this:

    AppController.getInstance().setOnVisibilityChangeListener(new ValueChangeListener() {
        @Override
        public void onChanged(Boolean value) {
            Log.d("isAppInBackground", String.valueOf(value));
        }
    });
    

    Don't forget to add application name into your manifest

    <application
        android:name="myPackageName.AppController"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"">
    

    Done.


    (Kotlin example)

    https://github.com/jshvarts/AppLifecycleDemo

    0 讨论(0)
  • 2020-12-03 13:39

    You can use this function to determine if the app is closed ( not in background nor in the foreground).

    private boolean isAppRunning() {
        ActivityManager m = (ActivityManager) this.getSystemService( ACTIVITY_SERVICE );
        List<ActivityManager.RunningTaskInfo> runningTaskInfoList =  m.getRunningTasks(10);
        Iterator<ActivityManager.RunningTaskInfo> itr = runningTaskInfoList.iterator();
        int n=0;
        while(itr.hasNext()){
            n++;
            itr.next();
        }
        if(n==1){ // App is killed
            return false;
        }
    
        return true; // App is in background or foreground
    }
    

    You can also check if the app is in foreground by using this function: https://stackoverflow.com/a/8490088/9005188

    0 讨论(0)
  • 2020-12-03 13:41

    Like @S.R answer, you can also use the interface "Application.ActivityLifecycleCallbacks" in ur custom application, and then in the "onActivityStopped" use the "isAppOnForeground(Context)" method.

    public class MyApplication extends Application import Application.ActivityLifecycleCallbacks{
    
    [ Code of ur app class...]
    
    /* START Override ActivityLifecycleCallbacks Methods */
        @Override
        public void onActivityCreated(Activity activity, Bundle bundle) {
            mActivitiesBackStack.add(activity.getClass());
        }
    
        @Override
        public void onActivityStarted(Activity activity) {
    
        }
    
        @Override
        public void onActivityResumed(Activity activity) {
    
        }
    
        @Override
        public void onActivityPaused(Activity activity) {
    
        }
    
        @Override
        public void onActivityStopped(Activity activity) {
            if(!AppUtils.isAppOnForeground(this)){
                [Code when app in background...]
            }
        }
    
        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
    
        }
    
        @Override
        public void onActivityDestroyed(Activity activity) {
            if(mActivitiesBackStack.contains(activity.getClass())){
                mActivitiesBackStack.remove(activity.getClass());
            }
        }
        /* END Override ActivityLifecycleCallbacks Methods */
    
    [ Code of ur app class...]
    

    This is called every time the app goes in background and not when it get closed. If you put the "isAppOnForeground" inside the "onActivityDestroyed" it won't work with the code above for "isAppOnForeground" because it can't find the process (I think), maybe changing the code above or with another implementation it will work. The "onActivityDestroyed" will get called when the app is closed, so if you can check if the app is in background when it is called (so the app is already closed) you can grep exactly the moment when the app is being closed.

    Code of "isAppOnForeground" (I'm using it in a Utils static class):

    public static boolean isAppOnForeground(Context context) {
            boolean ret = false;
            ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
            if(appProcesses != null){
                String packageName = context.getPackageName();
                for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
                    if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
                        ret = true;
                    }
                }
            }
            return ret;
        }
    

    Hope this is helpful, see you bye and happy coding ! :D

    0 讨论(0)
  • 2020-12-03 13:44

    use one service which is start from Application class.

    public class AppService extends Service {
    
        @Override
        public void onTaskRemoved(Intent rootIntent) {
    
            super.onTaskRemoved(rootIntent);
            //here you will get call when app close.
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    }
    

    start this service from Application class.

    @Override
    public void onCreate() {
        super.onCreate();
        Intent intent = new Intent(getApplicationContext(), AppService.class);
        startService(intent);
    }
    
    0 讨论(0)
  • 2020-12-03 13:49
    public class MyBroadcastReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
            if (isAppForground(context)) {
                // App is in Foreground
            } else {
                // App is in Background
            }
        }
    
         private boolean isAppOnForeground(Context context,String appPackageName) {
            ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
            if (appProcesses == null) {
                 //App is closed
                return false;
            }
            final String packageName = appPackageName;
            for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
                if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
         //                Log.e("app",appPackageName);
                    return true;
                }else{
                    //App is closed
                }
            }
            return false;
        }
    
    }  
    

    Add this permission too

    <uses-permission android:name="android.permission.GET_TASKS" />
    

    try this hope it helps

    0 讨论(0)
提交回复
热议问题