Whitelisting
The preferred way to relax this restriction is to “whitelist” certain things. Basically, you tell Android, via a <queries>
element in the manifest, what sorts of other components you want to be able to see.
NOTE: Android Studio 4.0.1 — the current stable release of Android Studio — does not recognize this <queries>
element, even if you put it as a child of the <manifest>
element (the correct location). Just ignore the warning, and hope that, in the future, newer versions of Android Studio will ship with knowledge of this <queries>
element.
By Package
If you wish to have your app integrate with specific other apps, you can whitelist the package of that other app, by having a <package>
element inside of the <queries>
element, listing the package that you want to use:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.commonsware.android.r.embed.client">
<queries>
<package android:name="com.commonsware.android.r.embed.server" />
</queries>
<application
android:name=".MainApp"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Here, we have a fairly generic manifest, except for the <queries>
element towards the top. Here, we say that this app wants to be able to communicate with the com.commonsware.android.r.embed.server
app. This allows the client app to bind to a service exposed by com.commonsware.android.r.embed.server
, and it allows that service to return data (e.g., send messages back via a supplied Messenger
).
It appears that you can have as many <package>
elements as you want. However, there is no sign of support for wildcard pattern matching — you need to know, at compile time, what packages you need.
By Intent Signature
In our manifests, we are used to having <intent-filter>
elements on components to say that they are available to other apps via matching Intent
objects.
Now, in <queries>
, we can have <intent>
elements — with the same basic structure as <intent-filter>
elements — advertising what other components we want to talk to via IPC.
So, for example, a launcher might have:
<manifest package="com.example.game">
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent>
</queries>
<!-- rest of manifest goes here -->
</manifest>
This, in principle, should allow the launcher app to query for MAIN
/LAUNCHER
activities as before.
In general, everything allowed in an <intent-filter>
is allowed in an <intent>
element… with some restrictions:
- There must be exactly one
<action>
element, though you can use wildcards - You are limited to
mimeType
,scheme
, andhost
attributes on your<data>
element, where wildcards are also supported
We will see an example of this later in the chapter.
<queries>
and Gradle
The Android Gradle Plugin needs to know about new manifest elements, particularly for the manifest merger process. The plugin has a tendency to get confused if it sees elements in the manifest merger that it does not recognize, tossing out build errors like: “unexpected element <queries> found in <manifest>”.
And, as you might guess from that error, the Android Gradle Plugin was not happy about the introduction of <queries>
.
The fact that this occurs from manifest merger means that simply upgrading a dependency might bring about this error. For example, if you upgrade to the latest version of com.awesome:awesome-library
, and it contained a <queries>
element in its manifest, you would crash with the aforementioned error in your builds, even without any actual app changes in your code.
Google released a series of patch versions of the Android Gradle Plugin to address this:
3.3.3
3.4.3
3.5.4
3.6.4
4.0.1
If you are using an existing plugin in the 3.3.*
through 4.0.*
series, upgrade to the associated patch version (or higher) from that list, and you should no longer run into that error.
If you are using Android Studio 4.1 or higher, with a matching Android Gradle Plugin (e.g., in the 4.1.*
series), you should be fine without any changes. Those plugin versions were already aware of <queries>
.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.