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

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

このガイドでは、別のアプリで宣言されている一連の権限を確認する方法について説明します。また、他のアプリがお客様のアプリと連携する方法を制限するように、アクティビティ、サービス、コンテンツ プロバイダ、ブロードキャスト レシーバを設定する方法についても説明します。

別のアプリの権限を確認する

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

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

    この画面には、権限グループのセットが表示されます。アプリで宣言されている一連の権限は、権限グループに自動的に整理されます。

権限を確認する便利な方法は他にもいくつかあります。

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

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

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

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

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

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

マニフェストの <provider> タグに android:permission 属性を使用して、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() メソッドの参考資料をご覧ください。

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

<receiver> タグで android:permission 属性を使用して、関連付けられた BroadcastReceiver へのブロードキャストの送信を許可する他のアプリを制限します。権限のチェックは、Context.sendBroadcast() が戻った後、送信されたブロードキャストが指定レシーバに配信されるときに行われます。つまり、権限エラーが発生しても呼び出し元に例外がスローされることはなく、単に Intent が配信されないだけとなります。

同様に、Context.registerReceiver() に権限を付与し、プログラムで登録されているレシーバへのブロードキャストを許可する他のアプリを管理することもできます。逆方向の場合は、Context.sendBroadcast() の呼び出し時に権限を付与することで、ブロードキャストの受信を許可するブロードキャスト レシーバを制限します。

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