blob: f582756c816ce26f854259277593ecc35bc0e170 [file] [log] [blame]
page.title=パーミッション
page.tags=previewresources, androidm
page.keywords=パーミッション,実行時,プレビュー
page.image={@docRoot}preview/features/images/permissions_check.png
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>クイックビュー</h2>
<ul>
<li>アプリのターゲットが M Preview SDK の場合、インストール時ではなく実行時に、パーミッションを付与するようユーザーに求めます。
</li>
<li>ユーザーはいつでもアプリの [設定] 画面からパーミッションを取り消すことができます。
</li>
<li>アプリは実行時に毎回、必要なパーミッションがあることを確認する必要があります。
</li>
</ul>
<h2>本書の内容</h2>
<ol>
<li><a href="#overview">概要</a></li>
<li><a href="#coding">実行時のパーミッションのコード</a></li>
<li><a href="#testing">実行時のパーミッションをテストする</a></li>
<li><a href="#best-practices">ベスト プラクティス</a></li>
</ol>
<!--
<h2>Related Samples</h2>
<ol>
<li></li>
</ol>
-->
<!--
<h2>See also</h2>
<ol>
<li></li>
</ol>
-->
</div> <!-- qv -->
</div> <!-- qv-wrapper -->
<p>
M Developer Preview では、アプリをインストールしてアップグレードするユーザーのプロセスを効率化する新しいアプリのパーミッション モデルが導入されました。
M Preview で実行しているアプリで新しいパーミッション モデルがサポートされている場合、ユーザーはアプリをインストールまたはアップグレードするときにパーミッションを付与する必要はありません。その代わりに、アプリは必要になるとパーミッションを要求し、パーミッションを確認するよう求めるダイアログが表示されます。
</p>
<p>
アプリで新しいパーミッション モデルがサポートされている場合、以前のバージョンの Android を実行している端末で、以前のパーミッション モデルを使ってインストールして実行することもできます。
</p>
<h2 id="overview">
概要
</h2>
<p>
M Developer Preview とともに、プラットフォームでは新しいアプリのパーミッション モデルが導入されました。
この新しいモデルの主要なコンポーネントの概要を次に示します。
</p>
<ul>
<li>
<strong>パーミッションを宣言する:</strong> アプリは、以前の Android プラットフォームと同様に、マニフェストで必要なすべてのパーミッションを宣言します。
</li>
<li>
<strong>パーミッション グループ:</strong> パーミッションは、その機能に基づいて<em>パーミッション グループ</em>に分けられます。
たとえば、<code>CONTACTS</code> パーミッション グループにはユーザーの連絡先とプロフィール情報を読み書きするパーミッションが含まれます。
</li>
<li>
<p><strong>インストール時に付与される制限付きのパーミッション:</strong> ユーザーがアプリをインストールまたはアップデートするとき、{@link
android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} に該当する、アプリが要求するすべてのパーミッションがアプリに付与されます。
たとえば、目覚まし時計とインターネットのパーミッションは {@link
android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} に該当するため、インストール時に自動的にそれらのパーミッションが付与されます。
</p>
<p>システムは、<a href="#system-apps">システムアプリと署名のパーミッション</a>に記載のとおり、アプリの署名とシステムのパーミッションも付与することがあります。
ユーザーは、インストール時にパーミッションを付与するように促すメッセージは表示<em>されません</em>。
</p>
</li>
<li>
<strong>実行時にユーザーがパーミッションを付与する:</strong> アプリがパーミッションを要求すると、ユーザーにダイアログが表示されます。その後、アプリのコールバック関数を呼び出して、パーミッションが付与されているかどうかを知らせます。
ユーザーがパーミッションを付与する場合、アプリ マニフェストで宣言されたパーミッションの機能領域にあるすべてのパーミッションがアプリに付与されます。
</li>
</ul>
<p>
このパーミッション モデルにより、パーミッションを要求する機能に対するアプリの動作方法が変わります。
このモデルに合わせるために、従う必要のある開発プラクティスの概要を次に示します。
</p>
<ul>
<li>
<strong>常にパーミッションを確認する:</strong> アプリがパーミッションを必要とするアクションを実行する必要があるとき、まずパーミッションが既にあるかどうかを確認する必要があります。
パーミッションがない場合、そのパーミッションを付与するよう要求します。
</li>
<li>
<strong>パーミッションの不足をスムーズに処理する:</strong> アプリに適切なパーミッションが付与されていない場合、エラーが完全に処理される必要があります。
たとえば、追加機能に対してのみパーミッションが必要な場合、アプリはその機能を無効にできます。
アプリが機能するためにパーミッションが必須である場合、アプリはすべての機能を無効にしてパーミッションを付与する必要があることをユーザーに知らせることがあります。
</li>
<div class="figure" style="width:220px" id="fig-perms-screen">
<img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220">
<p class="img-caption">
<strong>図 1.</strong>アプリの [設定] のパーミッション画面。
</p>
</div>
<li>
<strong>パーミッションは取り消し可能:</strong> ユーザーはいつでもアプリのパーミッションを取り消すことができます。
アプリのパーミッションをオフにすると、アプリに通知<em>されません</em>。
アプリは制限されたアクションを実行する前に、必要なパーミッションがあることを確認する必要があります。
</li>
</ul>
<p class="note">
<strong>注:</strong> アプリのターゲットが M Developer Preview の場合、新しいパーミッション モデルを使う<em>必要があります</em>。
</p>
<p>
M Developer Preview のローンチ時点では、すべての Google アプリで新しいパーミッション モデルが完全に実装されているわけではありません。
Google はこれらのアプリを M Developer Preview 中にアップデートして、パーミッションの切り替え設定を完全に実装します。
</p>
<p class="note">
<strong>注:</strong> アプリに独自の API サーフェスがある場合、まず呼び出し側にそのデータへのアクセスに必要なパーミッションがあることを確認しないままパーミッションをプロキシしないでください。
</p>
<h3 id="system-apps">
システムアプリと署名のパーミッション
</h3>
<p>
本来、ユーザーがアプリをインストールするとき、システムはアプリに
{@link android.content.pm.PermissionInfo#PROTECTION_NORMAL
PROTECTION_NORMAL} のみを付与します。ただし、特定の環境では、アプリにより多くのパーミッションが付与されます。
</p>
<ul>
<li>アプリがシステム イメージの一部である場合、そのマニフェストにリストされているすべてのパーミッションが自動的に付与されます。
</li>
<li>アプリが {@link
android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE} に該当するマニフェストでパーミッションを要求し、アプリがこれらのパーミッションを宣言したアプリと同じ証明書で署名される場合、要求しているアプリに対してこれらのパーミッションがインストール時に付与されます。
</li>
</ul>
<p>
どちらの場合でも、ユーザーはシステムの [<strong>設定</strong>] 画面に移動して [<strong>アプリ</strong>] &gt; <i>[app_name]</i> &gt; [<strong>パーミッション</strong>] を選ぶと、いつでもパーミッションを取り消すことができます。アプリは実行時にパーミッションを継続して確認し、必要に応じて要求する必要があります。
</p>
<h3 id="compatibility">
上方互換と下方互換
</h3>
<p>
アプリのターゲットが M Developer Preview 以外の場合、M Preview 端末でも以前のパーミッション モデルを引き続き使います。
ユーザーがアプリをインストールするとき、ユーザーはアプリのマニフェストでリストされているすべてのパーミッションを付与するように要求されます。
</p>
<p class="note">
<strong>注:</strong> M Developer Preview を実行している端末で、ユーザーはアプリの [設定] 画面から従来のアプリを含むすべてのアプリのパーミッションをオフにできます。
従来のアプリに対してパーミッションをオフにすると、適切な機能がサイレント状態で無効になります。
アプリがそのパーミッションを必要とする操作を実行しようとするとき、その操作によって必ずしも例外が発生するとは限りません。
代わりに、空のデータセットを返す、エラーを示す、または予期しない動作を返すことがあります。
たとえば、パーミッションなしでカレンダーを照会すると、メソッドは空のデータセットを返します。
</p>
<p>
M Preview を実行していない端末で新しいパーミッション モデルを使ってアプリをインストールする場合、他のすべてのアプリと同様に扱われ、インストール時に、すべての宣言されたパーミッションを付与するようユーザーに求めます。
</p>
<p class="note">
<strong>注:</strong> Preview リリースの場合、M Preview SDK に SDK の最小バージョンを設定して Preview SDK でコンパイルする必要があります。
つまり、Developer Preview 中は従来のプラットフォームでそのようなアプリをテストできません。
</p>
<h3 id="perms-vs-intents">パーミッションとインテント</h3>
<p>
多くの場合、アプリがタスクを実行するには 2 つの方法から選択できます。
アプリ自体が操作を実行するパーミッションを要求できます。
アプリでインテントを使うようにして、別のアプリがそのタスクを実行するようにすることもできます。
</p>
<p>
たとえば、端末のカメラで写真を撮る機能がアプリに必要だとします。
アプリは <code>android.permission.CAMERA</code> パーミッションをリクエストでき、それによりアプリが直接カメラにアクセスできるようになります。
そのとき、アプリはカメラの API を使ってカメラを制御し、写真を撮ります。
このアプローチにより、アプリが写真のプロセスを完全に制御し、カメラの UI をアプリに組み込むことができます。
</p>
<p>
ただし、そのような制御が不要な場合は、{@link
android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} インテントを使うだけで画像を要求できます。
インテントを開始すると、カメラアプリ(デフォルトのカメラアプリがない場合)を選んでアプリで写真を撮るよう求めるメッセージが表示されます。
カメラアプリはアプリの {@link
android.app.Activity#onActivityResult onActivityResult()} メソッドに写真を返します。
</p>
<p>
同様に、ユーザーの連絡先にアクセスするなどして電話をかける必要がある場合、適切なインテントを作成するか、パーミッションを要求して適切なオブジェクトに直接アクセスできます。
各アプローチにはメリットとデメリットがあります。
</p>
<p>
パーミッションを使う場合:
</p>
<ul>
<li>操作を実行するとき、アプリによってユーザーの操作感が完全に制御されます。
ただし、そのような幅広い制御により、適切な UI を設計する必要があるため、タスクが複雑化します。
</li>
<li>操作を初めて実行するときに、ユーザーに一度だけパーミッションの付与を求めるメッセージが表示されます。
その後、アプリはユーザーからの介入は必要とせずに操作を実行できます。
ただし、ユーザーがパーミッションを付与しない(または後でパーミッションを取り消す)場合、アプリは操作を一切実行できなくなります。
</li>
</ul>
<p>
インテントを使う場合:
</p>
<ul>
<li>操作用に UI を設計する必要はありません。インテントを処理するアプリでは UI が提供されますが、これはユーザーの操作感を制御できないことを意味します。
ユーザーはこれまでに見たことのないアプリと相互操作することになります。
</li>
<li>操作に対してデフォルトのアプリを持たないユーザーの場合、ユーザーにアプリの選択を求めるメッセージが表示されます。ユーザーがデフォルトのハンドラを指定しない場合、操作のたびに別のダイアログで指定する必要があることがあります。
</li>
</ul>
<h2 id="coding">実行時のパーミッションのコード</h2>
<p>
アプリのターゲットが新しい M Developer Preview の場合、新しいパーミッション モデルを使う必要があります。
つまり、マニフェストで必要なパーミッションを宣言する他に、実行時にパーミッションがあることを確認し、まだパーミッションがない場合にはパーミッションを要求します。
</p>
<h3 id="enabling">
新しいパーミッション モデルを有効にする
</h3>
<p>
新しい M Developer Preview パーミッション モデルを有効にするには、アプリの <code>targetSdkVersion</code> 属性を <code>"MNC"</code> に、<code>compileSdkVersion</code> を <code>"android-MNC"</code> に設定します。
このように設定することで、新しいパーミッション機能すべてが有効になります。
</p>
<p>
Preview リリースの場合、<code>minSdkVersion</code> を <code>"MNC"</code> に設定して Preview SDK でコンパイルする必要があります。
</p>
<h3 id="m-only-perm">
M Preview のみに対するパーミッションの設計
</h3>
<p>
アプリ マニフェストで新しい <code>&lt;uses-permission-sdk-m&gt;</code> 要素を使って、M Developer Preview のみで必要なパーミッションを表示できます。
このようにしてパーミッションを宣言すると、アプリを以前の端末にインストールする場合はユーザーにメッセージが表示されないか、アプリにパーミッションが付与されません。<code>&lt;uses-permission-sdk-m&gt;</code> 要素を使うと、新しいパーミッションを追加してインストールをアップデートするときにパーミッションの付与を強制せずにアプリのバージョンがアップデートされます。
</p>
<p>
M Developer Preview を使ってアプリが端末で実行されている場合、<code>&lt;uses-permission-sdk-m&gt;</code> は <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code> と同じように動作します。
アプリをインストールするとき、パーミッションの付与を求めるメッセージは表示されず、アプリは必要なときにパーミッションを要求します。
</p>
<h3 id="prompting">
パーミッションについてのダイアログを表示する
</h3>
<p>
アプリで新しい M Developer Preview パーミッション モデルが使われている場合、M Preview を実行している端末でアプリを初めて起動するとき、すべての権限を付与する必要はありません。
その代わりに、アプリは必要なときにパーミッションを要求します。
アプリがパーミッションを要求すると、ユーザーにダイアログが表示されます。
</p>
<p>
SDK 22 以降がインストールされた端末でアプリを実行する場合、アプリでは以前のパーミッション モデルが使われます。
ユーザーがアプリをインストールすると、アプリがそのマニフェストで要求するすべてのパーミッションの付与を求めるメッセージが表示されます。ただし、<code>&lt;uses-permission-sdk-m&gt;</code> というラベルの付いたパーミッションは例外です。
</p>
<h4 id="check-platform">アプリが実行されているプラットフォームを確認する</h4>
<p>
このパーミッション モデルは、M Developer Preview を実行している端末でのみサポートされます。
これらのメソッドのいずれかを呼び出す前に、アプリは {@link android.os.Build.VERSION#CODENAME
Build.VERSION.CODENAME} の値を確認してどのプラットフォーム上で実行されているのかを確認する必要があります。
端末で M Developer Preview が実行されている場合、{@link android.os.Build.VERSION#CODENAME CODENAME} は <code>"MNC"</code> です。
</p>
<h4 id="check-for-permission">アプリに必要なパーミッションがあるかどうかを確認する</h4>
<p>ユーザーがパーミッションを要求する動作を行うと、アプリは現在この操作を実行するためのパーミッションがあるかどうかを確認します。
確認するために、アプリは <code>Context.checkSelfPermission(<i>permission_name</i>)</code> を呼び出します。ユーザーが既にパーミッションを付与していることをアプリが認識している場合でも、ユーザーはいつでもアプリのパーミッションを取り消すことができるため、この確認が行われます。
たとえば、ユーザーがアプリを使って写真を撮る場合、アプリは <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code> を呼び出します。
</p>
<p class="table-caption" id="permission-groups">
<strong>表 1.</strong>パーミッションとパーミッション グループ。</p>
<table>
<tr>
<th scope="col">パーミッション グループ</th>
<th scope="col">パーミッション</th>
</tr>
<tr>
<td><code>android.permission-group.CALENDAR</code></td>
<td>
<ul>
<li>
<code>android.permission.READ_CALENDAR</code>
</li>
</ul>
<ul>
<li>
<code>android.permission.WRITE_CALENDAR</code>
</li>
</ul>
</td>
</tr>
<tr>
<td><code>android.permission-group.CAMERA</code></td>
<td>
<ul>
<li>
<code>android.permission.CAMERA</code>
</li>
</ul>
</td>
</tr>
<tr>
<td><code>android.permission-group.CONTACTS</code></td>
<td>
<ul>
<li>
<code>android.permission.READ_CONTACTS</code>
</li>
<li>
<code>android.permission.WRITE_CONTACTS</code>
</li>
<li>
<code>android.permission.READ_PROFILE</code>
</li>
<li>
<code>android.permission.WRITE_PROFILE</code>
</li>
</ul>
</td>
</tr>
<tr>
<td><code>android.permission-group.LOCATION</code></td>
<td>
<ul>
<li>
<code>android.permission.ACCESS_FINE_LOCATION</code>
</li>
<li>
<code>android.permission.ACCESS_COARSE_LOCATION</code>
</li>
</ul>
</td>
</tr>
<tr>
<td><code>android.permission-group.MICROPHONE</code></td>
<td>
<ul>
<li>
<code>android.permission.RECORD_AUDIO</code>
</li>
</ul>
</td>
</tr>
<tr>
<td><code>android.permission-group.PHONE</code></td>
<td>
<ul>
<li>
<code>android.permission.READ_PHONE_STATE</code>
</li>
<li>
<code>android.permission.CALL_PHONE</code>
</li>
<li>
<code>android.permission.READ_CALL_LOG</code>
</li>
<li>
<code>android.permission.WRITE_CALL_LOG</code>
</li>
<li>
<code>com.android.voicemail.permission.ADD_VOICEMAIL</code>
</li>
<li>
<code>android.permission.USE_SIP</code>
</li>
<li>
<code>android.permission.PROCESS_OUTGOING_CALLS</code>
</li>
</ul>
</td>
</tr>
<tr>
<td><code>android.permission-group.SENSORS</code></td>
<td>
<ul>
<li>
<code>android.permission.BODY_SENSORS</code>
</li>
</ul>
<ul>
<li>
<code>android.permission.USE_FINGERPRINT</code>
</li>
</ul>
</td>
</tr>
<tr>
<td><code>android.permission-group.SMS</code></td>
<td>
<ul>
<li>
<code>android.permission.SEND_SMS</code>
</li>
<li>
<code>android.permission.RECEIVE_SMS</code>
</li>
<li>
<code>android.permission.READ_SMS</code>
</li>
<li>
<code>android.permission.RECEIVE_WAP_PUSH</code>
</li>
<li>
<code>android.permission.RECEIVE_MMS</code>
</li>
<li>
<code>android.permission.READ_CELL_BROADCASTS</code>
</li>
</ul>
</td>
</tr>
</table>
<h4 id="request-permissions">必要に応じてパーミッションを要求する</h4>
<p>アプリに必要なパーミッションがない場合、アプリは <code>Activity.requestPermissions(String[], int)</code> メソッドを呼び出して適切なパーミッションを要求します。
アプリは必要なパーミッションと整数の「要求コード」を渡します。
このメソッドは非同期に機能します。このメソッドはすぐに返され、ユーザーがダイアログ ボックスに応答した後、システムはその結果と一緒にアプリのコールバック メソッドを呼び出し、アプリが <code>requestPermissions()</code> に渡すのと同じ「要求コード」を渡します。
</p>
<p>次のコードは、ユーザーの連絡先を読み込むパーミッションがアプリにあることを確認し、必要に応じてパーミッションを要求します。
</p>
<pre>
if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant
return;
}
</pre>
<h4 id="handle-response">パーミッションの要求への応答を処理する</h4>
<p>
アプリがパーミッションを要求すると、システムによってダイアログ ボックスが表示されます。
ユーザーが応答すると、システムはアプリの <code>Activity.onRequestPermissionsResult(int, String[], int[])</code> を呼び出し、ユーザーの応答を渡します。
アプリはそのメソッドをオーバーライドする必要があります。コールバックには開発者が <code>requestPermissions()</code> に渡したのと同じ要求コードが渡されます。
たとえばアプリが <code>READ_CONTACTS</code> アクセスを要求する場合、次のコールバック メソッドが含まれる可能性があります。
</p>
<pre>
&#64;Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! do the
// calendar task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'switch' lines to check for other
// permissions this app might request
}
}
</pre>
<p>ユーザーがパーミッションを付与すると、システムは、機能領域のアプリ マニフェストがリストするすべてのパーミッションを付与します。
ユーザーが要求を拒否する場合は、適切なアクションを取ってください。
たとえば、このパーミッションに応じて、すべてのメニュー アクションを無効にできます。
</li>
</p>
<p>
ユーザーにパーミッションの付与を確認するとき、ユーザーにそのパーミッションについて再度確認しないようにするオプションがあります。
この場合、アプリが <code>requestPermissions()</code> を使ってパーミッションを確認すると、システムはその要求をすぐに拒否します。
この場合、システムはユーザーが要求を再度明示的に拒否する場合と同様に <code>onRequestPermissionsResult()</code> を呼び出します。
このため、アプリではユーザーとの直接的なやり取りが発生することが想定されません。
</p>
<h2 id="testing">実行時のパーミッションをテストする</h2>
<p>
アプリのターゲットが M Developer Preview の場合、パーミッションが正しく処理されることをテストする必要があります。
アプリ起動時に特定のパーミッションがアプリにあることは想定できません。
アプリが初めて起動されるとき、パーミッションがない可能性が高く、ユーザーはいつでもパーミッションを取り消すまたは復元できます。
</p>
<p>
アプリがすべてのパーミッションの状況下で確実に正しく動作することをテストしてください。
M Preview SDK とともに、新しい <a href="{@docRoot}tools/help/adb.html">Android デバッグ ブリッジ(adb)</a>コマンドが導入され、試す必要のあるあらゆるパーミッション設定でアプリをテストできます。
</p>
<h3>
新しい adb コマンドとオプション
</h3>
<p>
M Preview SDK Platform-tools では、アプリがパーミッションをどう処理するかをテストするための、いくつかの新しいコマンドが導入されました
</p>
<h4>
パーミッション付きでインストールする
</h4>
<p>
<a href="{@docRoot}tools/help/adb.html#move"><code>adb
install</code></a> コマンドの新しい <code>-g</code> オプションを使ってアプリをインストールし、そのマニフェストにリストされるすべてのパーミッションを付与できます。
</p>
<pre class="no-pretty-print">
$ adb install -g &lt;path_to_apk&gt;
</pre>
<h4>
パーミッションの付与と取り消し
</h4>
<p>
新しい ADB <a href="{@docRoot}tools/help/adb.html#pm">Package Manager(pm)</a>コマンドを使って、インストールされているアプリにパーミッションを付与したり取り消したりできます。この機能は自動化されたテストに役立ちます。
</p>
<p>
パーミッションを付与するには、Package Manager の <code>grant</code> コマンドを使います。
</p>
<pre class="no-pretty-print">
$ adb pm grant &lt;package_name&gt; &lt;permission_name&gt;
</pre>
<p>
たとえば、com.example.myapp パッケージ パーミッションを付与してオーディオを録音するには、このコマンドを使います。
</p>
<pre class="no-pretty-print">
$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
</pre>
<p>
パーミッションを取り消すには、Package Manager の <code>revoke</code> コマンドを使います。
</p>
<pre class="no-pretty-print">
$ adb pm revoke &lt;package_name&gt; &lt;permission_name&gt;
</pre>
<h2 id="best-practices">ベスト プラクティス</h2>
<p>
新しいパーミッション モデルにより、ユーザーはよりスムーズな操作感を得られ、アプリを簡単にインストールできるようになり、アプリが実行している内容に満足します。
新しいモデルを最大限に活用するために、次のベスト プラクティスをお勧めします。
</p>
<h3 id="bp-what-you-need">必要なパーミッションのみを要求する</h3>
<p>
パーミッションを要求するたびに、ユーザーに決定するよう強制します。
ユーザーが要求を却下すると、アプリの機能が低下します。
これらの要求回数は最小限にしてください。
</p>
<p>
たとえば、アプリがパーミッションを要求する代わりに、<a href="{@docRoot}guide/components/intents-filters.html">インテント</a>を使って必要な機能を取得できる場合がよくあります。
アプリが携帯電話のカメラで写真を撮る必要がある場合、そのアプリでは {@link
android.provider.MediaStore#ACTION_IMAGE_CAPTURE
MediaStore.ACTION_IMAGE_CAPTURE} インテントを使用できます。
アプリがインテントを実行すると、写真を撮るためのインストール済みのカメラアプリを選ぶようユーザーに促します。
</p>
<h3 id="bp-dont-overwhelm">
ユーザーを疲れさせない
</h3>
<p>
ユーザーにパーミッションをたくさん要求すると、ユーザーを疲れさせてしまい、アプリが終了される原因になります。代わりに、ユーザーには必要なパーミッションのみを要求してください。
</p>
<p>
アプリ対して 1 つ以上のパーミッションが必須である場合もあります。その場合は、アプリの起動後すぐに、すべてのパーミッションを要求することが合理的である場合があります。
たとえば、カメラアプリを作成する場合、アプリは端末のカメラにアクセスする必要があります。
アプリを初めて起動するときにカメラの使用についてのパーミッションを求められても驚かないはずです。
ただし、同じアプリにユーザーの連絡先と写真を共有する機能もある場合は、最初の起動時にパーミッションを要求<em>しない</em>方が無難です。
その代わりに、ユーザーが「共有」機能を使うまで待ち、そのときにパーミッションを要求します。
</p>
<p>
アプリにチュートリアルが含まれる場合は、チュートリアルのシーケンスの最後で、アプリに必須のパーミッションを要求する方が合理的です。
</p>
<h3 id="bp-explain">
パーミッションが必要な理由を説明する
</h3>
<p>
<code>requestPermissions()</code> を呼び出すとき、システムによって表示されるパーミッション ダイアログにはアプリが必要としているパーミッションは表示されますが、理由は表示されません。
これによりユーザーが困惑する場合もあります。
<code>requestPermissions()</code> を呼び出す前に、アプリがパーミッションを必要としている理由をユーザーに説明するのはよい方法です。
</p>
<p>
たとえば、カメラアプリでは、位置情報サービスを使って写真に位置情報タグを付けられるようにする場合があります。
通常のユーザーは、写真に位置情報が含まれる場合があることを認識していない可能性があり、なぜカメラアプリで位置情報が必要なのか困惑する可能性があります。
この場合、アプリが <code>requestPermissions()</code> を呼び出す<em>前</em>に、この機能についてユーザーに知らせることをお勧めします。
</p>
<p>
その方法として、これらの要求をアプリのチュートリアルに組み込むこともできます。チュートリアルでは、アプリの各機能を順番に表示できるので、必要なパーミッションを説明できます。
たとえば、カメラアプリのチュートリアルでは、「連絡先と写真を共有する」機能について説明し、ユーザーの連絡先を参照するためにアプリにパーミッションが必要であることをユーザーに知らせることができます。
その後、アプリは <code>requestPermissions()</code> を呼び出して、ユーザーにそのアクセスを求めることができます。
もちろん、すべてのユーザーがチュートリアルに従うわけではないため、アプリの通常操作中にパーミッションを確認して要求することも必要です。
</p>