1. 程式人生 > >判斷應用是否處於前臺的六種方法優缺點?

判斷應用是否處於前臺的六種方法優缺點?

前段時間需要做一個功能,就是判斷手機中本APP是否處於前臺,如果處於前臺就執行一個操作.參考了網上其他大神寫的一些方法,發現一些漏洞和bug,表達一下自己觀點.

方法1:RunningTask判斷

話不多說直接上程式碼

public static boolean getRunningTask(Context context, String packageName) {
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
    return !TextUtils.isEmpty(packageName) && packageName.equals(cn.getPackageName());
}

此方法說的是5.0以後失效但是可以判斷自己應用,5.0之前通用,用過測試過發現,這個方法是檢測棧頂的存在Activity,(別如說我開啟應用了,這個是微信來了一條訊息,開啟微信,這時此方法判斷結果為在前臺存活,
可是我想要結果是在後臺)。

結論:分特定情況,不準確.

方法2:RunningProcess判斷

/**
 * 方法2:通過getRunningAppProcesses的IMPORTANCE_FOREGROUND屬性判斷是否位於前臺,當service需要常駐後臺時候,此方法失效,
 * 在小米 Note上此方法無效,在Nexus上正常
 *
 * @param context     上下文引數
 * @param packageName 需要檢查是否位於棧頂的App的包名
 * @return
 */
public static boolean getRunningAppProcesses(Context context, String packageName) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
    if (appProcesses == null) {
        return false;
    }
    for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
        if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
            return true;
        }
    }
    return false;
}

結論:比如存在服務是不準。

方法3:ActivityLifecycleCallbacks監聽實現

/**存活Activity數量(寫在你的Util就行)**/
public static boolean getApplicationValue(MyApplication myApplication) {
    return myApplication.getAppCount() > 0;
}

寫在Application之中,別忘記清單檔案註冊。

private int appCount = 0;
ActivityLifecycleCallbacks activityLifecycleCallbacks=new ActivityLifecycleCallbacks() {
    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    }

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

    @Override
    public void onActivityResumed(Activity activity) {
    }

    @Override
    public void onActivityPaused(Activity activity) {
    }

    @Override
    public void onActivityStopped(Activity activity) {
        appCount--;
    }

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

    }

    @Override
    public void onActivityDestroyed(Activity activity) {

    }
}
@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(activityLifecycleCallbacks);

}

public int getAppCount() {
    return appCount;
}

@Override
public void onTerminate() {
    super.onTerminate();
    unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks);
}

- AndroidSDK14在Application類裡增加了ActivityLifecycleCallbacks
- 結論:程式碼最少,沒有測出任何問題

方法4:UsageStatsManager監聽實現

結論:需要授權,不適用,我也沒測,直接棄用

方法5:通過Android無障礙功能實現

結論:需要授權,不適用,我也沒測,直接棄用

方法6:讀取Linux系統核心儲存在/proc目錄下的process程序資訊

  • Android 輔助功能(AccessibilityService) 為我們提供了一系列的事件回撥,幫助我們指示一些使用者介面的狀態變化。 我們可以派生輔助功能類,進而對不同的 AccessibilityEvent 進行處理。 同樣的,這個服務就可以用來判斷當前的前臺應用

存在bug:後臺常駐失效,比如我開了一個服務在下載檔案,這是我按返回鍵退出應用程式,沒有殺死,利用此方法判斷出來App仍在前臺,(只要後臺存在判斷出來都不準確)