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,就可以解决以上问题
写在最后: 因为项目需要,我只实现了后台切换到前台的功能,聪明如你,实现后台切换到前台也炒鸡简单吧
关键代码:
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) {
}
}