最近需要在項目中判斷界面是否回到桌面,上網(wǎng)找了下資料,發(fā)現(xiàn)大部分都是如下做法:
/**
* 獲得屬于桌面的應用的應用包名稱
*
* @return 返回包含所有包名的字符串列表
*/
public static List<String> getHomes(Context context) {
List<String> names = new ArrayList<String>();
PackageManager packageManager = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resolveInfos) {
names.add(resolveInfo.activityInfo.packageName);
}
return names;
}
/**
* 判斷當前界面是否是桌面
*/
public static boolean isHome(Context context) {
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);
return getHomes(context).contains(rti.get(0).topActivity.getPackageName());
}
另外需要權(quán)限
<uses-permission android:name="android.permission.GET_TASKS" />
這種做法的原理就是:通過Intent的Category和PackageManager.MATCH_DERAULT_ONLY等參數(shù)來拿到所有屬于桌面應用,再去拿到對應的包名。然后再通過ActivityManger的獲取當前正在運行的第一個(棧頂)的task,判斷其包名是否為桌面應用的包名。
缺點:
1、<uses-permission android:name="android.permission.GET_TASKS" />
這個權(quán)限從Android5.0開始就被棄用了,除了安全方面的考慮,所以在項目中即使申請了也是沒有用的。
2、例如當前是在應用A里面使用這個方式去判斷(即傳入的Context是屬于應用A的),當界面在應用A和桌面時,是可以正確判斷出來的,但是如果此時打開另一個不屬于我們的應用B,獲取到的TopActivity的包名還是應用A。所以這樣就會造成誤判。
改進的判斷方式(通過adb命令)
在這里,我們可以通過adb命令來獲取當前的屏幕焦點,然后通過判斷其是否是桌面應用,這樣就可以判斷出是否在桌面了。親測Android4.4和Android6.0可用
/**
* 通過adb判斷當前是否是桌面
* @param context
* @return
*/
public static boolean isHomeByAdb(Context context){
try {
// 獲取當前屏幕的焦點 mCurrentFocus=Window{55910ce u0 com.miui.home/com.miui.home.launcher.Launcher}
// 沒有root權(quán)限使用adb shell
// List<String> list = ShellUtil.getShellOut2(ShellUtil.shell("dumpsys window | grep mCurrentFocus"));
String res = ShellUtil.performSuCommandAndGetRes("dumpsys window | grep mCurrentFocus");
if (res!=null){
List<String> names = getHomes(context);
for (String name:names){
if(res.contains(name)){
return true;
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
Log.i(TAG, "isHomeByAdb: error -- ",e);
}
return false;
}