Android проверяет, закрыто ли приложение

У меня есть приложение для Android, мне нужна одна функция или любой широковещательный приемник, который может проверить, закрыто ли приложение. Мне не нужно вызывать команду уничтожения в каждом действии (в приложении имеется около 20 действий). Я пытался добавить эту функцию в Класс приложения

public class ApplicationLifeCycleManager implements ActivityLifecycleCallbacks {

/** Manages the state of opened vs closed activities, should be 0 or 1.
 * It will be 2 if this value is checked between activity B onStart() and
 * activity A onStop().
 * It could be greater if the top activities are not fullscreen or have
 * transparent backgrounds.
 */
private static int visibleActivityCount = 0;

/** Manages the state of opened vs closed activities, should be 0 or 1
 * because only one can be in foreground at a time. It will be 2 if this
 * value is checked between activity B onResume() and activity A onPause().
 */
private static int foregroundActivityCount = 0;

/** Returns true if app has foreground */
public static boolean isAppInForeground(){
    return foregroundActivityCount > 0;
}

/** Returns true if any activity of app is visible (or device is sleep when
 * an activity was visible) */
public static boolean isAppVisible(){
    return visibleActivityCount > 0;
}

public void onActivityCreated(Activity activity, Bundle bundle) {
}

public void onActivityDestroyed(Activity activity) {
    Log.wtf("destroyed","app closed!!");
}

public void onActivityResumed(Activity activity) {
    foregroundActivityCount ++;

}

public void onActivityPaused(Activity activity) {
    foregroundActivityCount --;
}


public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}

public void onActivityStarted(Activity activity) {
    visibleActivityCount ++;
}

public void onActivityStopped(Activity activity) {
    visibleActivityCount --;
}

}

Также я зарегистрировался на создание в классе приложения

    @Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(new ApplicationLifeCycleManager());}

но функция on paused, onresume и ondestroyed вызывается, когда я переключаюсь между действиями: потому что она определяет, закрыта ли какая-либо деятельность, уничтожена или возобновлена

так какое решение проверить, закрыто ли приложение в одной функции??

3 ответа

Этот ответ использует ProcessLifecycleOwner для определения видимости приложения.

который является частью компонента архитектуры Android.


1. добавить эту библиотеку в ваш проект

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

2. Расширить класс приложения, который реализует LifecycleObserver

public class MyApplication extends Application implements LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onEnterForeground(){
        Log.d("LifecycleObserver ","Foreground");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onEnterBackground() {
        Log.d("LifecycleObserver ","Background");
    }


    @Override
    public void onCreate() {
        super.onCreate();

        // addObserver
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

}

не забудьте добавить его в свой манифест

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

Готово.


(Пример Котлина)

https://github.com/jshvarts/AppLifecycleDemo

Вы можете использовать эту функцию, чтобы определить, закрыто ли приложение (не в фоновом режиме и не на переднем плане).

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
}

Вы также можете проверить, находится ли приложение на переднем плане, используя эту функцию: /questions/45075224/proverit-android-prilozhenie-na-perednem-plane-ili-net/45075274#45075274

Используйте один сервис, который запускается из класса Application.

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;
    }
}

запустить этот сервис из класса приложения.

@Override
    public void onCreate() {
        super.onCreate();
        Intent intent = new Intent(getApplicationContext(), AppService.class);
        startService(intent);
    }

В основном, глядя на вашу проблему, вы хотите отслеживать изменения состояния в приложении.

Может быть довольно трудно сделать это правильно, заботясь обо всех случаях использования. Но есть удивительная библиотека, которая работает очень хорошо и очень проста в использовании - RxAppState.

Я использую эту библиотеку довольно давно, и она работает очень хорошо во всех случаях. Я настоятельно рекомендую вам попробовать это.

Как и ответ @SR, вы также можете использовать интерфейс "Application.ActivityLifecycleCallbacks" в пользовательском приложении, а затем в "onActivityStopped" использовать метод "isAppOnForeground(Context)".

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...]

Это вызывается каждый раз, когда приложение выходит в фоновом режиме, а не когда оно закрывается. Если вы поместите "isAppOnForeground" в "onActivityDestroyed", он не будет работать с приведенным выше кодом для "isAppOnForeground", потому что он не может найти процесс (я думаю), возможно, изменяя код выше или с другой реализацией, он будет работать, "OnActivityDestroyed" будет вызываться при закрытии приложения, поэтому, если вы можете проверить, находится ли приложение в фоновом режиме, когда оно вызывается (то есть приложение уже закрыто), вы можете точно определить момент, когда приложение закрывается.

Код "isAppOnForeground" (я использую его в статическом классе Utils):

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;
    }

Надеюсь, что это полезно, до свидания и счастливого кодирования!:D

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;
    }

}  

Добавить это разрешение тоже

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

попробуй эту надежду это поможет

Другие вопросы по тегам