应用列表未在 Android 11 上使用包管理器填充



我正在使用包管理器为我的启动器中的应用抽屉接口获取应用程序列表。一切正常,但在安卓11上,唯一显示的应用程序是安卓设置应用程序。是什么改变了它,使它不再工作,和/或我应该怎么做才能使它工作?应用程序列表现在基于用户配置文件吗?

这是我当前的列表代码

public static List<ApplicationInfo> getPrimaryApps(Context context) {    
PackageManager pm = context.getPackageManager();    
List<ApplicationInfo> res = new ArrayList<>();    
ArrayList<String> hiddenPackages = new ArrayList<>();    
IconPackHelper iconPackHelper = IconPackHelper.getInstance(context);
//All Apps Package Filter    
Set<String> filteredPackages = new HashSet<>();
filteredPackages.add("com.android.wallpaper.livepicker");    
filteredPackages.add("com.gocalsd.symphlyx");
//All Apps Blacklist    
String[] flattenedPackages = SettingsProvider.get(context).getString(SettingsProvider.HIDDEN_APPS, "").split("\|");
for (String flat : flattenedPackages) {    
ComponentName cmp = ComponentName.unflattenFromString(flat);    
if (cmp != null) {
hiddenPackages.add(cmp.getPackageName());
}    
}
Intent intent = new Intent(Intent.ACTION_MAIN, null);    
intent.addCategory(Intent.CATEGORY_LAUNCHER);   
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
List<ResolveInfo> resolveInfoList = pm.queryIntentActivities(intent, 0);
//Sort all apps    
Collections.sort(resolveInfoList, new ResolveInfo.DisplayNameComparator(pm));
for (ResolveInfo resolveInfo : resolveInfoList) {    
ActivityInfo activityInfo = resolveInfo.activityInfo;
int iconId = IconPackHelper.getInstance(context).getResourceIdForActivityIcon(activityInfo);
if (!filteredPackages.contains(resolveInfo.activityInfo.packageName)) {    
if (!hiddenPackages.contains(resolveInfo.activityInfo.packageName)) {    
String appName = activityInfo.applicationInfo.loadLabel(pm).toString();     
String packageName = activityInfo.packageName;    
Drawable icon = null;  
int extractedIconColor = 0;
//toggle themed icon    
if (iconPackHelper.isIconPackLoaded() && iconPackHelper.getThemedIcon(context, packageName)) {    
if (iconId != 0) {    
icon = IconPackHelper.getInstance(context).getIconPackResources().getDrawable(iconId); 
Bitmap iconBm = ImageUtils.drawableToBitmap(icon);    
extractedIconColor = ColorProvider.getDominantColor(iconBm);    
}    
}
if (icon == null || !IconPackHelper.getInstance(context).isIconPackLoaded()) {  
icon = activityInfo.applicationInfo.loadIcon(pm);
Bitmap iconBm = ImageUtils.drawableToBitmap(icon);
extractedIconColor = ColorProvider.getDominantColor(iconBm);
}
res.add(new ApplicationInfo(appName, icon, packageName, extractedIconColor));
}
}
}
return res;
}

在Android 11中,我们可以看到许多改进隐私的更新。如果您的应用程序使用PackageManager方法获取用户设备中已安装应用程序的列表,则必须对使用Android 11的设备的代码进行一些更改。

现在,对于使用Android 11的用户来说,代码保持不变,但除非在AndroidManifest中添加一些附加元素,否则它不会起作用

有3种不同的方式来查询已安装的应用

1.查询特定包

如果您已经知道要查询哪些应用程序,只需提及AndroidManifest<queries>元素内的包名称即可。

<manifest package="com.nd1010.app">
<queries>
<package android:name="com.fake.app" /> //replace with com.android.wallpaper.livepicker
<package android:name="com.fake.game" /> //replace with com.gocalsd.symphlyx
</queries>
...
</manifest>

2.使用意向过滤器查询

如果您不知道要查询的应用程序的所有包名称,但有一组具有类似功能的应用程序要查询,那么您可以根据自己的要求在<queries>元素中使用意向过滤器,就像下面的代码片段中所做的那样。

<manifest package="com.nd1010.app">
<queries>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="image/jpeg" />
</intent>
</queries>
...
</manifest>

<intent>元素看起来像,但几乎没有区别。<intent>元素具有以下限制:

  • <intent>元素只能有一个<action>元素
  • <data>元素只能具有以下属性:mimeTypeschemehost

3.查询所有应用程序

如果你想像之前一样查询用户的所有应用程序,你需要在AndroidManifest中包含QUERY_ALL_PACKAGES权限。这是一个正常的权限,一旦安装应用程序,就会授予它。

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>

理想情况下,一个人应该要求最少的包裹数量,并尊重用户的隐私。在大多数情况下,不需要此权限,只有对于启动器等应用程序,向用户请求查询手机上所有已安装应用程序的权限才有意义。

在探索<queries>元素时,我注意到了一个漏洞,如果您在意向过滤器中添加android.intent.action.MAIN作为动作元素,您可以在不添加权限的情况下查看用户的几乎所有应用,因为几乎所有应用都会在AndroidManifest中包含此元素。

相关内容

最新更新