javaandroidgoogle-playandroid-permissions

Alternative way to get app icon and name in Android 11+?


After the user has enabled Usage Access you seem to require the new QUERY_ALL_PACKAGES permission in Android 11+ to access a package's name and icon with the following code:

String appName = packageManager.getApplicationLabel( packageManager.getApplicationInfo(packageName,0) );
Drawable appIcon = packageManager.getApplicationIcon(packageName);

Otherwise I would get a PackageManager.NameNotFoundException for either lines of code which obviously means I don't have access to the friendly app name and icon.

Is there another way to achieve this without the permission? I can't find any other way other than code prior to Android 11.

I maintain an app that also features a screen time functionality but Google has refused to approve the inclusion of this "sensitive permission" in my update despite it being a core functionality of my app, claiming there are other ways to achieve this but also refusing to elaborate.

Keeping a whitelist of apps using <queries> isn't really a viable way of doing so obviously due to the infinite number of possibilities. Even just keeping a list of the most popular ones would require users to send a list of their apps to me and even then I would have to release a new update each time.


Solution

  • I did a fair amount of research on this back when I wrote this free book. At least at the moment, package visibility rules are very coarse-grained: if the package meets an allowlist rule, then everything with the package is available in PackageManager.

    So, you need to see if there is a generic whitelist entry that you can use — or perhaps a few — that will cover most or all of the apps that you care about.

    So, for example, if the packages that matter to you are ones with launchable activities, you could use:

        <queries>
            <intent>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent>
        </queries>
    

    This unlocks everything in PackageManager for apps with launchable activities, even things like getApplicationLabel() and getApplicationIcon() that technically are unrelated to the launchable activities.