Google is committed to advancing racial equity for Black communities. See how.

Package visibility in Android 11

Android 11 changes how apps can query and interact with other apps that the user has installed on a device. Using the new <queries> element, apps can define the set of other apps that they can access. This element helps encourage the principle of least privilege by telling the system which other apps to make visible to your app, and it helps app stores like Google Play assess the privacy and security that your app provides for users.

If your app targets Android 11, you might need to add the <queries> element in your app's manifest file. Within the <queries> element, you can specify apps by package name, by intent signature, or by provider authority.

The <queries> element allows you to describe which other apps your app might need to interact with. You can specify apps by package name or by intent signature within a single <queries> element. For information on how to query for other apps to fulfill a specific use case, see the package visibility use cases guide.

The PackageManager methods that return results about other apps, such as queryIntentActivities(), are filtered based on the calling app's <queries> declaration. Explicit interactions with other apps, such as startService(), also require the target app to match one of the declarations in <queries>.

We're interested in hearing your feedback! Please take this short survey to let us know how you're using the feature. In particular, tell us about use cases impacted by this feature.

Set up your environment

To build an app that uses the <queries> element, use the following tools:

Query and interact with specific packages

If you know the specific set of apps that you want to query or interact with, such as apps that integrate with your app, or apps whose services you use, include their package names in a set of <package> elements inside the <queries> element:

<manifest package="com.example.game">
    <queries>
        <package android:name="com.example.store" />
        <package android:name="com.example.services" />
    </queries>
    ...
</manifest>

Query and interact with apps given an intent filter

Your app might need to query or interact with a set of apps that serve a particular purpose, but you might not know the specific package names to include. In this situation, you can list intent filter signatures in your <queries> element. Your app can then discover apps that have matching <intent-filter> elements.

The following example allows your app to see installed apps that support JPEG image sharing:

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

The <intent> element has a few restrictions:

  • You must include exactly one <action> element.
  • You cannot use the path, pathPrefix, pathPattern, or port attributes in a <data> element. The system behaves as if you set each attribute's value to the generic wildcard character (*).
  • You cannot use the mimeGroup attribute of a <data> element.
  • Within the <data> elements of a single <intent> element, you can use each of the following attributes at most once:

    • mimeType
    • scheme
    • host

    You can distribute these attributes across multiple <data> elements or use them in a single <data> element.

The <intent> element supports the generic wildcard character (*) as the value for a few attributes:

  • The name attribute of the <action> element.
  • The subtype of the mimeType attribute of a <data> element (image/*).
  • The type and subtype of the mimeType attribute of a <data> element (*/*).
  • The scheme attribute of a <data> element.
  • The host attribute of a <data> element.

Unless otherwise specified in the previous list, the system doesn't support a mix of text and wildcard characters, such as prefix*.

Query and interact with apps given a provider authority

In cases where you need to query a content provider but don't know the specific package names, you can declare that provider authority in a <provider> element, as shown in the following snippet:

<manifest package="com.example.suite.enterprise">
    <queries>
        <provider android:authorities="com.example.settings.files" />
    </queries>
    ...
</manifest>

You can declare multiple provider authorities in a single <queries> element. To do so, complete one of the following steps:

  • In a single <provider> element, declare a semicolon-delimited list of authorities.
  • Include multiple <provider> elements, all within the same <queries> element. In each <provider> element, declare either a single authority or a semicolon-delimited list of authorities.

Query and interact with all apps

In rare cases, your app might need to query or interact with all installed apps on a device, independent of the components they contain. To allow your app to see all other installed apps, Android 11 introduces the QUERY_ALL_PACKAGES permission.

The following list gives some examples of use cases where the QUERY_ALL_PACKAGES permission is appropriate to include:

  • Launcher apps
  • Accessibility apps
  • Browsers
  • Peer-to-peer (P2P) sharing apps
  • Device management apps
  • Security apps

In the vast majority of cases, however, it's possible to fulfill your app's use cases by declaring the <queries> element. To respect user privacy, your app should request the smallest amount of package visibility necessary in order for your app to work.

In an upcoming policy update, look for Google Play to provide guidelines for apps that need the QUERY_ALL_PACKAGES permission.

Use cases that aren't affected by the change

The following list includes several examples of use cases that don't require a <queries> declaration:

  • The target app is your own app.
  • You use an implicit intent to start an activity.
  • Your app interacts with certain system packages, such as the media provider, that implement core Android functionality.
  • The target app installed your app. You have visibility into the app(s) returned from the calls to getInitiatingPackageName() and getInstallingPackageName() on the InstallSourceInfo object for your own app.
  • An app launches your app using the startActivityForResult() method. (That app becomes visible to your app automatically.)
  • An app starts or binds to a service in your app. (That app becomes visible to your app automatically.)
  • An app makes a request to a content provider in your app. (That app becomes visible to your app automatically.)
  • Your app is an input method editor (IME) and is providing input to another app. (That app becomes visible to your app automatically.)

Log messages for package filtering

To discover more details about how the changes to package visibility affect your app, you can enable log messages for package filtering. If you're developing a test app or debuggable app in Android Studio, this capability is enabled for you. Otherwise, you can run the following command in a terminal window to enable it manually:

adb shell pm log-visibility --enable PACKAGE_NAME

Then, whenever packages are filtered out of a PackageManager object's return values, you see a message similar to the following in Logcat:

I/AppsFilter: interaction: PackageSetting{7654321 \
  com.example.myapp/12345} -> PackageSetting{...} BLOCKED

Test the change

To test whether this behavior change has taken effect in your app, complete the following steps:

  1. Install Android Studio 3.6.1 or higher.
  2. Install the latest version of Gradle that Android Studio supports.
  3. Set your app's targetSdkVersion to 30.
  4. Don't include the <queries> element in your app's manifest file.
  5. Call getInstalledApplications() or getInstalledPackages(). Both methods should return a filtered list.
  6. See which features of your app aren't working.
  7. Introduce appropriate <queries> entries to fix these features.