APP権限の要求

7931 ワード

各APPは独自のプロセスで実行され、プロセス以外のリソースや情報にアクセスする必要がある場合は、対応する権限を要求する必要があります.APPは、Manifestファイルに要求する権限をリストし、実行時にユーザーに権限の付与を要求する必要があります(Android 6.0以降).この文書では、Android Support Libraryで権限のチェックとリクエストを行う方法について説明します.Android 6.0(API level 23)以上のAndroid Frameworkも同様の機能をサポートしていますが、support libraryを使用するとより早いAndroidバージョンに適しています.

マニフェストで権限を明示する


すべてのAndroidバージョンでは、アプリのManifestファイルで要素でどのアプリに必要な権限を使用しますか.たとえば、1つのAPPでSMSメッセージを送信する必要がある場合は、Manifestファイルで次のように説明する必要があります.
"http://schemas.android.com/apk/res/android"
        package="com.example.snazzyapp">

    "android.permission.SEND_SMS"/>
    

    ...>
        ...
    

システムは申請した権限の等級によって異なる表現がある:一般権限に対して、システムはAPPのインストール時に自動的にAPPに付与する;危険な権限に対応するには、ユーザーに明示的なAPPへの付与を要求する必要があります.権限レベルについては、Android権限概要の「権限レベル」を参照してください.

アクセス権の確認


Android 6.0(API level 23)から、アプリのtargetがAndroid 6.0(API level 23)より小さい場合でも、ユーザーはいつでもアプリの権限を取り消すことができます.例えば、あるアプリに昨日Cameraを使う権限があったとしても、今日ユーザーが手動でこの権限をキャンセルした場合、次回アプリを使うときはこの権限がありません.したがって、APPに危険な権限が必要な場合は、APPがこの権限を必要とする操作を実行するたびに、APPにこの権限があるかどうかを確認する必要があります.
ContextCompat.の使用checkSelfPermission()メソッドを使用して、APPに権限があるかどうかを確認します.次の例では、activityがcalendarに書き込む権限を持っていることを確認します.
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
        != PackageManager.PERMISSION_GRANTED) {
    // Permission is not granted
}

アプリにこの権限があれば、PERMISSION_に戻ります.GRANTED、APPは相応の操作を行うことができます;アプリにこの権限がない場合は、PERMISSION_に戻ります.DENIED、APPはユーザーに権限の付与を明示的に要求しなければならない.

リクエスト権限


APPがcheckSelfPermission()を呼び出してPERMISSION_に戻る場合DENIEDの結果、ユーザーに権限の付与を要求する必要があります.AndroidはrequestPermissions()のような権限を要求する方法をいくつか提供しています.これらの権限を要求する方法を使用すると、Android権限の概要に記載されているように、標準的でカスタマイズできないダイアログボックスが呼び出されます.

アプリにこの権限が必要な理由をユーザーに説明する


場合によっては、アプリにこの権限が必要な理由を理解するのに役立つ必要があります.たとえば、ユーザーは図庫APPを起動し、ユーザーはAPPに対してCamera権限を使用する必要がないことに意外に思っていますが、ユーザーはなぜこのAPPがユーザーの位置情報と連絡先情報にアクセスする必要があるのか理解していないかもしれません.したがって、APPが権限を要求する前に、なぜこれらの権限を使用する必要があるのかをユーザーに説明する必要があります.しかし、あまり煩雑な説明がないように注意してください.そうしないと、ユーザーはアプリが分かりにくく、アプリをアンインストールします.したがって、説明は、ユーザーがこの権限の付与を拒否した場合にのみ提供されます.Androidが提供するツールメソッドshouldShowRequestPermissionRationale()を呼び出すことができます.trueを返すと、ユーザーがこの権限を拒否したことを示します.権限を要求するときにどのようにユーザー体験を保障するかについては、App Permissions Best Practicesを参照してください.

必要な権限の要求


APPはrequestPermissions()関数を使用して必要な権限を要求し、APPが要求する権限とintegerタイプのrequest codeを入力します.この関数は非同期で、呼び出されるとすぐに戻ります.ユーザーがリクエストに応答すると、コールバック関数が呼び出されてrequest codeと操作結果が返されます.
次のコードは、APPに連絡先を読み取る権限があるかどうかを確認し、権限がない場合は、なぜこの権限を使用したのかをユーザーに説明するかどうかを確認し、説明が必要ない場合は、ユーザーに権限の付与を要求します.
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.READ_CONTACTS)
    != PackageManager.PERMISSION_GRANTED) {

    // Permission is not granted
    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed; request the permission
        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
} else {
    // Permission has already been granted
}

APPがrequestPermissions()を呼び出すと、標準のポップアップボックスがユーザーに表示されます.APPではこのポップアップボックスを設定またはカスタマイズできません.APPがユーザーになぜ権限が必要なのかを説明する必要がある場合は、requestPermissions()の前に、「ユーザーにAPPがなぜこの権限が必要なのかを説明する」で説明したようにする必要があります.

権限要求コールバックの処理


ユーザーがAPPの権限要求に応答すると、APPのonRequestPermissionsResult()コールバック関数が呼び出され、request codeとユーザーの応答結果が返されます.例えばAPP要求READ_CONTATSでは、次のようなコールバックがあります.
@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request.
    }
}

システムからポップアップされた権限要求ダイアログボックスでは、APPに関連する権限グループのみが記述され、権限は個別に記述されません.例えば、APP要求READ_CONTATS権限、権限要求ダイアログボックスは、APPがデバイスにアクセスする必要がある連絡先のみを説明します.同じ権限グループに属する権限については、ユーザーは一度明示的に付与するだけでよい.APPがすでに権限を取得している場合、同じ権限グループの他の権限を要求すると、自動的にAPPに権限が付与されます.コード実行では、requestPermissions()を呼び出すと、ユーザーの許可のために権限要求ボックスをポップアップする必要はありません.onRequestPermissionsResult()コールバックメソッドを直接呼び出し、PERMISSION_を返します.GRANTED.注意:ユーザーが権限グループ内の権限を許可したとしても、APPが権限グループ内の他の権限を使用する場合はrequestPermissions()明示的な要求権限を呼び出す必要がありますが、ユーザーは明示的な権限を必要とせず、システムが自動的に許可します.例えば、APPのManifestファイルにREAD_が明記されていますCONTATSとWRITE_CONTATSの2つの権限、もしAPPがすでにREADを要求したならばCONTATS権限とユーザーが明示的に許可されている場合、WRITE_を要求します.CONTATS権限の場合、ユーザーと対話する必要がなく、すぐにこの権限が付与されます.
ユーザーが権限の付与を拒否した場合、APPは対応する措置を取らなければならない.例えば、APPにはポップアップボックスが表示され、ユーザーがこの権限の使用に同意しない場合、一部の機能が使用できないことを示している.
システムがユーザーに権限を付与すると、ユーザーは「次回プロンプトしない」オプションを選択できます.ユーザーがこの権限を選択した場合、次のAPPがrequestPermissions()を呼び出して再びこの権限を要求すると、システムはすぐにこの権限を拒否します.コード実行では、requestPermissions()を呼び出すと、ユーザーの許可のために権限要求ボックスをポップアップする必要はありません.onRequestPermissionsResult()コールバックメソッドを直接呼び出し、PERMISSION_を返します.DENIED.デバイスポリシーがAPPにいくつかの権限を取得することを禁止している場合、requestPermissions()はfalseを返します.したがって、APPがrequestPermissions()を呼び出すと、APPがユーザと対話するとは限らない.