最近需要在项目中判断界面是否回到桌面,上网找了下资料,发现大部分都是如下做法:
/**
* 获得属于桌面的应用的应用包名称
*
* @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());
}
另外需要权限
<uses-permission android:name="android.permission.GET_TASKS" />
这种做法的原理就是:通过Intent的Category和PackageManager.MATCH_DERAULT_ONLY等参数来拿到所有属于桌面应用,再去拿到对应的包名。然后再通过ActivityManger的获取当前正在运行的第一个(栈顶)的task,判断其包名是否为桌面应用的包名。
缺点:
1、<uses-permission android:name="android.permission.GET_TASKS" />
这个权限从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权限使用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;
}