Android前后台状态判断及锁屏操作
Android前后台状态判断及锁屏操作

Directory

写在前面:最近做项目有一个锁屏的功能,需求是:当APP从后台切到前台时,需要打开锁屏页面(5分钟内不锁屏) APP前后台说明

前台:有一个或多个Activity可见  

后台:应用内所有Activity不可见

兼容性:Android4.0及以上 ActivityLifecycleCallbacks added in [API level 14]

参考 http://blog.csdn.net/goodlixueyong/article/details/50543627 在Activity的onStart和onStop方法中用变量count计数,在onStart中将变量加1,onStop中减1。 假设应用有两个Activity,分别为A和B。

情况1,首先启动A,A再启动B,然后关掉B:   启动A,count=1;   A启动B,先B.onStart 然后A.onStop,count先加1后减1,count为1。   关掉B,先A.onStart 然后B.onStop,count先加1后减1,count为1

情况2,首先启动A,然后按Home键返回桌面:   启动A,count=1,   按Home键返回桌面,会执行A.onStop,count的计数变位0。

以上,可以通过对count的值来判断应用从前后台状态。

这篇文章给了我思路,可以通过Activity计数来实现前后台状态的判断,其它方法都没有该方法简洁高效。 但是实践的时候发现只通过变量计数的方法,不能完美解决问题。

bug1:当应用第一次启动时,仍然会调用app从后台切到前台的方法。(我这里需要屏蔽掉这种情况)

仔细琢磨发现可以再加一个条件进行判断,增加一个最后一次可见的Activity变量(也可以增加一个后台超时时间),在执行onResume方法时进行判断最后一次可见Activity是否是当前可见的Activity,就可以解决以上问题

写在最后: 因为项目需要,我只实现了后台切换到前台的功能,聪明如你,实现后台切换到前台也炒鸡简单吧

github源码下载

关键代码:

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new AppForeBackStatusCallback());
    }
}
public class AppForeBackStatusCallback implements Application.ActivityLifecycleCallbacks {

    /**
     * 活动的Activity数量,为1时,APP处于前台状态,为0时,APP处于后台状态
     */
    private int activityCount = 0;

    /**
     * 最后一次可见的Activity
     * 用于比对Activity,这样可以排除启动应用时的这种特殊情况,
     * 如果启动应用时也需要锁屏等操作,请在启动页里进行操作。
     */
    private Activity lastVisibleActivity;

    /**
     * 最大无需解锁时长 5分钟 单位:毫秒
     */
    private final static long MAX_UNLOCK_DURATION = 5 * 60 * 1000;

    /**
     * 最后一次离开应用时间 单位:毫秒
     */
    private long lastTime;

    @Override

    public void onActivityCreated(Activity activity, Bundle bundle) {

    }

    @Override
    public void onActivityStarted(Activity activity) {
        activityCount++;
    }

    @Override
    public void onActivityResumed(Activity activity) {
        // 后台进程切换到前台进程,不包含启动应用时的这种特殊情况
        //最后一次可见Activity是被唤醒的Activity && 活动的Activity数量为1
        if (lastVisibleActivity == activity && activityCount == 1) {
            //Background -> Foreground , do something
            startLockScreen(activity);
        }

        lastVisibleActivity = activity;
    }

    /**
     * 打开手势密码
     *
     * @param activity Activity
     */
    private void startLockScreen(Activity activity) {
        if (lockScreen(activity)) {
            Intent intent = new Intent(activity, LockScreenActivity.class);
            activity.startActivity(intent);
        }
    }

    /**
     * 锁屏
     *
     * @param activity Activity
     * @return true 锁屏,反之不锁屏
     */
    private boolean lockScreen(Activity activity) {
        //解锁未超时,不锁屏
        if (!unlockTimeout())
            return false;
        // 当前Activity是锁屏Activity或登录Activity,不锁屏
        if (activity instanceof LockScreenActivity || activity instanceof LoginActivity)
            return false;
        //不满足其它条件,不锁屏,#备用#
        if (!otherCondition()) {
            return false;
        }
        //锁屏
        return true;
    }

    /**
     * 由后台切到前台时,解锁时间超时
     *
     * @return 时间间隔大于解锁时长为true,反之为false
     */
    private boolean unlockTimeout() {
        //当前时间和上次离开应用时间间隔
        long dTime = System.currentTimeMillis() - lastTime;
        return dTime > MAX_UNLOCK_DURATION;
    }

    /**
     * 其它条件
     *
     * @return boolean
     */
    private boolean otherCondition() {
        return true;
    }


    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivityStopped(Activity activity) {
        activityCount--;
        lastTime = System.currentTimeMillis();
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {

    }
}