一. 原因
详解参考官方文档: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;//没有淘宝 }