パッケージの公開設定の必要性を宣言する

アプリを作成する際には、アプリが操作する必要があるデバイス上の他のアプリを考慮することが重要です。Android 11(API レベル 30)以降をターゲットとするアプリの場合、一部のアプリは自動的に公開されますが、それ以外のアプリはデフォルトでは公開されません。このガイドでは、デフォルトでは公開されないアプリを自分のアプリに公開する方法について説明します。

Android 11 以降をターゲットとするアプリで、自動的に公開されないアプリとの連携が必要な場合は、アプリのマニフェスト ファイルに <queries> 要素を追加します。次のセクションで説明するように、<queries> 要素内では、パッケージ名インテント シグネチャ、またはプロバイダ オーソリティで他のアプリを指定できます。

特定のパッケージ名

別のアプリを自分のアプリに統合する場合や、自分のアプリで別のアプリのサービスを使用する場合など、アプリがクエリや操作を行う特定のアプリについて把握している場合は、そのパッケージ名を指定した <package> 要素のセットを <queries> 要素に含めます。

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

ライブラリ内のホストアプリと通信する

Android ライブラリを開発する場合は、AAR マニフェスト ファイル<queries> 要素を追加することで、パッケージの公開設定の必要性を宣言できます。この <queries> 要素の機能は、アプリが独自のマニフェストで宣言できる要素と同じです。

ライブラリが「ホスト」アプリとの通信を伴う場合(バインドされたサービスの使用など)、ホストアプリのパッケージ名を指定した <package> 要素を含めます。

<!-- Place inside the <queries> element. -->
<package android:name=PACKAGE_NAME />

この宣言を含めれば、bindService() を呼び出すことなどで、ホストアプリがインストールされているかどうかを確認し、インストールされている場合は連携できます。ライブラリを使用する呼び出し元アプリは、この連携の結果として、ホストアプリに自動的に公開されます

インテント フィルタ シグネチャに一致するパッケージ

アプリが特定の目的を果たすアプリのセットに対してクエリや連携を行う必要があっても、指定するその個々のパッケージ名がわからない場合があります。その場合は、インテント フィルタのシグネチャのリストを <queries> 要素に指定できます。それにより、<intent-filter> 要素が一致するアプリを見つけられます。

次のコードサンプルは <intent> 要素を示していて、JPEG 画像を共有できる他のインストール済みアプリを検出できるようになっています。

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

<intent> 要素には以下のような制限があります。

  • <action> 要素は 1 つだけ含める必要があります。
  • <data> 要素内で pathpathPrefixpathPatternport の各属性を使用することはできません。各属性の値を汎用のワイルドカード文字(*)に設定した場合と同じように動作することになります。
  • <data> 要素の mimeGroup 属性は使用できません。
  • 1 つの <intent> 要素の複数の <data> 要素にわたって、以下の各属性を 1 回だけ使用できます。

    • mimeType
    • scheme
    • host

    これらの属性は複数の <data> 要素に分散させることも、1 つの <data> 要素で使用することもできます。

<intent> 要素は、属性の値として以下の汎用のワイルドカード文字(*)をサポートしています。

  • <action> 要素の name 属性。
  • <data> 要素の mimeType 属性のサブタイプ(image/*)。
  • <data> 要素の mimeType 属性のタイプとサブタイプ(*/*)。
  • <data> 要素の scheme 属性。
  • <data> 要素の host 属性。

前のリストで特に指定されていない限り、システムはテキストとワイルドカード文字(prefix* など)の組み合わせに対応していません。

特定のオーソリティを使用するパッケージ

コンテンツ プロバイダをクエリする必要があるものの、具体的なパッケージ名がわからない場合は、次のスニペットのように、<provider> 要素内でプロバイダ オーソリティを宣言できます。

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

複数のプロバイダ オーソリティを 1 つの <queries> 要素で宣言できます。<queries> 要素で宣言する <provider> 要素は、1 つでも複数でもかまいません。<provider> 要素では、単一のプロバイダ オーソリティ、またはセミコロンで区切った複数のプロバイダ オーソリティのリストを指定できます。

すべてのアプリ(非推奨)

まれなケースですが、デバイス上にインストールされている「すべての」アプリに対して、各アプリに含まれるコンポーネントに関係なく、クエリや連携を行うことが必要になる場合があります。自分のアプリがインストール済みの他のすべてのアプリを見つけられるように、QUERY_ALL_PACKAGES 権限が用意されています。

QUERY_ALL_PACKAGES 権限を使用することが適しているユースケースとしては、次のようなものがあります。

  • ユーザー補助機能アプリ
  • ブラウザ
  • デバイス管理アプリ
  • セキュリティ アプリ
  • ウイルス対策アプリ

ただし通常は、自動的に公開されるアプリセットと連携したり、自分のアプリがアクセスする必要がある他のアプリをマニフェスト ファイル内で宣言したりすることで、ユースケースに対応します。ユーザーのプライバシーを尊重し、アプリの動作に最低限必要な範囲で、パッケージへのアクセスをリクエストしてください。

Google Play のポリシー更新では、QUERY_ALL_PACKAGES 権限を必要とするアプリに関するガイドラインを提供しています。