判斷App位于前臺或者后臺的6種方法

作者: wenmingvs
Github: https://github.com/wenmingvs/AndroidProcess

用法

傳入Context參數(shù)與想要判斷是否位于前臺的App的包名,會返回ture或者false表示App是否位于前臺


//六種方法任選其一

//使用方法一
Boolean isForeground = BackgroundUtil.getRunningTask(context, packageName);
//使用方法二
Boolean isForeground = BackgroundUtil.getRunningAppProcesses(context, packageName);
//使用方法三
Boolean isForeground = BackgroundUtil.getApplicationValue(context);
//使用方法四
Boolean isForeground = BackgroundUtil.queryUsageStats(context, packageName);
//使用方法五
Boolean isForeground = BackgroundUtil.getFromAccessibilityService(context, packageName);
//使用方法六
Boolean isForeground = BackgroundUtil.getLinuxCoreInfo(context, packageName);

六種方法的區(qū)別

方法 判斷原理 需要權限 可以判斷其他應用位于前臺 特點
方法一 RunningTask Android4.0系列可以,5.0以上機器不行 5.0此方法被廢棄
方法二 RunningProcess 當App存在后臺常駐的Service時失效
方法三 ActivityLifecycleCallbacks 簡單有效,代碼最少
方法四 UsageStatsManager 需要用戶手動授權
方法五 通過Android無障礙功能實現(xiàn) 需要用戶手動授權
方法六 讀取/proc目錄下的信息 當proc目錄下文件夾過多時,過多的IO操作會引起耗時

方法一:通過RunningTask

原理

當一個App處于前臺的時候已艰,會處于RunningTask的這個棧的棧頂祟滴,所以我們可以取出RunningTask的棧頂?shù)娜蝿者M程刊懈,看他與我們的想要判斷的App的包名是否相同手幢,來達到效果

缺點

getRunningTask方法在Android5.0以上已經被廢棄捷凄,只會返回自己和系統(tǒng)的一些不敏感的task,不再返回其他應用的task围来,用此方法來判斷自身App是否處于后臺跺涤,仍然是有效的,但是無法判斷其他應用是否位于前臺监透,因為不再能獲取信息

方法二:通過RunningProcess

原理

通過runningProcess獲取到一個當前正在運行的進程的List桶错,我們遍歷這個List中的每一個進程,判斷這個進程的一個importance 屬性是否是前臺進程胀蛮,并且包名是否與我們判斷的APP的包名一樣院刁,如果這兩個條件都符合,那么這個App就處于前臺

缺點

在聊天類型的App中醇滥,常常需要常駐后臺來不間斷的獲取服務器的消息黎比,這就需要我們把Service設置成START_STICKY,kill 后會被重啟(等待5秒左右)來保證Service常駐后臺鸳玩。如果Service設置了這個屬性阅虫,這個App的進程就會被判斷是前臺,代碼上的表現(xiàn)就是appProcess.importance的值永遠是 ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND不跟,這樣就永遠無法判斷出到底哪個是前臺了颓帝。

方法三:通過ActivityLifecycleCallbacks

原理
AndroidSDK14在Application類里增加了ActivityLifecycleCallbacks,我們可以通過這個Callback拿到App所有Activity的生命周期回調。

 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);
    }

知道這些信息购城,我們就可以用更官方的辦法來解決問題吕座,當然還是利用方案二里的Activity生命周期的特性,我們只需要在Application的onCreate()里去注冊上述接口瘪板,然后由Activity回調回來運行狀態(tài)即可吴趴。

可能還有人在糾結,我用back鍵切到后臺和用Home鍵切到后臺侮攀,一樣嗎锣枝?以上方法適用嗎?在Android應用開發(fā)中一般認為back鍵是可以捕獲的兰英,而Home鍵是不能捕獲的(除非修改framework),但是上述方法從Activity生命周期著手解決問題撇叁,雖然這兩種方式的Activity生命周期并不相同,但是二者都會執(zhí)行onStop()畦贸;所以并不關心到底是觸發(fā)了哪個鍵切入后臺的陨闹。另外,Application是否被銷毀,都不會影響判斷的正確性

方法四:通過使用UsageStatsManager獲取

原理

通過使用UsageStatsManager獲取,此方法是Android5.0之后提供的新API薄坏,可以獲取一個時間段內的應用統(tǒng)計信息趋厉,但是必須滿足一下要求

使用前提
1.此方法只在android5.0以上有效
2.AndroidManifest中加入此權限

<uses-permission xmlns:tools="http://schemas.android.com/tools"    
 android:name="android.permission.PACKAGE_USAGE_STATS"   
  tools:ignore="ProtectedPermissions" />

3.打開手機設置,點擊安全-高級颤殴,在有權查看使用情況的應用中觅廓,為這個App打上勾

enter image description here
enter image description here

方法五:通過Android自帶的無障礙功能

非常感謝@EffectiveMatrix大神帶來的新的判斷前后臺的方法

此方法屬于他原創(chuàng),具體的博文參照這里http://effmx.com/articles/tong-guo-android-fu-zhu-gong-neng-accessibility-service-jian-ce-ren-yi-qian-tai-jie-mian/

此方法無法直觀的通過下拉通知視圖來進行前后臺的觀察涵但,請到LogCat中進行觀察即可,以下是LogCat中打印的信息

enter image description here

原理

Android 輔助功能(AccessibilityService) 為我們提供了一系列的事件回調帖蔓,幫助我們指示一些用戶界面的狀態(tài)變化矮瘟。 我們可以派生輔助功能類,進而對不同的 AccessibilityEvent 進行處理塑娇。 同樣的澈侠,這個服務就可以用來判斷當前的前臺應用

優(yōu)勢

  1. AccessibilityService 有非常廣泛的 ROM 覆蓋,特別是非國產手機埋酬,從 Android API Level 8(Android 2.2) 到 Android Api Level 23(Android 6.0)
  1. AccessibilityService 不再需要輪詢的判斷當前的應用是不是在前臺哨啃,系統(tǒng)會在窗口狀態(tài)發(fā)生變化的時候主動回調,耗時和資源消耗都極小
  2. 不需要權限請求
  3. 它是一個穩(wěn)定的方法写妥,與 “方法6”讀取 /proc 目錄不同屹堰,它并非利用 Android 一些設計上的漏洞司澎,可以長期使用的可能很大
  4. 可以用來判斷任意應用甚至 Activity, PopupWindow, Dialog 對象是否處于前臺

劣勢

  1. 需要要用戶開啟輔助功能
  1. 輔助功能會伴隨應用被“強行停止”而剝奪

方法六:讀取Linux系統(tǒng)內核保存在/proc目錄下的process進程信息

此方法并非我原創(chuàng),原作者是國外的大神,GitHub項目在這里董习,也一并加入到工程中航缀,供大家做全面的參考選擇

原理

無意中看到烏云上有人提的一個漏洞,Linux系統(tǒng)內核會把process進程信息保存在/proc目錄下,Shell命令去獲取的他酬姆,再根據(jù)進程的屬性判斷是否為前臺

優(yōu)點

  1. 不需要任何權限
  1. 可以判斷任意一個應用是否在前臺,而不局限在自身應用

缺點

  1. 當/proc下文件夾過多時,此方法是耗時操作

用法
獲取一系列正在運行的App的進程

List<AndroidAppProcess> processes = ProcessManager.getRunningAppProcesses();

獲取任一正在運行的App進程的詳細信息

AndroidAppProcess process = processes.get(location);
String processName = process.name;

Stat stat = process.stat();
int pid = stat.getPid();
int parentProcessId = stat.ppid();
long startTime = stat.stime();
int policy = stat.policy();
char state = stat.state();

Statm statm = process.statm();
long totalSizeOfProcess = statm.getSize();
long residentSetSize = statm.getResidentSetSize();

PackageInfo packageInfo = process.getPackageInfo(context, 0);
String appName = packageInfo.applicationInfo.loadLabel(pm).toString();

判斷是否在前臺

if (ProcessManager.isMyProcessInTheForeground()) {
  // do stuff
}

獲取一系列正在運行的App進程的詳細信息

List<ActivityManager.RunningAppProcessInfo> processes = ProcessManager.getRunningAppProcessInfo(ctx);

更多文章請關注公眾號

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末奥溺,一起剝皮案震驚了整個濱河市辞色,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浮定,老刑警劉巖相满,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異壶唤,居然都是意外死亡雳灵,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門闸盔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悯辙,“玉大人,你說我怎么就攤上這事迎吵《阕” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵击费,是天一觀的道長拢蛋。 經常有香客問我,道長蔫巩,這世上最難降的妖魔是什么谆棱? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮圆仔,結果婚禮上垃瞧,老公的妹妹穿的比我還像新娘。我一直安慰自己坪郭,他們只是感情好个从,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著歪沃,像睡著了一般嗦锐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沪曙,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天奕污,我揣著相機與錄音,去河邊找鬼珊蟀。 笑死菊值,一個胖子當著我的面吹牛外驱,可吹牛的內容都是我干的。 我是一名探鬼主播腻窒,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼昵宇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了儿子?” 一聲冷哼從身側響起瓦哎,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柔逼,沒想到半個月后蒋譬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡愉适,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年犯助,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片维咸。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡剂买,死狀恐怖,靈堂內的尸體忽然破棺而出癌蓖,到底是詐尸還是另有隱情瞬哼,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布租副,位于F島的核電站坐慰,受9級特大地震影響,放射性物質發(fā)生泄漏用僧。R本人自食惡果不足惜结胀,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望责循。 院中可真熱鬧把跨,春花似錦、人聲如沸沼死。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽意蛀。三九已至,卻和暖如春健芭,著一層夾襖步出監(jiān)牢的瞬間县钥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工慈迈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留若贮,地道東北人省有。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像谴麦,于是被迫代替她去往敵國和親蠢沿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內容