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:

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:

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.