当前位置:   article > 正文

Android 获取应用列表

android 获取应用列表

前言

目前正是Android 11 马上要发布的时期,当前在Android手机上获取应用安装列表,要从三个维度上区分:获取方法、系统版本、是否系统应用。

  • 获取方法:至少有两种方法,它们的行为结果会有所差异
  • 系统版本:从 Android 11 开始,应用列表的获取将受到限制
  • 是否系统应用:系统应用与非系统应用的获取结果,也不尽相同

获取方法介绍

获取所有应用列表(系统应用+非系统应用),常用的方法有2种:Shell命令行、系统API。

而要进一步区分是否系统应用,只要对上述结果进行一次过滤即可。下面分别介绍:

1.shell命令行

pm list packages
  • 1

示例代码:

private List<String> getPkgList() {
	List<String> packages = new ArrayList<String>();
	try {
		Process p = Runtime.getRuntime().exec("pm list packages");
		InputStreamReader isr = new InputStreamReader(p.getInputStream(), "utf-8");
		BufferedReader br = new BufferedReader(isr);
		String line = br.readLine();
		while (line != null) {
			line = line.trim();
			if (line.length() > 8) {
				String prefix = line.substring(0, 8);
				if (prefix.equalsIgnoreCase("package:")) {
					line = line.substring(8).trim();
					if (!TextUtils.isEmpty(line)) {
						packages.add(line);
					}
				}
			}
			line = br.readLine();
		}
		br.close();
		p.destroy();
	} catch (Throwable t) {
		t.printStacktraces();
	}
	return packages;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

2.系统API

PackageManager.getInstalledPackages()
  • 1

示例代码:

private List<String> getPkgListNew() {
	List<String> packages = new ArrayList<String>();
	try {
		List<PackageInfo> packageInfos = context.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES |
				PackageManager.GET_SERVICES);
		for (PackageInfo info : packageInfos) {
			String pkg = info.packageName;
			packages.add(pkg);
		}
	} catch (Throwable t) {
		t.printStackTrace();;
	}
	return packages;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

判断是否系统应用

// 通过packName得到PackageInfo,作为参数传入即可
private boolean isSystemApp(PackageInfo pi) {
	boolean isSysApp = (pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1;
	boolean isSysUpd = (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1;
	return isSysApp || isSysUpd;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

总结对比

  • 测试机:Google Pixel 3 XL
  • 系统应用:262个
  • 非系统应用:2个(包括测试demo)
获取方法系统应用非系统应用
< Android 11>= Android 11< Android 11>= Android 11
shell命令- 可用- 不需要权限- 条件可用- 无权限:结果变少(99个)- 有权限:得到所有应用(262个)- 可用- 不需要权限- 条件可用- 无权限:只能得到自己(1个)- 有权限:得到所有应用(2个)
系统API- 可用- 不需要权限- 条件可用- 无权限:结果变少(99个)- 有权限:得到所有应用(262个)- 可用- 不需要权限- 条件可用- 无权限:只能得到自己(1个)- 有权限:得到所有应用(2个)

说明:

  • 这里说的权限是:QUERY_ALL_PACKAGES,Android 11 新增权限,不用动态申请
  • 这里说的 >= Android 11 是:targetSdkVersion 为 Android 11 且 运行在11的设备上

补充:广播监听应用安装/卸载的行为变化

如果使用了广播,监听应用安装与卸载动作,那么在 Android 11 上也有一些行为变化。

概括来讲,就是 Android 11 下,若无 QUERY_ALL_PACKAGES 权限,则无法监听到 安装 动作

Android 11 之前
  • 能监听到 安装/卸载
Android 11 开始
  • 若无 QUERY_ALL_PACKAGES 权限:只能监听到 卸载
  • 若有 QUERY_ALL_PACKAGES 权限:仍能监听到 安装/卸载
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/265495
推荐阅读
相关标签
  

闽ICP备14008679号