判斷指定App是否位於前臺的方法
原文地址:http://p.codekk.com/detail/Android/wenmingvs/AndroidProcess
提供6種方法來判斷App處於前臺還是後臺,並且封裝成工具類供大家使用
最後一種方法堪稱android黑科技(非原創),既可以突破Android5.0以上的許可權封鎖,獲取任意前臺App的包名,又不需要許可權,歡迎大家star我的新專案
2016.2.11更新------感謝@EffectiveMatrix大神帶來的新的判斷前後臺的方法
六種判斷方法展示
用法
傳入Context引數與想要判斷是否位於前臺的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);
六種方法的區別
方法 | 判斷原理 | 需要許可權 | 可以判斷其他應用位於前臺 | 特點 |
---|---|---|---|---|
方法一 | RunningTask | 否 | Android4.0系列可以,5.0以上機器不行 | 5.0此方法被廢棄 |
方法二 | RunningProcess | 否 | 當App存在後臺常駐的Service時失效 | 無 |
方法三 | ActivityLifecycleCallbacks | 否 | 否 | 簡單有效,程式碼最少 |
方法四 | UsageStatsManager | 是 | 是 | 需要使用者手動授權 |
方法五 | 通過Android無障礙功能實現 | 否 | 是 | 需要使用者手動授權 |
方法六 | 讀取/proc目錄下的資訊 | 否 | 是 | 當proc目錄下資料夾過多時,過多的IO操作會引起耗時 |
方法一:通過RunningTask
原理
當一個App處於前臺的時候,會處於RunningTask的這個棧的棧頂,所以我們可以取出RunningTask的棧頂的任務程序,看他與我們的想要判斷的App的包名是否相同,來達到效果
缺點
getRunningTask方法在Android5.0以上已經被廢棄,只會返回自己和系統的一些不敏感的task,不再返回其他應用的task,用此方法來判斷自身App是否處於後臺,仍然是有效的,但是無法判斷其他應用是否位於前臺,因為不再能獲取資訊
方法二:通過RunningProcess
原理
通過runningProcess獲取到一個當前正在執行的程序的List,我們遍歷這個List中的每一個程序,判斷這個程序的一個importance 屬性是否是前臺程序,並且包名是否與我們判斷的APP的包名一樣,如果這兩個條件都符合,那麼這個App就處於前臺
缺點:
在聊天型別的App中,常常需要常駐後臺來不間斷的獲取伺服器的訊息,這就需要我們把Service設定成START_STICKY,kill 後會被重啟(等待5秒左右)來保證Service常駐後臺。如果Service設定了這個屬性,這個App的程序就會被判斷是前臺,程式碼上的表現就是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回調回來執行狀態即可。
可能還有人在糾結,我用back鍵切到後臺和用Home鍵切到後臺,一樣嗎?以上方法適用嗎?在Android應用開發中一般認為back鍵是可以捕獲的,而Home鍵是不能捕獲的(除非修改framework),但是上述方法從Activity生命週期著手解決問題,雖然這兩種方式的Activity生命週期並不相同,但是二者都會執行onStop();所以並不關心到底是觸發了哪個鍵切入後臺的。另外,Application是否被銷燬,都不會影響判斷的正確性
方法四:通過使用UsageStatsManager獲取
原理
通過使用UsageStatsManager獲取,此方法是Android5.0之後提供的新API,可以獲取一個時間段內的應用統計資訊,但是必須滿足一下要求
使用前提
- 此方法只在android5.0以上有效
- AndroidManifest中加入此許可權
<uses-permission xmlns:tools="http://schemas.android.com/tools" android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
- 開啟手機設定,點選安全-高階,在有權檢視使用情況的應用中,為這個App打上勾
方法五:通過Android自帶的無障礙功能
此方法無法直觀的通過下拉通知檢視來進行前後臺的觀察,請到LogCat中進行觀察即可,以下是LogCat中列印的資訊
原理
Android 輔助功能(AccessibilityService) 為我們提供了一系列的事件回撥,幫助我們指示一些使用者介面的狀態變化。 我們可以派生輔助功能類,進而對不同的 AccessibilityEvent 進行處理。 同樣的,這個服務就可以用來判斷當前的前臺應用
優勢
- AccessibilityService 有非常廣泛的 ROM 覆蓋,特別是非國產手機,從 Android API Level 8(Android 2.2) 到 Android Api Level 23(Android 6.0)
- AccessibilityService 不再需要輪詢的判斷當前的應用是不是在前臺,系統會在視窗狀態發生變化的時候主動回撥,耗時和資源消耗都極小
- 不需要許可權請求
- 它是一個穩定的方法,與 “方法6”讀取 /proc 目錄不同,它並非利用 Android 一些設計上的漏洞,可以長期使用的可能很大
- 可以用來判斷任意應用甚至 Activity, PopupWindow, Dialog 物件是否處於前臺
劣勢
- 需要要使用者開啟輔助功能
- 輔助功能會伴隨應用被“強行停止”而剝奪
方法六:讀取Linux系統核心儲存在/proc目錄下的process程序資訊
原理
無意中看到烏雲上有人提的一個漏洞,Linux系統核心會把process程序資訊儲存在/proc目錄下,Shell命令去獲取的他,再根據程序的屬性判斷是否為前臺
優點
- 不需要任何許可權
- 可以判斷任意一個應用是否在前臺,而不侷限在自身應用
缺點
- 當/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);
相關推薦
判斷指定App是否位於前臺的方法
原文地址:http://p.codekk.com/detail/Android/wenmingvs/AndroidProcess 提供6種方法來判斷App處於前臺還是後臺,並且封裝成工具類供大家使用 最後一種方法堪稱android黑科技(非原創),既可以突破Andro
PHP判斷指定時間段的2個方法
有時我們需要在一天中的某個時間段進行某項任務,或者在一天中的不同小時裡進行不同的任務,使用PHP如何實現呢,下面的兩個例子都可以解決這個問題 一、包含小時和分鐘的判斷date_default_timezone_set("Asia/Shanghai"); $time = intval (date(
只要兩行程式碼,就能判斷一個App是否在前臺執行
公司最近做專案有這樣的一個需求:當App在前臺執行的時候,不接受推送通知;當App在後臺執行的時候,接受推送通知。很顯然,這是一個非常常見的功能,我們在微信或者QQ就能體驗到這樣的功能。 首先分析一下,假如我們需要完成這樣的一個功能,谷歌官方有沒有給我們提供現成的介面供我
安卓判斷APP是在前臺還是在後臺
安卓中判斷APP是否在前臺: 方法一:CCApplication 中判斷 private boolean mIsInForeground = false; public boolean isInForeground() { return mIsInForeground; }
U3D獲取IOS裝置所在時區、是否安裝指定APP、判斷真機還是模擬器
unity是無法直接獲取ios裝置資訊的,但是unity可以與IOS程式碼進行互動,這就可以完成你想要實現的功能了。 直接上程式碼: CheckCountry.h檔案: #import <Foundation/Foundation.h> @interface CheckCountry
【C#】判斷字串中是否包含指定字串,contains與indexof方法效率問題
1 class Program 2 { 3 private const int N = 10000000; 4 private static Stopwatch watch = new Stopwatch(); 5 static v
判斷指定的程序或程式是否存在方法小結(vc等)
一、判斷指定程式名的程序是否存在 BOOL EnumWindows( WNDENUMPROC lpEnumFunc, // pointer to callback function LPARAM lParam // application-defined val
判斷當前 App 是否被切換到後臺的方法
有兩種方法: 1. 需要許可權 <uses-permission android:name="android.permission.GET_TASKS"/>, 普通App也可獲取,不需要確認,Android 5.1 之後已經廢棄,但是 compileSdkVe
判斷App整體處於前臺還是後臺
轉載請註明轉自:[noyet12的部落格](http://blog.csdn.net/u012975705) 部落格原址:http://blog.csdn.net/u012975705/article
mongodb 判斷座標是否在指定多邊形區域內的方法
MongoDB是一個基於分散式檔案儲存的資料庫,並提供建立基於地理空間的索引的能力,本文將使用MongoDB 基於地理空間索引進行座標所在區域的判斷及使用。 1.使用百度拾取座標工具,在地圖上定義多邊形的座標點,並把每個點的座標儲存。 多邊形的座標點如下
判斷app是否在前臺執行
public static boolean isAppRunningForeground(String pkgname, Context context) { boolean isAppRunning = false; ActivityManager am = (Acti
怎麽判斷一個APP是原生APP、混合APP還是WEB APP ?
大眾點評 支付寶 開發者 文章 螞蟻 1、看斷網情況 通過斷開網絡,刷新頁面,觀察內容緩存情況來有個大致的判斷,可以正常顯示的就是原生寫的,顯示404或者錯誤頁面的就是html頁面。2、看布局編輯3、看復制文章的提示,需要通過對比才能得出結果。 比如文章資訊頁面可以長按頁面試試,如
在JSP使用EL中判斷指定元素是否存在於指定集合中
element span cti ems 頁面 指定元素 jsp 指定 col 在JSP使用EL中判斷指定元素是否存在於指定集合中 1、問題描述 在JSP頁面中使用EL表達式判斷一個指定元素是否存在於指定集合中? 2、問題解決 eg:指定集合:collection:
js實現獲取兩個日期之間篩選出指定周日制的方法
js var start = "2017-5-25"; var end = "2017-6-5"; var startTime = new Date(start); var endTime = new Date(end) var timeArr = []; var weekDay = ["1","2
判斷你的應用在前臺還是在後臺
keyword 優化 rdm span sap ber callback handle tex 我的嘗試 /** * 判斷應用是否是在後臺 */ public static boolean isBackground(Context conte
第一篇、Android Supersu 權限管理定制,隱藏過濾權限,指定APP最高權限
權限 一律 例如 mod 系統 權限管理 過濾 tracking 屏蔽 近期有個需求,在預裝ROM的時候,須要權限,可是又不同意全部的應用都有權限,僅僅同意自己的應用有最高的權限(當然沒有系統簽名情況下)。 所以。編譯了CM 提取了supersu進行了二次定制,讓他進行
Java指定保留小數位數的方法
小數位數 mode down ceil package style spa 直接 obj package com.qiyuan.util; import java.math.BigDecimal; import java.math.RoundingMode; impor
ios-APP後臺切前臺token處理
obj erro highlight str post res json cat true /* APP從後臺轉前臺調用的方法 */ - (void)applicationDidBecomeActive:(UIApplication *)application {
判斷圖連通的三種方法——dfs,bfs,並查集
題目 pan closed 節點 out esp cli div find Description 如果無向圖G每對頂點v和w都有從v到w的路徑,那麽稱無向圖G是連通的。現在給定一張無向圖,判斷它是否是連通的。 Input 第一行有2個整數n和m(0 <
Set集合判斷對象重復的方法
set集合 rgs pwd 依次 code style nbsp string類 println Set<User> userSet = new HashSet<>(); User user1= new User("aa","11"