一. 原因
详解参考官方文档:Android 上的软件包可见性过滤 | Android Developers (google.cn)
简单来说就是,为了用户数据的隐私考虑,默认不允许当前应用访问到全部应用信息,而是访问系统过滤后的应用信息,这也就导致了我们无法只通过 packageManager.getInstalledApplications()方法、packageManager.getInstalledPackages()方法来获取设备的全部应用列表。
二. 解决方法
(一)若想在设备中查询是否包含特定的应用:
1.在manifest中直接声明需访问到的应用,格式如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<queries>
<!-- 想查询访问的应用包名 如:淘宝 -->
<package android:name="com.taobao.taobao" />
</queries>
...
...
</manifest>
声明后,本应用则会和声明要访问的这个应用彼此可见,因而之后可访问得到。
2.获取应用信息
PackageManager packageManager = getPackageManager();
//获取过滤后的已安装应用信息,若在清单中声明的应用存在,则系统不会将其过滤掉
List<PackageInfo> installedPackages = packageManager.getInstalledPackages(0);
//创建一个集合用于存储已安装APP的包名
List<String> installedAppNames = new ArrayList<>();
//遍历获取已安装的应用包名
for (int i = 0; i < installedPackages.size(); i++) {
installedAppNames.add(installedPackages.get(i).packageName);
LogUtils.d(this,"AppName-->" + installedAppNames.get(i));
}
//判断是否包含我们所需的应用包名
mHasTaoBaoApp = installedAppNames.contains("com.taobao.taobao");
或
PackageManager packageManager = getPackageManager();
try {
PackageInfo packageInfo = packageManager.getPackageInfo("com.taobao.taobao", PackageManager.MATCH_UNINSTALLED_PACKAGES);
if (packageInfo != null) {
mHasTaoBaoApp = true;//有淘宝
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
mHasTaoBaoApp = false;//没有淘宝
}