As you create your app, it's important to consider the set of packages, representing other installed apps on the device, that your app intends to access. If your app targets Android 11 (API level 30) or higher, the system makes some apps visible to your app automatically, but it hides other apps by default. By making some apps not visible by default, the system 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.
These differences in app visibility affect the return results of methods that
give information about other apps, such as
queryIntentActivities()
.
The differences in visibility also affect explicit interactions with other apps,
such as starting another app's service.
This guide lists the set of apps that are visible to your app automatically and describes how to make other apps visible to your app. The guide also gives some suggestions on how you can configure log messages to determine how the visibility of other apps affects your app.
Apps that are visible automatically
The system automatically makes some apps visible to your app so that your app
can interact with them without needing to declare the <queries>
element. This
behavior helps support basic functionality and common use cases.
In particular, the following types of apps are always visible to your app, even when your app targets Android 11 (API level 30) or higher:
- Your own app.
- Certain system packages, such as the media provider, that implement core Android functionality. Learn more about how to determine which packages are visible automatically on the device that runs your app.
- The app that installed your app.
- Any app that launches an activity in your app using the
startActivityForResult()
method, as described in the guide about how to get a result from an activity. - Any app that starts or binds to a service in your app.
- Any app that accesses a content provider in your app.
- Any app that has a content provider, where your app has been granted URI permissions to access that content provider.
- Any app that receives input from your app. This case applies only when your app provides input as an input method editor.
In addition, you can start another app's activity using either an implicit or explicit intent, regardless of whether that other app is visible to your app.
System packages that are visible automatically
Some system packages that implement core Android functionality are automatically visible to your app, even when your app targets Android 11 (API level 30) or higher. The specific set of packages depends on the device that runs your app.
To view the full list of packages for a specific device, run the following command in a terminal on your development machine:
adb shell dumpsys package queries
In the command output, find the forceQueryable
section. This section includes
the list of packages that the device has made visible to your app automatically.
Declare that your app interacts with a specific set of other apps
If your app targets Android 11 (API level 30) or higher and needs to interact
with apps other than the ones that are visible
automatically, add the <queries>
element in your
app's manifest file. Within the <queries>
element, specify the other apps by
package name, by intent signature, or by
provider authority, as described in the following
sections.
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
, orport
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, the system provides 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 interacting with the set of apps that are visible automatically and by declaring the other apps that your app needs to access in your manifest file. 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.
Log messages for package filtering
To discover more details about how the default visibility of apps affects 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