寫在前面:
最近做項(xiàng)目有一個鎖屏的功能,需求是:當(dāng)APP從后臺切到前臺時,需要打開鎖屏頁面(5分鐘內(nèi)不鎖屏)
APP前后臺說明
前臺:有一個或多個Activity可見
后臺:應(yīng)用內(nèi)所有Activity不可見
兼容性:Android4.0及以上 ActivityLifecycleCallbacks added in [API level 14]
參考 http://blog.csdn.net/goodlixueyong/article/details/50543627
在Activity的onStart和onStop方法中用變量count計(jì)數(shù),在onStart中將變量加1,onStop中減1。
假設(shè)應(yīng)用有兩個Activity,分別為A和B。
情況1,首先啟動A,A再啟動B,然后關(guān)掉B:
啟動A,count=1;
A啟動B,先B.onStart 然后A.onStop,count先加1后減1,count為1。
關(guān)掉B,先A.onStart 然后B.onStop,count先加1后減1,count為1
情況2,首先啟動A,然后按Home鍵返回桌面:
啟動A,count=1,
按Home鍵返回桌面,會執(zhí)行A.onStop,count的計(jì)數(shù)變位0。
以上,可以通過對count的值來判斷應(yīng)用從前后臺狀態(tài)。
這篇文章給了我思路,可以通過Activity計(jì)數(shù)來實(shí)現(xiàn)前后臺狀態(tài)的判斷,其它方法都沒有該方法簡潔高效。
但是實(shí)踐的時候發(fā)現(xiàn)只通過變量計(jì)數(shù)的方法,不能完美解決問題。
bug1:當(dāng)應(yīng)用第一次啟動時,仍然會調(diào)用app從后臺切到前臺的方法。(我這里需要屏蔽掉這種情況)
仔細(xì)琢磨發(fā)現(xiàn)可以再加一個條件進(jìn)行判斷,增加一個最后一次可見的Activity變量(也可以增加一個后臺超時時間),在執(zhí)行onResume方法時進(jìn)行判斷最后一次可見Activity是否是當(dāng)前可見的Activity,就可以解決以上問題
寫在最后:
因?yàn)轫?xiàng)目需要,我只實(shí)現(xiàn)了后臺切換到前臺的功能,聰明如你,實(shí)現(xiàn)后臺切換到前臺也炒雞簡單吧
關(guān)鍵代碼:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new AppForeBackStatusCallback());
}
}
public class AppForeBackStatusCallback implements Application.ActivityLifecycleCallbacks {
/**
* 活動的Activity數(shù)量,為1時,APP處于前臺狀態(tài),為0時,APP處于后臺狀態(tài)
*/
private int activityCount = 0;
/**
* 最后一次可見的Activity
* 用于比對Activity,這樣可以排除啟動應(yīng)用時的這種特殊情況,
* 如果啟動應(yīng)用時也需要鎖屏等操作,請?jiān)趩禹摾镞M(jìn)行操作。
*/
private Activity lastVisibleActivity;
/**
* 最大無需解鎖時長 5分鐘 單位:毫秒
*/
private final static long MAX_UNLOCK_DURATION = 5 * 60 * 1000;
/**
* 最后一次離開應(yīng)用時間 單位:毫秒
*/
private long lastTime;
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
activityCount++;
}
@Override
public void onActivityResumed(Activity activity) {
// 后臺進(jìn)程切換到前臺進(jìn)程,不包含啟動應(yīng)用時的這種特殊情況
//最后一次可見Activity是被喚醒的Activity && 活動的Activity數(shù)量為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;
// 當(dāng)前Activity是鎖屏Activity或登錄Activity,不鎖屏
if (activity instanceof LockScreenActivity || activity instanceof LoginActivity)
return false;
//不滿足其它條件,不鎖屏,#備用#
if (!otherCondition()) {
return false;
}
//鎖屏
return true;
}
/**
* 由后臺切到前臺時,解鎖時間超時
*
* @return 時間間隔大于解鎖時長為true,反之為false
*/
private boolean unlockTimeout() {
//當(dāng)前時間和上次離開應(yīng)用時間間隔
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) {
}
}