他のアプリとの連携を制限する

権限の目的はシステム機能を要求することだけではありません。他のアプリがアプリのコンポーネントと連携する方法を制限することもできます。

このガイドでは、別のアプリで宣言されている権限のセットを表示する方法について説明します。また、他のアプリがアプリと連携する方法を制限するように、アクティビティ、サービス、コンテンツ プロバイダ、ブロードキャスト レシーバを設定する方法について説明します。このページの最後では、アプリ間の連携パターンを強制する他の方法についても説明します。

別のアプリの権限を表示する

別のアプリで宣言されている権限のセットを表示するには、デバイスまたはエミュレータで次の手順を行います。

  1. アプリの [アプリ情報] 画面を開きます。
  2. [権限] を選択します。[アプリの権限] 画面が表示されます。

    この画面には、権限グループのセットが表示されます。アプリが宣言した権限のセットは、これらのグループに整理されます。

アプリのアクティビティとの連携を制限する

android:permission 属性を使用してマニフェストの <activity> タグに適用される権限により、その Activity を開始できる主体が制限されます。権限は、Context.startActivity()Activity.startActivityForResult() でチェックされます。呼び出し元に必要な権限がない場合は、SecurityException が発生します。

アプリのサービスとの連携を制限する

android:permission 属性を使用してマニフェストの <service> タグに適用される権限により、関連する Service を開始またはバインドできる主体が制限されます。権限は、Context.startService()Context.stopService()Context.bindService() でチェックされます。呼び出し元に必要な権限がない場合は、SecurityException が発生します。

アプリのコンテンツ プロバイダとの連携を制限する

android:permission 属性を使用して <provider> タグに適用される権限により、ContentProvider 内のデータにアクセスできる主体が制限されます(コンテンツ プロバイダでは、後述の URI 権限と呼ばれる追加の重要なセキュリティ機能を使用できます)。他のコンポーネントと異なり、2 つの権限属性を個別に設定できます。android:readPermission はプロバイダから読み取りを行う主体を制限し、android:writePermission は書き込みを行う主体を制限します。プロバイダが読み取りと書き込みの両方の権限で保護されている場合、書き込み権限だけを持っていても、プロバイダの情報を読み取ることはできません。

この権限は、最初にプロバイダを取得するとき(いずれかの権限を持っていない場合、SecurityException が発生します)と、プロバイダでオペレーションを行うときに確認されます。ContentResolver.query() を使用するには読み取り権限が必要です。ContentResolver.insert()ContentResolver.update()ContentResolver.delete() を使用するには書き込み権限が必要です。いずれの場合も、必要な権限を持っていなければ SecurityException が発生します。

URI ごとにアクセスを許可する

他のアプリがコンテンツ プロバイダにアクセスする方法を詳細に制御できます。特に、コンテンツ プロバイダは、プロバイダの直接クライアントが特定の URI を他のアプリと共有できるようにしつつ、読み書きの権限で自身を保護できます。このモデルに対するアプリのサポートを宣言するには、android:grantUriPermissions 属性または <grant-uri-permission 要素を使用します。

URI ごとに権限を付与することもできます。アクティビティを開始するとき、またはアクティビティに結果を返すとき、インテント フラグ Intent.FLAG_GRANT_READ_URI_PERMISSIONIntent.FLAG_GRANT_WRITE_URI_PERMISSION のいずれかまたは両方を設定します。これにより、インテントに含まれるデータ URI に対する読み取り、書き込み、読み取り / 書き込みの権限が一方のアプリに付与されます。他方のアプリは、コンテンツ プロバイダのデータに一般的にアクセスする権限の有無にかかわらず、特定の URI に対するこれらの権限を付与されます。

たとえばユーザーがアプリでメールを表示しており、そのメールに、添付ファイルとして画像が含まれているとします。他のアプリは一般的にメール コンテンツにアクセスできないはずですが、画像の表示を必要とする場合もあります。画像表示アプリで画像を表示するには、アプリでインテントと Intent.FLAG_GRANT_READ_URI_PERMISSION インテント フラグを使用します。

もう 1 つの考慮事項は、アプリの公開設定です。Android 11(API レベル 30)以降をターゲットとするアプリの場合、そのアプリで、一部のアプリは自動的に表示されますが、他のアプリはデフォルトでは表示されません。アプリにコンテンツ プロバイダがあり、別のアプリに URI 権限を付与すると、そのアプリは他のアプリに自動的に表示されます。

詳細については、grantUriPermission() メソッド、revokeUriPermission() メソッド、checkUriPermission() メソッドの参考資料をご覧ください。

アプリのブロードキャスト レシーバとの連携を制限する

android:permission 属性を使用して <receiver> タグに適用される権限により、関連する BroadcastReceiver にブロードキャストを送信できる主体が制限されます。権限は、Context.sendBroadcast() が返された後、送信されたブロードキャストを指定されたレシーバにシステムが配信しようとしたときにチェックされます。したがって、権限エラーが発生しても呼び出し元に例外はスローされません。単に Intent が配信されないだけです。

同様に、Context.registerReceiver() に権限を与えることにより、プログラムで登録されたレシーバにブロードキャストを送信できる主体を制限できます。逆に、Context.sendBroadcast() を呼び出す際に権限を与えて、ブロードキャストを受信できるブロードキャスト レシーバを制限することもできます。

ブロードキャストの受信側と送信側の両方で権限が必要とされる場合があります。その場合、関連するターゲットにインテントが配信されるためには、両方の権限チェックに合格する必要があります。詳細については、権限の設定によるブロードキャストの制限をご覧ください。

権限に関するその他の確認

有用な権限の確認方法は他にもいくつかあります。

  • サービスの呼び出し中に、権限文字列を Context.checkCallingPermission() に渡します。この方法では、現在の呼び出しプロセスにその権限が付与されているかどうかを示す整数値が返されます。別のプロセスからの呼び出しを実行する場合にのみ使用できることに注意してください。このような呼び出しは、一般的にはサービスから発行された IDL インターフェースを介して行いますが、別のプロセスに固有の他の方法で行うこともあります。
  • 別のプロセスに特定の権限が付与されているかどうかを確認するには、プロセス(PID)を Context.checkPermission() に渡します。
  • 別のパッケージに特定の権限が付与されているかどうかを確認するには、パッケージ名を PackageManager.checkPermission() に渡します。