简体   繁体   中英

List of apps doesn't populate on Android 11 using PackageManager

I am using package manager to get a list of apps for an app drawer interface in my launcher. Everything works as it should but on Android 11,the only app that shows is the Android Settings app. What changed to make this not work anymore and/or what should i do to make it work? Are app list now based on user profiles?

Here is my current list code

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;

}

In Android 11, we can see a lot of updates that improve privacy. If your app uses the PackageManager methods to get the list of installed apps in the user's device, you will have to make some changes in your code for devices using Android 11.

Now for your users using Android 11, the code remains the same but it won't work unless you add some additional elements in the AndroidManifest

There are 3 different ways of querying installed apps

1.Query specific packages

If you already know which apps you want to query just mention the package names inside the <queries> element in the 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>

2.Query using intent filter

In case you don't know all the package names of the apps that you want to query but there is a set of apps with similar functionality that you want to query then you can use an intent filter inside the <queries> element according to your requirements like it has been done in the code snippet below.

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

The <intent> element looks like but there are few differences. <intent> element has the following restrictions:

  • The <intent> element can have only one <action> element.
  • The <data> element can only have the following attributes: mimeType , scheme and host .

3.Query all the apps

If you want to query all the apps of the user like you were doing earlier, you need to include QUERY_ALL_PACKAGES permission in the AndroidManifest . It is a normal permission and it is granted as soon as the app is installed.

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

Ideally one should request the least amount of packages and respect the user's privacy. In most cases this permission won't be required, only for apps like launchers it makes sense to ask the user for permission to query all the installed apps on their phone.

There is one loophole that I noticed while exploring the <queries> element if you add android.intent.action.MAIN as the action element in the intent filter, you can see almost all the apps of the user without adding the permission since almost all apps would have this element in the AndroidManifest .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM