Java 应用程序列表不';t使用PackageManager在Android 11上填充
我正在使用package manager为我的启动器中的应用程序抽屉接口获取应用程序列表。一切正常,但在安卓11上,唯一显示的应用程序是安卓设置应用程序。是什么改变了这一点,使其不再工作和/或我应该做些什么使其工作?应用程序列表现在是否基于用户配置文件 这是我当前的列表代码Java 应用程序列表不';t使用PackageManager在Android 11上填充,java,android,list,android-studio,Java,Android,List,Android Studio,我正在使用package manager为我的启动器中的应用程序抽屉接口获取应用程序列表。一切正常,但在安卓11上,唯一显示的应用程序是安卓设置应用程序。是什么改变了这一点,使其不再工作和/或我应该做些什么使其工作?应用程序列表现在是否基于用户配置文件 这是我当前的列表代码 public static List<ApplicationInfo> getPrimaryApps(Context context) { PackageManager pm = context.
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;
}
公共静态列表getPrimaryApps(上下文){
PackageManager pm=context.getPackageManager();
List res=new ArrayList();
ArrayList hiddenPackages=新建ArrayList();
IconPackHelper IconPackHelper=IconPackHelper.getInstance(上下文);
//所有应用程序包筛选器
Set filteredPackages=new HashSet();
filteredPackages.add(“com.android.wallper.livepicker”);
filteredPackages.add(“com.gocalsd.symphlyx”);
//所有应用程序黑名单
String[]FlattedPackages=SettingsProvider.get(上下文).getString(SettingsProvider.HIDDEN\u应用程序“”).split(“\\\\\”);
对于(字符串展开:扁平化包){
ComponentName cmp=ComponentName.unflattenFromString(平面);
如果(cmp!=null){
添加(cmp.getPackageName());
}
}
意图=新意图(Intent.ACTION\u MAIN,空);
intent.addCategory(intent.CATEGORY_启动器);
intent.setFlags(intent.FLAG_ACTIVITY_NEW_TASK|intent.FLAG_ACTIVITY_RESET_TASK_,如果需要);
List resolveInfoList=pm.querytentActivities(intent,0);
//对所有应用进行排序
排序(resolveInfoList,newresolveinfo.DisplayNameComparator(pm));
对于(ResolveInfo ResolveInfo:resolveInfoList){
ActivityInfo ActivityInfo=resolveInfo.ActivityInfo;
int iconId=IconPackHelper.getInstance(上下文).getResourceIdForActivityIcon(activityInfo);
如果(!filteredPackages.contains(resolveInfo.activityInfo.packageName)){
如果(!hiddenPackages.contains(resolveInfo.activityInfo.packageName)){
字符串appName=activityInfo.applicationInfo.loadLabel(pm.toString();
字符串packageName=activityInfo.packageName;
可绘制图标=空;
int-extractedIconColor=0;
//切换主题图标
if(iconPackHelper.isiconpackloated()&&iconPackHelper.getThemedIcon(context,packageName)){
如果(iconId!=0){
icon=IconPackHelper.getInstance(context).getIconPackResources().getDrawable(iconId);
位图iconBm=ImageUtils.drawableToBitmap(图标);
extractedIconColor=ColorProvider.getDominantColor(iconBm);
}
}
if(icon==null | | |!IconPackHelper.getInstance(context).isIconPackLoaded()){
icon=activityInfo.applicationInfo.loadIcon(pm);
位图iconBm=ImageUtils.drawableToBitmap(图标);
extractedIconColor=ColorProvider.getDominantColor(iconBm);
}
res.add(新的ApplicationInfo(appName、icon、packageName、extractedIconColor));
}
}
}
返回res;
}
在Android 11中,我们可以看到许多改进隐私的更新。如果您的应用程序使用PackageManager
方法获取用户设备中已安装应用程序的列表,则您必须对使用Android 11的设备的代码进行一些更改
现在,对于使用Android 11的用户,代码保持不变,但除非在AndroidManifest
有3种不同的方式查询已安装的应用程序
1.查询特定软件包
如果您已经知道要查询哪些应用程序,只需在AndroidManifest
中的
元素中提及包名即可
<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>
理想情况下,用户应要求最少数量的软件包,并尊重用户的隐私。在大多数情况下,不需要此权限,只有对于launchers之类的应用程序,才有必要向用户请求查询其手机上所有已安装应用程序的权限
在探索
元素时,如果在intent过滤器中添加android.intent.action.MAIN
作为action元素,我注意到了一个漏洞,您可以在不添加权限的情况下查看用户的几乎所有应用程序,因为几乎所有应用程序都会在AndroidManifest
中包含此元素肯定是解决方案
<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>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>