Working with Package Visibility

Meghan Mehta
Apr 1 · 3 min read

In Android, we are making changes to enhance user privacy and platform security to provide our users with a safer experience. Apps targeting Android 11 (API level 30) or higher will only see a filtered list of apps that are installed on a device. In order to access apps beyond that filtered list, an app will need to declare the apps they need to interact with directly using a <queries> element in the Android manifest. This blog post will go through best practices of how to adapt to this feature.

Querying and interacting with apps:

There are different ways to query and interact with apps:

We encourage data minimization by querying only for the packages you need to interact with. QUERY_ALL_PACKAGES or equivalently broad <intent> elements should only be used by apps that need this level of information. Our new Package Visibility policy introduces an approval process for the new QUERY_ALL_PACKAGES permission which controls access to the complete inventory of installed apps on a device.

Activity flags:

Most common use cases don’t require your app to have package visibility at all. For many scenarios, you can use startActivity() and catch an exception if there is no app that can open this intent.

While you can start any activity without visibility of the target, you can’t query for the availability of that activity before starting it or learn which specific app will be launched because it is an implicit intent. Instead, you will be notified when you start if it doesn’t resolve. If you want to be more selective about what opens, you can use flags.

A common example that uses flags is Custom Tabs, which allow a developer to customize how a browser looks and feels and have more control over the web content experience. Links will correctly open in non-browser apps if available, but flags help in advanced cases when developers want to be selective about handling the content in a native application before using custom tabs. In short, this flag helps a developer determine if there’s a native app to navigate to and from there they can handle it how they want.

FLAG_ACTIVITY_REQUIRE_NON_BROWSER

This flag only launches the intent if it resolves to a result that is not a browser. If no such result exists, an ActivityNotFoundException will be thrown and your app can then open the URL in a custom tab.

If an intent includes this flag, a call to startActivity() causes an ActivityNotFoundException to be thrown when the call would have launched a browser app directly or the call would have shown a disambiguation dialog to the user, where the only options are browser apps. To read more about flags, see Configuring package visibility based on use cases.

Customizing a share sheet

We recommend using the system share sheet instead of a custom one. You can customize the system share sheet without needing app visibility. Refer to this documentation for more information.

Debugging Package Visibility

You can easily check your manifest to see all queries included. In order to do this, go to your manifest file and choose Merged Manifest.

You can also enable log messages for package filtering to see how default visibility affects your app:

Next steps:

For more information on Package Visibility, check out these resources:

Happy coding!

Android Developers

The official Android Developers publication on Medium

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store