Google I/O 2015 新しいパミッションモデルの超訳
Google I/O 2015終わりました。今年は車関係で大きな発表をするのかなと思ってたんですが、それも特になく、新デバイスもないし、TVもGlassもWEARもARAもChromBookもNexusQも特に大きな発表はなく、しかもリリースされたSDKは、API Levelも付いていないDeveloper Previewだしで、今年は盛り上がるネタがなかったねーという感じがネットで蔓延しているわけですが、新しいパミッションモデル導入するよという、タオ的には、がっつり調べなきゃーネタがでてきました。
新しい仕様がくると、セキュリティに関する事項をしらべて、Tao RiskFinderに機能を随時組み込むという作業を、この2,3年ずっと行っているのですが、今回のAndroid M Developer Previewに関していてば、調べても正式リリースでは仕様変更するかもしれないし、ここは絶対変わるよなー、えーこれマジ?なんてのが、出てきています。正直中途半端に出すのはやめて、ガツンと一度に来てもらいです。
ということで、新しいパミッションモデルについての説明ページ、Android M Developer Preview Permissionを、翻訳しましたので、興味のある方はご覧ください。なお、そのまま翻訳するとわけわからないので、かなり超訳した部分がありますので、ご了承ください。
Permission翻訳
http://developer.android.com/preview/features/runtime-permissions.html
M開発者プレビューには、新しいアプリパミッションモデルが導入され、ユーザがアプリをインストールやアップデートする操作がよりスムーズになっています。新しいパミッションモデルをサポートしているアプリケーションがM開発者プレビュー上で動作している時、アプリのインストール、アップデート時にユーザはパミッションの許可を与える必要はありません。そのかわり、アプリケーションはパミッションが必要な時にリクエストを行います。するとシステムはパミッションの許可を求めるダイアログをユーザに表示します。
アプリケーションが新しいパミッションモデルをサポートしていても、古いバージョンのアンドロイド端末にインストールして動作させることができます。この場合、古いパミッションモデルと同じ動作をします。
OverView
M開発者プレビューでは、新しいアプリパミッションモデルが導入されています。ここでは、この新しいモデルの鍵となる要素についての概要を以下に記載します。
- Declaring Permissions: (パミッションの宣言)
- アプリケーションは以前のAndroidプラットフォームと同様に、マニュフェストに必要な全ての権限を宣言します。
- Permission Groups: (パミッショングループ)
- パミッションは、それらの機能に基づいて、パミッショングループに分けられています。例えばCONTACTSパミッショングループには、ユーザの電話帳や、プロファイル情報を読み書きするためのパミッションが含まれています。
- Limited Permissions Granted at Install Time:(インストール時に許可される一部のパミッション)
- ユーザがアプリケーションをインストールもしくはアップデートした時、システムは、アプリケーションが要求する全てのPROTECTION_NORMALのパミッション権限を与えます。例えば、アラームクロックとインターネットパミッションはPROTECTION_NORMALです、これらはインストール時に自動的に付与されます。
- 「System apps and signature permissions」ので説明しているように、システムはアプリケーションのsignatureとsystemパミッション権限もインストール時に付与します。インストール時、ユーザに対してパミッションの許可を求めるような表示は一切行われません。
- User Grants Permissions at Run-Time:(ランタイム時のユーザによる許可)
- アプリケーションがパミッションをリクエストするとき、システムはユーザにダイアログを表示し、その後ユーザがパミッションを許可したどうかをアプリケーションに通知するコールバックファンクションを呼び出します。ユーザが許可を与えた場合、アプリケーションはマニュフェストで宣言されたそのパミッションの機能領域について、すべての権限を与えられます。
- (訳注:。パミッショングループには複数のパミッションが含まれるので、そのパミッションの固まりを機能領域と言っています。パミッショングループ単位での許可を与えても、Manifestに記載されているパミッション以上の権限をアプリケーションが取得する事はありません)
パミッションモデルの変更により、パミッション許可を必要とする機能の動作も変更になりました。
アプリケーションを開発する際、このモデルに適用させるために従うべきことの要約は以下の通りです。
- Always Check for Permissions:(常にパミッションをチェックする)
- アプリケーションはパミッションを必要とするアクションを実行する時は、最初にそのパミッションを既に取得しているかを確認する必要があります。パミッションが付与されていない場合は、そのパミッションを取得する要求をします。
- Handle Lack of Permissions Gracefully:(パミッション不足時の動作を綺麗に)
- アプリケーションが適切なパミッションを取得していない時(ユーザによって許可を与えられなかった時)、問題を綺麗に解決すべきです。例えば、アプリケーションに新たに追加された機能にパミッションが必要で、それがユーザに許可されなかった時、アプリケーションはその機能を無効にします。アプリケーションの機能に不可欠なパミッションの時は、全ての機能を無効にしてユーザにパミッションの取得が必要な事を表示します。
- Permission are Revocable:(パミッションは取り消し可能)
- ユーザはいつでも、与えたパミッションを取り消す事ができます。ユーザがアプリケーションのパミッションをオフにした場合、アプリケーションは通知を受け取りません。もう一度、許可が必要なアクションを実行する前に、パミッションを取得していることを確認する必要があります。
Note: アプリケーションのターゲットがM開発者プレビューの場合は、新しいパミッションモデルを使用する必要があります。
M開発者プレビューのローンチ時点で、Googleのアプリケーション全てが、完全に新しいアクセス許可モデルを実装しているわけではありません。GoogleはM開発者向けプレビューの間に、これらのアプリケーションを更新していきます。
Note:もしあなたのアプリケーションがAPIを提供している場合、呼び出し側のアプリケーションがデータへ初めてアクセスする時点で必要なパミッションを持っている場合を除いて、データへのアクセスを許可してはいけません。
System apps and signature permissions (システムアプリケーションとSignatureパミッション)
通常、ユーザがアプリケーションをインストールした時、システムは、アプリケーションのマニフェストに記載されたPROTECTION_NORMALのプロテクションレベルを持つ権限のみ自動的に許可を与えます。しかしながら、いくつかの状況下でシステムはアプリケーションにもっと多くの権限を与えます。
- アプリケーションがシステムイメージの一部である場合、マニュフェストに記載されている全ての権限が自動的に付与されます。
- アプリケーションが、マニフェスト上で、プロテクションレベルPOTECTION_SIGNATUREのパミッションを要求し、そのパミッションを宣言した既にインストールされているアプリケーションと同じ証明書で署名されていた時、システムはそれらのパミッションを自動的に付与します。
両方のケースで、ユーザはシステムの設定画面に移動し、Apps > app_name > Pemissionを選択してアクセス許可を取り消す事ができます。従って、アプリケーションは実行時に権限を持っているかどうかチェックし、必要に応じて権限を要求するようにすべきです。
(訳注:プレインストールアプリケーションも設定画面で権限を使用できなくできるのは良い点)
Forwards and backwards compatibility (下位互換、上位互換)
アプリケーションがM開発者向けプレビューをターゲットとしていない時、Mプレビューデバイス上であっても、アプリケーションは古いパミッションモデルとして動作します。従って、ユーザがアプリケーションをインストールした時、システムはマニュフェストにリストされた全てのパミッションの許可を与えるかユーザに問い合わせをします。
Note: M開発者向けプレビューが動作しているデバイス上で、ユーザはシステムの設定画面でアプリケーションの権限をオフにする事ができます。(レガシーアプリケーションも含む)。レガシーアプリケーションのパミッションをユーザがオフにした場合、システムは適切に機能を使用不能にします。アプリケーションが権限を必要とする操作を実行した時、Exceptionは発生しません。その代り、空のデータ、エラー、その他予期しない動作をする事があります。例えばカレンダーパミッションなしにカレンダーデータを要求した時システムは空のデータセットを返します。
訳注:レガシーパミッションモデルのアプリを設定画面から権限を変更しようとすると、「このアプリは古いタイプなので権限を不許可にすると問題が発生するかも、」といったダイアログが表示されます。
訳注:レガシーアプリケーションとは、新しいパミッションモデルを採用していない、今までのアプリケーションを指す。
M開発者向けプレビューではないデバイスに、新しいパミッションモデルのアプリケーションをインストールした場合、システムは、他のアプリケーションと同じように扱います。:システムはインストール時に全ての宣言された権限を付与するようにユーザに確認します。
Note: プレビューリリースでは、minimum SDK Versionに、M preview SDKをセットし、プレビューSDKでコンパイルしなければいけません。これは、開発者プレビュー時点では、古いプラットフォーム上でアプリケーションをテストできない事を意味します。
訳注:M開発者プレビュー自体、位置づけが中途半端であり、後半に出てくる<uses-permission-sdk-m>が正式SDKになった時どのような扱いになるか推測するに色々と疑問点も多い、現時点では、下位互換や上位互換はあまり考えない方が良いと思われる。
Permissions versus Intents (パミッション VS インテント)
多くの場合、あなたのアプリケーションでタスクを実行するために二つの方法を選択することができます。一つ目はパミッションの許可を求めてタスクを自分自身で実行する事、もう一つはインテントを使用してタスクを他のアプリケーションに実行してもらう事です。
例えば、アプリケーションがカメラで写真を取る必要があるとします。あなたのアプリケーションは、カメラに直接アクセスするためにandroid.permission.CAMERAパミッションを要求することができ、あなたのアプリケーションはカメラAPIを用いてカメラをコントロールし写真を撮る事ができます。このアプローチは写真関連の処理の完全な制御を与え、あなたのアプリケーションはカメラUIを組み込むことになります。
一方、このような完全なコントロールを必要としない場合は、写真を取得するために、ACTION_IMAGE_CAPTUREインテントを用いる事ができます。インテントを投げると、カメラアプリ選択画面で、ユーザが使用するカメラアプリを選択します(既にデフォルトのカメラアプリが選択されていない場合)、そして呼び出されたアプリケーションは写真を取ります。カメラアプリは写真をonActivityResult()メソッドで返します。
同じように、電話をかける必要がある時、ユーザの電話帳をアクセスする必要がある時、というように適切なインテントを作成するか、直接適切なオブジェクトにアクセスするためにパミッションを要求するかを選択できます。各アプローチには長所と短所があります。
パミッションを用いる場合
- アプリケーションは機能をフルコントロールでき、ユーザエキスペリエンスを完全に制御できます。しかしながら、あなたは適切なUIを設計する必要があり、このような幅広い制御は、プログラムを複雑にします。
- 最初に機能を実行する時、ユーザに実行の許可を一度与えてもらう必要があります。その後は、ユーザに特別な追加の操作リクエストを必要することなく実行できます。しかしながら、ユーザがパミッションを与えたくない時(また、後から権限を削除した時)あなたのアプリケーションは実行したい機能を全て実行できなくなります。
インテントを用いる場合
- UIデザインを設計する必要はありません。インテントを受け取るアプリケーションがUIを提供します。しかしながら、これはユーザエキスペリエンスをコントロールできない事を表します。ユーザはあなたが知らないアプリケーションを選択して操作します。
- ユーザが、インテントを受け取るデフォルトのアプリケーションを設定していない場合、システムはアプリケーション選択ダイアログを開きます。この時ユーザが「デフォルトにする」を指定しない場合、同じ機能を実行する時毎回、アプリケーション選択ダイアログが出現します(訳注:面倒という意味)
訳者注:パミッションを使用するか、インテントを使用するかの話は、特に新しいパミッションモデルとは関係なく従来からある話です。興味がある方は以下を参照してください。
Coding for Runtime Permissions (ランタイムパミッションの記述)
M開発者プレビューをターゲットとするならば、新しいパミッションモデルを使用する必要があります。これは、マニフェストに必要なアクセス許可を宣言する事に加え、実行時に権限を持っているか確認し、持っていない場合はアクセス権限を要求しなければならない事を意味します。
Enabling the new permissions model (新しいパミッションモデルの有効化)
M開発者プレビューパミッションモデルを有効にするために、以下の記載をします。
targetSdkVersionに”MNC”
compileSdkVersionに”android-MNC”
プレビューリリースでは、minSdkVersion=”MNC”とし、プレビューSDKでコンパイルします。
Designating a permission for the M Preview only (Mプレビュー上だけでのパミッションの使用)
新しい<uses-permission-sdk-m>要素をマニフェストファイルに記載する事で、M開発者プレビュー上のみで必要なパミッションとして使用する事ができます。パミッションの使用権限をこのように宣言すると、アプリケーションは古いデバイスにインストールされるとき、システムはユーザに許可を求めることなく、権限も取得することはありません。(訳注:認識できない要素なので、存在しない物として扱われます)。<uses-permission-sdk-m>要素を使用する事で、新しいパミッションを追加するアプリケーションのバージョンアップ時に、ユーザに許可を求める必要がなくなります。
(訳注:権限追加があると、アプリケーションの自動更新をユーザの許可なくできるので(ユーザが自動更新するにしている場合)便利だという事だと思うが、<uses-permission-sdk-m>という要素が正式採用される事が前提で書いてあるようで何かおかしい気がする。)
アプリケーションが、Mデベロッパープイビュー上で実行されるとき、<uses-permission-sdk-m>は、<uses-permission>と同じふるまいをします。システムはアプリケーションをインストールする時に、ユーザにパミッションの許可を要求しません。アプリケーションは必要な時にパミッションの権限を要求します。
Prompting for permissions (パミッションプロンプト)
アプリケーションがM開発者プレビューのパミッションモデルを使用している場合、Mプレビューデバイス上でアプリケーションを初めて実行した時点では、アプリケーションが使用する全てのパミッションがユーザに要求されるわけではありません。そのかわりアプリケーションは権限が必要になった時にパミッションを要求します。アプリケーションがパミッションを要求する時、システムはユーザに許可ダイアログを表示します。
アプリケーションがSDK22以下(訳注:Mより下)のデバイス上で動作する場合は、アプリケーションは古い(従来の)パミッションモデルで動作します。ユーザがアプリケーションをインストールした時に、マニュフェストに記載される全てのパミッションの許可をユーザに求めます。<uses-permission-sdk-m>は除く
Check what platform the app is running on (Mデベロッパーデバイスかの確認方法)
この新しいパミッションモデルは、M開発者プレビューデバイスで動作する時のみサポートされています。これらのメソッドを呼ぶ前に、アプリケーションはBuild.VERSION.CODENAMEの値をチェックしてどのようなプラットフォームで実行されているのかを確認する必要があります。M開発者プレビューデバイスで実行している場合は、CODENAMEは、”MNC”となります。
Check if the app has the needed permission (必要なパミッションを取得しているかの確認法)
ユーザがアクセス権限を必要とする何かをしようとする時、アプリケーションは現在その操作を実行する権限を持っているかを確認します。確認をするには、Context.checkSelfPermission(permission_name)を呼び出します。ユーザが既に権限を付与しているとわかっている場合でも、ユーザが任意の時点でアプリケーションの許可を取り消す事ができますので、チェックをする必要があります(訳注:アプリケーション実行時にタスクを切り替えて、システム設定から権限の取り消しができる)例えばユーザが写真を撮るためにアプリケーションを使用したい時は、Contenxt.checkSelfPermission(Manifest.permission,CAMERA)のように呼び出します。
Permission Group | Permissions |
---|---|
android.permission-group.CALENDAR |
|
android.permission-group.CAMERA |
|
android.permission-group.CONTACTS |
|
android.permission-group.LOCATION |
|
android.permission-group.MICROPHONE |
|
android.permission-group.PHONE |
|
android.permission-group.SENSORS |
|
android.permission-group.SMS |
|
訳注)なんでここの場所に、グループとパミッションの対応表が出てきたのか、ちょっと謎
Request Permission if necessary (必要時のパミッション要求)
アプリケーションケーションが必要な権限を持っていない場合は、Activity.requesrtPermission(String[].int)メソッドを用いて権限を要求します。(複数のパミッションを同時に指定する事も可能)第一引数には、パミッションもしくは複数のパミッションを指定し、第二引数には、integer型の「リクエストコード」(訳注:リクエストコードはプログラム内でユニークになる値を使用します)を指定します。このメソッドは非同期です。非同期なのですぐにメソッドは返ってきます。そして、ユーザがダイアログボックスで許可、不許可の選択をした後、選択された値と、requestPermissions()で指定した「リクエストコード」と共にコールバックメソッドが呼ばれます。
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;}
Handle the permission request response (パミッション要求のレスポンス処理)
アプリケーションがパミッションを要求した時、システムはユーザにダイアログボックスを表示します。ユーザが応答すると、システムは、アプリケーションのActivity.onRequestPermissionResult(int,String[],int[])を呼び出し、そのパラメータにユーザのレスポンスを含めます。アプリケーションはこのメソッドをオーバーライドする必要があります。コールバックファンクションは、requestPermissions()に指定したものと同じリクエストコードが渡されます。例えばアプリケーションがREAD_CONTACTSパミッションを要求する時、以下のようなコールバックメソッドを持っている必要があります。
@Overridepublic 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 }}
ユーザが許可を与える場合、システムは機能エリアの権限(アプリケーションマニュフェストに書かれている物のみ)を与えます。ユーザが許可をしなかった時、適切に処理をする必要があります。例えばそのパミッションに依存する全てのメニューアクションを無効にします。
システムがユーザに対してアプリケーションに権限を付与するかどうか確認する際に、ユーザはオプションとして、システムに再問合わせをしないようにすることを指定できます。この時、アプリケーションがrequestPermissions()を使用してパミッションの問い合わせをした時、システムは直ぐに要求を拒否します。(訳注:許可をした場合は再問合わせを行わないので、ユーザが問い合わせを行わない事を指定した時は拒否を指定した時のみとなる)この場合システムは、ユーザが明示的に再度リクエストを拒否したのと同じようにonRequestPermissionResult()を呼び出ます。このため、アプリケーションは、ユーザが直接操作をしたかを推測する事はできません。
訳注:再問合わせしないを元に戻すときは、システムのセッティングから行う
Testing Runtime Permissions (実行時パミッションのテスト)
アプリケーションのターゲットがM開発者プレビューの時、適切なアクセス許可を処理しているかをテストする必要があります。アプリケーションの実行中、アプリケーションは自分が特定のアクセス権限を持っていると仮定する事はできません。アプリケーションが初めて起動された時、権限を持っていない可能性があり、また、ユーザはいつでも権限を取り消したり復元したりすることができるからです。
あらゆるパミッション状況下で適切に動作するかをテストする必要があります。MプレビューSDKで提供された新しい、Android Debug Bridge(adb)コマンドは、必要とする全てのアクセス権限のテストを可能にします。
New adb commands and options (新しいADBコマンドとオプション)
MプレビューSDKプラットフォームツールは、アプリケーションがアクセス許可をどのように処理するかをテストできるように、いくつかの新しいコマンドを提供しています。
Install with permissions (インストール時に権限を許可)
Adb install コマンドの新しい –g オプションを使用して、マニフェストに記載された全てのパミッションの許可をインストール時に与える事ができます。
$ adb install -g <path_to_apk>
Grant and revoke permissions (権限の許可と不許可)
新しいADB package manager(pm)コマンドで、既にインストールされているアプリケーションのパミッションの許可や不許可を指定する事ができます。この機能は自動テストの時に便利です。
パミッションを付与するには、パッケージマネージャーのgrantコマンドを使用します。
$ adb pm grant <package_name> <permission_name>
例えば、com.example.myappパッケージにRECORD_AUDIOパミッションを付与する時は、以下のコマンドを使います。
$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
許可を取り消すには、パッケージマネージャーのrevokeコマンドを使います。
$ adb pm revoke <package_name> <permission_name>
Best Practices (ベストプラクティス)
新しいパミッションの許可モデルは、ユーザにスムーズな体感を提供するとともに、アプリケーションのインストール作業を簡単にし、また、アプリケーションが何をしているのかということについて安心できるようにします私たちは、新しいモデルの利点を最大限に活用するために以下のベストプラクティスをお勧めします。
Only ask for permissions you need (必要なパミッションだけを要求する)
権限の許可を求めるたびに、ユーザにどうするのか判断することを強制することになります。ユーザが要求を拒否した時、アプリケーション機能性は下がります。権限の許可の要求をする回数を最小限に抑える必要があります。
回数をすくなくするには、例えば、かなりのケースで、パミッションを要求する代わりにインテントを使用する事ができます。もしカメラで写真を撮る必要がある場合、MediaStore.ACTION_IMAGE_CAPTUREインテントを使う事が出来ます。インテントを使用した場合システムは、写真を撮るために既にインストールされたカメラアプリを選択する画面を開きます。
Don’t overwhelm the user (ユーザを圧倒しない)
ユーザに対して沢山のパミッションの許可を一度に求めた場合、ユーザは圧倒されてアプリケーションを終了してしまうかもしれません。一度にではなく、パミッションが必要な時に要求すべきです。
いくつかのケースでは、一つ以上のパミッションがアプリケーションに必要不可欠であるかもしれません。この場合には、アプリケーションが初めて起動された時にすぐに全てのパミッションの許可を得るようにすることでユーザの理解を得られます。例えば、写真撮影アプリを作成した場合、アプリケーションはカメラデバイスへのアクセスが必要です。ユーザがアプリケーションを最初に起動した時、カメラパミッションの許可を尋ねられても驚きません。しかし、同じアプリケーションで、ユーザの連絡先と、写真を共有する機能を持っていた場合は、最初の起動時にその許可を求めるべきではありません。ユーザが「共有」機能を使用するまで、許可を求めないようにします。
もしアプリケーションがチュートリアルを提供している場合、チュートリアルの最後に、パミッション(起動時に取得すべきアプリケーションの本質的な機能のためのパミッション)の権限を要求するのも自然でしょう。
Explain why you need permissions (パミッションが何故必要かの説明)
requestPermissions()を呼び出したときシステムによりパミッションダイアログが表示されますが、どのパミッションが必要かはわかりますが、何故必要なのかはユーザにはわかりません。これはユーザを困惑させる場合があります。良い解決策は、requestPermission()を呼び出す前に何故そのパミッションが必要なのかを説明する事です。
例えば、写真撮影アプリは位置情報サービスを使用して写真に位置情報を付加することがあります。一般的なユーザは、写真が位置情報を含むことができる事を理解していない可能性があり、何故写真アプリが位置情報を知りたいかわからず困惑するでしょう。良い解決方法は、requestPermissions()を呼び出す前にこの機能についてユーザに通知する事です。
ユーザに通知する一つの方法は、チュートリアルに含めてしまう事です。チュートリアルでは、順番にアプリケーションの機能を説明でき、パミッションが何故必要かを説明する事ができます。例えば写真アプリのチュートリアルでは、「写真を連絡先に共有」のデモをすることができ。連絡先を参照するために権限が必要な事を知らせることができます。アプリケーションはrequestPermissions()メソッドを呼びアクセス許可をユーザに依頼します。もちろん、全てのユーザがチュートリアルを見てくれるわけではないので、やはりアプリケーションは通常動作中にパミッションの権限のチェックし、要求する必要があります。
以上で終わりです。
お疲れ様でした。
画面キャプチャーとか、図とか、殆どなく、非常に読みにくいのですが、それは、翻訳前のページがこのように文字だらけだからです。私のせいではありません。
この文章を読んだだけではいまいち理解できない部分がありますので、そのあたりは検証をくわえて、続編で説明してけたらと思っております。
コメント
コメントを投稿