导读:
开发过程中,需要知道某个APP的版本号,在安卓模拟器(android7版本)中可以正常获取到版本号,但真机(android11版本)测试时却无法获取,经过查资料才知道是因为Android11的包可见性导致的。
在Android11中,除了默认的一些应用外,我们不能直接获取到软件包是否已经安装了,换句话说我们安装了一个应用,但是我们调用 getInstalledApplications() 或 getInstalledPackages()方法时可能没有返回对应的包名,这就是Android11引入的包可见性的概念。
Android11这么做的意义:
鼓励最小权限原则,需要与哪些应用交互,就申请哪些包名;
帮助 Google Play 等应用商店评估应用的隐私性和安全性;
获取版本号的方法:
/**
* 获取应用版本号
* @param context
* @param packageName
* @return
*/
public static String getAPPVersion(Context context,String packageName) {
PackageManager manager = context.getPackageManager();
String versionName = "";
try {
//packageName表示类的包名,0表示获取版本信息
PackageInfo info = manager.getPackageInfo(packageName, 0);
versionName = info.versionName;
if (TextUtils.isEmpty(versionName) || versionName.length()<=0){
return "";
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return versionName;
}
对于Android11来说,如何让包可见呢?
1、升级Android的Gradle到3.6.0或更高版本,在Android Studio里配置:
"com.android.tools.build:gradle:3.6.0"
2、确保应用的 targetSdkVersion
设为 30以上
3、在AndroidManifest.xml清单文件
中,使用<queries>声明我们的应用期望与那些应用交互
<!--使用queries声明我们的应用期望与那些应用交互-->
<queries>
<package android:name="com.eg.android.AlipayGphone" />
<package android:name="com.tencent.mm" />
<package android:name="com.tencent.mobileqq" />
</queries>
其他问题
问题1:PackageManager.queryIntentActivities()接口在Android11是否可用?
Android11中,可以使用此接口。为了功能正常,我们还是需要在manefist中声明<queries>,格式如下:
<queries>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="image/jpeg" />
</intent>
</queries>
问题2::Android11如何获取设备中的所有的应用?比如我的应用是杀毒软件,需要扫描所有软件。
系统提供了查询所有的应用的权限,只需做如下声明:
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />