アプリで権限を宣言する前に、その必要があるかどうかを検討します。権限を宣言すると、実行時の権限を必要とするアプリ機能をユーザーが実行しようとするたびに、アプリが権限リクエストでユーザーの操作を中断することになります。そのたびに、ユーザーは権限を付与するかどうかを決定しなければなりません。ユーザーは、アプリが特定の権限をリクエストする理由を理解できない場合、権限の付与を拒否することや、アプリをアンインストールすることさえあり得ます。
アプリに代わって別のインストール済みアプリがその機能を実行できるかどうかを検討してください。それが可能な場合は、インテントを使用して別のアプリにタスクを委任するべきです。そうすれば、必要な権限を別のアプリが宣言しているので、改めて権限を宣言する必要がありません。
権限の宣言に代わる方法
このセクションでは、アプリが権限の必要性を宣言せずに機能を実行できるいくつかのユースケースについて説明します。
付近の場所を表示する
アプリでユーザーのおおよその位置情報を知りたい場合があります。こうした機能は、近くのレストランなどの位置認識情報を表示する場合に役立ちます。
いくつかのユースケースでは、デバイスの位置情報を大まかに推定する必要があります。このような場合は、アプリで位置認識情報が必要になる頻度に応じて、次のいずれかを行います。
- アプリで位置情報が必要になる頻度が多い場合は、
ACCESS_COARSE_LOCATION
権限を宣言します。この権限は、おおよその位置情報の精度に関するドキュメントに記載されているように、位置情報サービスから取得されるデバイスの位置情報の推定値を提供します。 - アプリで位置情報が必要になる頻度が少ない場合や、位置情報が 1 回だけ必要な場合は、代わりに住所や郵便番号の入力をユーザーに求めることを検討してください。
ユースケースによっては、デバイスの位置情報をもっと正確に推定する必要があります。そのような場合だけは、ACCESS_FINE_LOCATION
権限を宣言しても問題ありません。
写真を撮る
プリインストールされているシステム カメラアプリを使用して、ユーザーがアプリで写真を撮影できる場合があります。
このような場合、CAMERA
権限を宣言しないでください。代わりに、ACTION_IMAGE_CAPTURE
インテントのアクションを呼び出します。
動画を撮影する
プリインストールされているシステム カメラアプリを使用して、ユーザーがアプリで動画を撮影できる場合があります。
このような場合、CAMERA
権限を宣言しないでください。代わりに、ACTION_VIDEO_CAPTURE
インテントのアクションを呼び出します。
アプリで作成したメディアを開く
アプリは、ユーザーがアプリ内で作成したメディア コンテンツ(写真や動画など)を表示する場合があります。このような場合、アプリが Android 10 以降をターゲットとする限り、Android 10(API レベル 29)以降を搭載したデバイスでは READ_EXTERNAL_STORAGE
権限を使用する必要はありません。アプリが Android 10 をターゲットとしている場合は、対象範囲別ストレージをオプトアウトします。
古いデバイスとの互換性を維持するには、READ_EXTERNAL_STORAGE
権限を宣言し、android:maxSdkVersion
を 28
に設定します。
メディアストアになじみ深い次のコレクションのいずれかでファイルを探します。
ContentResolver
を使用すると、メディア コンテンツを独自に検索するのではなく、メディアストアから直接メディア コンテンツをクエリできます。
ドキュメントを開く
アプリは、そのアプリまたは別のアプリでユーザーが作成したドキュメントを表示する場合があります。一般的な例はテキスト ファイルです。
このような場合、アプリが Android 10 以降をターゲットとする限り、Android 10 以降を搭載したデバイスでは READ_EXTERNAL_STORAGE
権限を使用する必要はありません。アプリが Android 10 をターゲットとしている場合は、対象範囲別ストレージをオプトアウトします。
古いデバイスとの互換性を維持するには、READ_EXTERNAL_STORAGE
権限を宣言し、android:maxSdkVersion
を 28
に設定します。
ドキュメントを作成したアプリに応じて、次のいずれかを行います。
- ユーザーがアプリでドキュメントを作成した場合は、直接アクセスします。
- ユーザーが別のアプリでドキュメントを作成した場合は、ストレージ アクセス フレームワークを使用します。
アプリのインスタンスを実行しているデバイスを特定する
アプリの特定のインスタンスで、そのインスタンスを実行しているデバイスを知りたい場合があります。こうした機能は、TV デバイスとウェアラブル デバイスで異なるプレイリストを表示するアプリなど、デバイス固有の設定やメッセージングを使用するアプリで役に立ちます。
このような場合、デバイスの IMEI に直接アクセスしないでください。実際、Android 10 の時点では、そのようなことはできません。代わりに次のいずれかを行います。
- インスタンス ID ライブラリを使用してアプリのインスタンスの一意のデバイス ID を取得する。
- アプリのストレージにスコープを限定した独自の ID を作成する。これには
randomUUID()
などの基本的なシステム関数を使用します。
Bluetooth 経由でデバイスをペア設定する
Bluetooth 経由で別のデバイスにデータを転送すると、アプリのユーザー エクスペリエンスを向上させることができます。
この機能をサポートする場合、ACCESS_FINE_LOCATION
、ACCESS_COARSE_LOCATIION
、BLUETOOTH_ADMIN
の各権限を宣言しないでください。代わりに、コンパニオン デバイスのペア設定を使用します。
アプリが中断したときにメディアを一時停止する
ユーザーに電話がかかってきた場合や、ユーザーが設定したアラームが作動した場合、アプリは音声フォーカスを再取得するまでメディア再生を一時停止する必要があります。
この機能をサポートする場合、READ_PHONE_STATE
権限を宣言しないでください。代わりに、onAudioFocusChange()
イベント ハンドラを実装します。このハンドラは、システムが音声フォーカスをシフトすると、自動的に実行されます。詳しくは、音声フォーカスを実装する方法をご覧ください。
電話の着信をフィルタする
ユーザーの操作への不必要な割り込みを最小限に抑えるために、アプリで迷惑電話をフィルタしたい場合があります。
この機能をサポートする場合、READ_PHONE_STATE
権限を宣言しないでください。代わりに、CallScreeningService
API を使用します。