コンテンツに移動

よくアクセスするページ

最近アクセスしたページ

navigation

アプリ パーミッションのベスト プラクティス

パーミッション リクエストにより、端末で利用できる機密情報が保護されます。パーミッションは、アプリが機能するために情報にアクセスすることが必要な場合にのみ使用する必要があります。このドキュメントでは、こうした情報にアクセスする必要なく、同じ(または、より優れた)機能を実現するための方法について説明しています。Android オペレーティング システムでパーミッションが機能する方法の説明はそれほど難しいものではありません。

Android パーミッションの概要については、パーミッションとユーザーデータを参照してください。コードでパーミッションを使用する方法の詳細については、システム パーミッションの使用を参照してください。一意の識別子を使用する際のベスト プラクティスについては、一意の識別子のベスト プラクティスを参照してください。

Android パーミッションを扱うときの原則

Android パーミッションを扱うときは、次の原則に従うことをお勧めします。

#1: アプリが機能するために必要な場合にのみパーミッションを使用する。パーミッションの使用方法によっては、機密性の高い情報にアクセスすることなく、必要な操作(システム インテント、識別子、バックグラウンドでの通話)を行う別の方法が存在する場合があります。

#2: ライブラリが必要とするパーミッションに注意する。ライブラリを含めると、そのパーミッションの要件も継承します。含める要素、その要素が必要とするパーミッション、パーミッションの用途に注意する必要があります。

#3: 透過的にする必要がある。パーミッションをリクエストするときは、アクセスする対象とアクセスの理由を明確にし、ユーザーが十分な情報に基づいて判断できるようにする必要があります。パーミッション リクエストと共に十分な情報を、インストール、ランタイムおよびアップデート時のダイアログに表示してください。

#4: システム アクセスを明示的にする。機密性の高い機能(たとえば、カメラやマイク)にアクセスするときは、通知を継続して表示することにより、ユーザーに対して、データを収集するタイミングを明確にし、データをひそかに収集しているという疑いを持たれないようにします。

このガイドの残りのセクションでは、Android アプリの開発における、これらのルールについて解説しています。

Android 6.0 以降のパーミッション

Android 6.0 Marshmallow では、インストールの前ではなく、実行時にアプリがユーザーからのパーミッションをリクエストできるようにする新しいパーミション モデルが導入されました。この新しいモデルをサポートするアプリは、サービス、またはサービスによって保護されているデータが実際に必要なときにパーミッションをリクエストします。これにより、アプリの全体的な動作が(必ずしも)変更されることはありませんが、機密性の高いユーザーデータを扱う方法に関連する動作が少し変更されます。

状況コンテキストの増加: ユーザーは、アプリの状況に応じて実行時に、こうしたパーミッション グループが適用される機能にアクセスするためのパーミッションを求められます。ユーザーは、パーミッションがリクエストされる状況に関して敏感であるため、リクエストされているパーミッションとアプリの用途の間に不一致がある場合は、パーミッションをリクエストしている理由に関する詳細な説明をユーザーに提供することがさらに重要になります。可能な場合は常に、リクエストするとき、およびユーザーがリクエストを拒否した場合は以降のダイアログで、リクエストしている理由を提示する必要があります。

パーミッションを付与する際の高い柔軟性:ユーザーは、パーミッションがリクエストされたとき、および設定で、個々のパーミッションへのアクセスを拒否できますが、その結果として、機能が動かなくなると、驚く可能性があります。多くのユーザーがパーミッションをどのように拒否しているかをモニターする(たとえば、Google アナリティクスを使用して)ことにより、アプリをリファクタリングして、そのパーミッションを使用しないようにするか、アプリの適切な機能のためにパーミッションを必要としている理由について詳しい説明を提供します。また、ユーザーがパーミッション リクエストを拒否した場合、または設定でパーミッションをオフに切り替えた場合に生成される例外をアプリが処理できるようにする必要があります。

トランザクションの負荷の増加: ユーザーは、セットとしてではなく、個々のパーミッション グループへのアクセスを付与するように求められます。つまり、リクエストするパーミッションの数を最小限にすることが非常に重要なります。リクエストするパーミッションの数が増加すると、ユーザーがパーミッションを付与する手間が増え、少なくとも 1 つのリクエストが拒否される可能性が高くなるからです。

不要なパーミッション リクエストの回避

このセクションでは、パーミッション リクエストの数を制限することに役立つ、一般的なユースケースに代わる選択肢について説明します。ユーザーにリクエストされるパーミッションの数とタイプは、パーミッションのリクエストが少ない他の類似したアプリと比較した場合のダウンロード数に影響を及ぼすため、不要な機能のパーミッションをリクエストしないようにすることをお勧めします。

リアルタイムのユーザー リクエストよるカメラ / 連絡先へのアクセス

このケースでは、端末のカメラまたは連絡先情報に定期的にアクセスする必要がありますが、アクセスが必要になるたびに、ユーザーにパーミッションの付与が求められることについては、懸念する必要はありません。

ユーザーデータへのアクセスを求める頻度が低い場合、つまりユーザーに許容される範囲で、データへのアクセスが必要になるたびにランタイム ダイアログが表示される場合は、インテントベースのリクエストを使用できます。Android には、パーミッションを求める必要なく、アプリが使用できるいくつかのシステム インテントが用意されています。パーミッションを求める必要がない理由は、インテントベースのリクエストが発行された際に、アプリと共有する要素(存在する場合)をユーザーが選択するからです。

たとえば、 MediaStore.ACTION_IMAGE_CAPTURE または MediaStore.ACTION_VIDEO_CAPTURE のインテント アクション タイプを使用すると、Camera オブジェクトを直接使用することなく(または、パーミッションを要求する必要なく)、画像やビデオを撮影することができます。このケースでは、画像が撮影されるたびに、システム インテントにより、ユーザーにパーミッションが求められます。

オーディオ フォーカスを失った後のバックグラウンドでの実行

このケースでは、ユーザーに電話がかかってくると、アプリはバックグラウンドに移行し、通話が終了すると、一度だけ再度フォーカスします。

たとえば、通話中にメディア プレイヤーがミュートになるか、一時停止することなど、こうしたケースの一般的なアプローチでは、PhoneStateListener を使用して、通話の状態の変化をリッスンするか、android.intent.action.PHONE_STATE のブロードキャストをリッスンします。このソリューションの問題は、READ_PHONE_STATE パーミッションが必要なことであり、ユーザーは、端末や SIM ハードウェアの ID および着信した電話番号など、機密性の高いさまざまなデータへのアクセスを付与する必要があります。

アプリで明示的なパーミッションが不要な(機密性の高い情報にアクセスしない)AudioFocus をリクエストすることにより、この問題を回避することができます。オーディオがバックグラウンドで必要とするコードを onAudioFocusChange() イベント ハンドラに追加するだけで、OS がオーディオ フォーカスを変えると、このコードが自動的に実行されます。この操作を実行する方法について詳しく説明したドキュメントは、こちらにあります。

インスタンスが実行されている端末の判別

このケースでは、アプリのインスタンスが実行されている端末を判別するために、一意の識別子が必要なります。

アプリに、端末固有の設定またはメッセージがある場合があります(たとえば、ユーザーが車内や自宅で異なるプレイリストを楽しめるように、クラウドでユーザーの端末固有のプレイリストを保存する場合)。一般的なソリューションは、Device IMEI などの端末識別子を利用することですが、これには、Device ID and call information パーミッション グループ(M 以降では PHONE)が必要です。また、すべてのアプリ間で共有されるリセットできない識別子を使用します。

これらのタイプの識別子を使用する代わりに、次の 2 つの代替方法を使用できます。

  1. com.google.android.gms.iid InstanceID API を使用します。getInstance(Context context).getID() は、アプリ インスタンスの一意の端末識別子を返します。その結果、アプリに関する情報を保存するときにキーとして使用でき、ユーザーがアプリを再インストールするとリセットされる識別子がアプリ インスタンスに適用されます。
  2. randomUUID() などの基本的なシステム機能を使用して、アプリのストレージに適用される独自の識別子を作成します。

広告またはユーザー分析用の一意の識別子の作成

このケースでは、アプリにサインインしていないユーザーのプロファイルを作成するために一意の識別子が必要になります(たとえば、広告のターゲティングやコンバージョンの評価のために)。

広告やユーザー分析のためにプロファイルを作成する場合、他のアプリの間で共有される識別子が必要になることがあります。これに対する一般的なソリューションには、Device ID and call information パーミッション グループ(API レベル 23 以上では PHONE)を必要とする、ユーザーによってリセットされない Device IMEI などの端末識別子の利用が含まれます。また、これらのケースでは、リセット不可の識別子を使用したり、ユーザーにとって不自然に見える可能性のあるパーミッションをリクエストしたりすることに加えて、Google Play デベロッパー プログラム ポリシーに違反することになる場合があります。

残念ながら、これらのケースでは、アプリ間で ID を共有しなければならない場合があるため、com.google.android.gms.iid InstanceID API やシステム機能を使用して、アプリに適用される ID を作成することは適切なソリューションではありません。代替のソリューションは、getId() メソッドを介して AdvertisingIdClient.Info クラスから利用できる Advertising Identifier を使用することです。getAdvertisingIdInfo(Context) メソッドを使用して、AdvertisingIdClient.Info オブジェクトを作成し、getId() メソッドを呼び出して、識別子を使用することができます。これはブロッキング メソッドであるため、メインスレッドからこのメソッドを呼び出さないでください。このメソッドの詳細については、こちらを参照してください。

使用するライブラリの把握

アプリで使用するライブラリにパーミッションが必要になることがあります。たとえば、広告と分析のライブラリが Location へのアクセスや、必要な機能を実装するために Identity パーミッション グループを要求する場合があります。ただし、ユーザーの視点から見ると、パーミッション リクエストは、ライブラリではなく、アプリから送信されているように見えます。

同じ機能に対してより少ないパーミッションを使用するアプリをユーザーが選択する場合と同じように、デベロッパーは、ライブラリを確認して、不必要なパーミッションを使用しないサードパーティの SDK を選択する必要があります。たとえば、アプリがパーミッションを必要とする明確な理由がユーザーに説明されていない限り、Identity パーミッション グループを要求するライブラリの使用は避けるようにしてください。特に、位置情報機能を提供するライブラリの場合、位置情報ベースのターゲット機能を使用している場合を除いて、FINE_LOCATION パーミッションをリクエストする必要がないことに注意してください。

透過的にする必要性

アクセスしている対象とアクセスの理由をユーザーに通知する必要があります。調査では、ユーザーはアプリにパーミッションが必要な理由を知っている場合、パーミッション リクエストに対して、あまり不快感を感じないことが明らかになっています。あるユーザー調査では、次の点が指摘されています。

...ユーザーが特定のパーミッションを特定のモバイルアプリに付与するかどうかは、そのパーミッションに関連付けられている目的に大きく左右されます。たとえば、ユーザーが自分の位置情報へのアクセスを付与するかどうかは、アプリの中核機能をサポートするためにリクエストが要求されているのか、または広告ネットワークまたは分析会社とこの情報を共有するためにリクエストが要求されているかどうかによって異なります。1

カーネギーメロン大学の Jason Hong 教授は研究チームの調査結果に基づいて、概して次のように述べています。

...たとえば、ターゲット広告の場合など、ユーザーは、アプリが位置情報を使用していること単に知らされた場合よりも、アプリが位置情報のような機密性の高い情報を使用している理由を知っているときのほうが信頼感を感じます。1

そのため、パーミッション グループに該当する API 呼び出しのごく一部のみを使用している場合は、使用するパーミッションとパーミッションを使用する理由の明示的なリストを作成することが有用になります。次に例を示します。

特定の状況では、機密性の高いデータへのアクセスをリアルタイムでユーザーに知らせることが有効です。たとえば、カメラやマイクにアクセスする場合、通常、アプリ内の任意の場所に表示される通知アイコンまたは通知トレイ(アプリがバックグラウンドで動いている場合)を通じてユーザーにアクセスを知らせることにより、データをひそかに収集しているわけではないことを示すとよいでしょう。

最後に、アプリの何らかの機能を使用するためにパーミッションをリクエストする必要があるが、ユーザーにはその理由が明確ではない場合、最もセンシティブなパーミションが必要な理由をユーザーに知らせる方法を見つける必要があります。

リファレンス

[1] Modeling Users’ Mobile App Privacy Preferences:Restoring Usability in a Sea of Permission Settings, by J. Lin B. Liu, N. Sadeh and J. Hong.SOUPS 2014 の紀要。

このサイトでは、ユーザーが選択したサイトの言語と表示設定を保存する目的で Cookie を使用しています。

Android デベロッパー向けの最新情報やヒントを入手して、Google Play での成功を手に入れましょう。

* 必須

送信しました

WeChat で Google Developers をフォローする

このサイトをで表示しますか?

ページの表示言語としてを選択しましたが、このサイトの言語はに設定されています。

言語設定を変更してこのサイトをで表示しますか?言語設定を変更する場合は、各ページの下にある言語メニューを使用してください。

このクラスには、API レベル 以上が必要です。

API レベル が選択されているため、このドキュメントは非表示になっています。左のナビゲーションの上にあるセレクタを使って、ドキュメントの API レベルを変更できます。

アプリに必要な API レベルを指定する方法について、詳しくは異なるプラットフォーム バージョンのサポートをご覧ください。

Take a short survey?
Help us improve the Android developer experience. (April 2018 — Developer Survey)