4

我有一个android应用程序我需要一个函数或任何可以检查应用程序是否关闭的广播接收器。我不需要在每个活动中调用destroy(应用程序中有大约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());
}

但是当我在活动之间切换时会调用 onPaused 和 onResumed 和 onDestroyed 函数:因为它检测是否有任何活动被关闭或销毁甚至恢复

所以有任何解决方案来检查应用程序是否在一个功能中关闭?

4

6 回答 6

13

这个答案使用ProcessLifecycleOwner来检测应用程序的可见性。

这是Android 架构组件的一部分。


1.将此库添加到您的项目中

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

2.扩展一个实现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);
    }

}

并像这样使用它:

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

不要忘记将应用程序添加name到您的manifest

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

完毕。


(科特林示例)

https://github.com/jshvarts/AppLifecycleDemo

于 2019-02-14T07:03:21.643 回答
5

您可以使用此功能来确定应用程序是否已关闭(不在后台或前台)。

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
}

您还可以使用此功能检查应用程序是否在前台: https ://stackoverflow.com/a/8490088/9005188

于 2018-01-19T12:53:05.217 回答
3

使用从应用程序类开始的一项服务。

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);
}
于 2019-02-14T13:22:55.027 回答
2

基本上看你的问题,你想跟踪应用程序中的状态变化。

要正确处理所有用例可能非常困难。但是有一个很棒的库,它运行得非常好并且超级容易使用——RxAppState 。

我已经使用这个库很长时间了,它在所有情况下都运行良好。我强烈建议你试试这个。

于 2017-03-03T10:46:37.047 回答
1

像@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

于 2019-02-22T08:37:33.113 回答
0
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" />

试试这个希望它有帮助

于 2017-03-03T10:54:08.333 回答