Android监控当前app前后台方法

注意,测试场景应该包含back键退出、home键退出、锁屏、亮屏、通知栏跳入其他app、通知栏进入当前app等情况。

ActivityLifecycleCallbacks

该接口提供了一系列回调方法,用于让开发者对Activity的生命周期事件进行集中处理。在该方法出现前,我们往往需要将所有Activity都继承自统一的BaseActivity,再进行onStart/onStop等的监听计数等来实现同样的目的。

    public interface ActivityLifecycleCallbacks {
        void onActivityCreated(Activity activity, Bundle savedInstanceState);
        void onActivityStarted(Activity activity);
        void onActivityResumed(Activity activity);
        void onActivityPaused(Activity activity);
        void onActivityStopped(Activity activity);
        void onActivitySaveInstanceState(Activity activity, Bundle outState);
        void onActivityDestroyed(Activity activity);
    }

ActivityLifecycleCallbacks使用要求API 14+ (Android 4.0+)。初始化的时候需要注册 application.registerActivityLifecycleCallbacks(this);

可以分别在onActivityStarted和onActivityStoped两个方法中进行++、--的计数,来判断当前应用在前台还是后台。

为什么要在onStop中检测,而不是onPause?这是由于A启动B时,生命周期的执行顺序如下:A.onPause->B.onCreate->B.onStart->B.onResume->A.onStop,也就是说,在A的onPause方法中,B的生命周期还没有执行,进程没有进入前台,当然是检测不到的。

其他方案可参考 http://www.jianshu.com/p/e7f64e6bc2cc

RunningTaskInfo

ActivityManager.getRunningTasks方法返回当前运行的task列表,使用该接口需要 android.permission.GET_TASKS权限。最近使用的task排在第一位,按使用顺序依次排序。该方法的本意是调试和展示ui的任务蛮力,不应该用于应用的核心逻辑,例如根据获取的信息来展现不同的行为。谷歌官方处于安全的考虑,该方法在5.0(Build.VERSION_CODES_LOLLIPOP)及以后deprecated,第三方应用不能再访问。注释如下

 * @deprecated As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method
     * is no longer available to third party
     * applications: the introduction of document-centric recents means
     * it can leak person information to the caller.  For backwards compatibility,
     * it will still retu rn a small subset of its data: at least the caller's
     * own tasks, and possibly some other tasks
     * such as home that are known to not be sensitive.

在小米手机MIUI8系统运行,可看出该函数只能返回一个home的task。


Android监控当前app前后台方法_第1张图片
image.png

在5.0以下获取当前top应用的代码如下:

/**
  *判断当前应用程序处于前台还是后台
  */
public static boolean isApplicationBroughtToBackground(final Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List tasks = am.getRunningTasks(1);
        if (!tasks.isEmpty()) {
            ComponentName topActivity = tasks.get(0).topActivity;
            if (!topActivity.getPackageName().equals(context.getPackageName())) {
                return true;
            }
        }
        return false;
}

getRunningAppProcesses

5.0之后可以通过ActivityManager的getRunningAppProcesses()方法获取正在运行的应用程序。

public static boolean isBackground(Context context) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List appProcesses = activityManager.getRunningAppProcesses();
    for (RunningAppProcessInfo appProcess : appProcesses) {
         if (appProcess.processName.equals(context.getPackageName())) {
                if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
                          Log.i("后台", appProcess.processName);
                          return true;
                }else{
                          Log.i("前台", appProcess.processName);
                          return false;
                }
           }
    }
    return false;
}

实际测试中,该方法对大部分的场景可行,但是部分场景不可行。如通知栏点击进入其他应用,需要进行兼容性测试。

参考:
http://blog.csdn.net/zhuangyalei/article/details/50554862
http://blog.csdn.net/goodlixueyong/article/details/50543627

你可能感兴趣的:(Android监控当前app前后台方法)