| page.title=Requesting Permissions at Run Time | |
| page.tags="runtime permissions",androidm,marshmallow | |
| page.image=images/permissions_check.png | |
| page.metaDescription=Learn about runtime permissions and how they make it easier for users to install and upgrade your apps. | |
| @jd:body | |
| <div id="tb-wrapper"> | |
| <div id="tb"> | |
| <h2>This lesson teaches you to</h2> | |
| <ul> | |
| <li> | |
| <a href="#perm-check">Check For Permissions</a> | |
| </li> | |
| <li> | |
| <a href="#perm-request">Request Permissions</a> | |
| </li> | |
| </ul> | |
| <h2>Dependencies and Prerequisites</h2> | |
| <ul> | |
| <li>Android 6.0 (API level 23) | |
| </li> | |
| </ul> | |
| <h2>You should also read</h2> | |
| <ul> | |
| <li> | |
| <a href= | |
| "{@docRoot}guide/topics/security/permissions.html#normal-dangerous">Normal | |
| and Dangerous Permissions</a> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| <p> | |
| Beginning in Android 6.0 (API level 23), users grant | |
| permissions to apps while the app is running, not when they install the app. | |
| This approach streamlines the app | |
| install process, since the user does not need to grant permissions when they | |
| install or update the app. It also gives the user more control over the app's | |
| functionality; for example, a user could choose to give a camera app access | |
| to the camera but not to the device location. The user can revoke the | |
| permissions at any time, by going to the app's Settings screen. | |
| </p> | |
| <p> | |
| System permissions are divided into two categories, <em>normal</em> and | |
| <em>dangerous:</em> | |
| </p> | |
| <ul> | |
| <li>Normal permissions do not directly risk the user's privacy. If your app | |
| lists a normal permission in its manifest, the system grants the permission | |
| automatically. | |
| </li> | |
| <li>Dangerous permissions can give the app access to the user's confidential | |
| data. If your app lists a normal permission in its manifest, the system | |
| grants the permission automatically. If you list a dangerous permission, the | |
| user has to explicitly give approval to your app. | |
| </li> | |
| </ul> | |
| <p> | |
| For more information, see <a href= | |
| "{@docRoot}guide/topics/security/permissions.html#normal-dangerous">Normal | |
| and Dangerous Permissions</a>. | |
| </p> | |
| <p> | |
| On all versions of Android, your app needs to declare both the normal and the | |
| dangerous permissions it needs in its app manifest, as described in <a href= | |
| "declaring.html">Declaring Permissions</a>. However, the <em>effect</em> of | |
| that declaration is different depending on the system version and your | |
| app's target SDK level: | |
| </p> | |
| <ul> | |
| <li>If the device is running Android 5.1 or lower, <strong>or</strong> your app's target SDK | |
| is 22 or lower: If you list a dangerous permission in your manifest, the user | |
| has to grant the permission when they install the app; if they do not grant | |
| the permission, the system does not install the app at all. | |
| </li> | |
| <li>If the device is running Android 6.0 or higher, <strong>and</strong> your app's target SDK | |
| is 23 or higher: The app has to list the permissions in the manifest, | |
| <em>and</em> it must request each dangerous permission it needs while the app | |
| is running. The user can grant or deny each permission, and the app can | |
| continue to run with limited capabilities even if the user denies a | |
| permission request. | |
| </li> | |
| </ul> | |
| <p class="note"> | |
| <strong>Note:</strong> Beginning with Android 6.0 (API level 23), users can | |
| revoke permissions from any app at any time, even if the app targets a lower | |
| API level. You should test your app to verify that it behaves properly when | |
| it's missing a needed permission, regardless of what API level your app | |
| targets. | |
| </p> | |
| <p> | |
| This lesson describes how to use the Android <a href= | |
| "{@docRoot}tools/support-library/index.html">Support Library</a> to check | |
| for, and request, permissions. The Android framework provides similar methods | |
| as of Android 6.0 (API level 23). However, using the support library is | |
| simpler, since your app doesn't need to check which version of Android it's | |
| running on before calling the methods. | |
| </p> | |
| <h2 id="perm-check">Check For Permissions</h2> | |
| <p> | |
| If your app needs a dangerous permission, you must check whether you have | |
| that permission every time you perform an operation that requires that | |
| permission. The user is always free to revoke the permission, so even if the | |
| app used the camera yesterday, it can't assume it still has that permission | |
| today. | |
| </p> | |
| <p> | |
| To check if you have a permission, call the {@link | |
| android.support.v4.content.ContextCompat#checkSelfPermission | |
| ContextCompat.checkSelfPermission()} method. For example, this snippet shows how to | |
| check if the activity has permission to write to the calendar: | |
| </p> | |
| <pre>// Assume thisActivity is the current activity | |
| int permissionCheck = ContextCompat.checkSelfPermission(thisActivity, | |
| Manifest.permission.WRITE_CALENDAR);</pre> | |
| <p> | |
| If the app has the permission, the method returns {@link | |
| android.content.pm.PackageManager#PERMISSION_GRANTED | |
| PackageManager.PERMISSION_GRANTED}, and the app can proceed with the | |
| operation. If the app does not have the permission, the method returns {@link | |
| android.content.pm.PackageManager#PERMISSION_DENIED PERMISSION_DENIED}, and | |
| the app has to explicitly ask the user for permission. | |
| </p> | |
| <h2 id="perm-request">Request Permissions</h2> | |
| <p> | |
| If your app needs a dangerous permission that was listed in the app manifest, | |
| it must ask the user to grant the permission. Android provides several | |
| methods you can use to request a permission. Calling these methods brings up a | |
| standard Android dialog, which you cannot customize. | |
| </p> | |
| <h3 id="explain">Explain why the app needs permissions</h3> | |
| <div class="figure" style="width:220px" id="fig-perms-dialog"> | |
| <img src="{@docRoot}images/training/permissions/request_permission_dialog.png" | |
| srcset="{@docRoot}images/training/permissions/request_permission_dialog.png 1x, | |
| {@docRoot}images/training/permissions/request_permission_dialog_2x.png 2x" | |
| alt="" width="220" /> | |
| <p class="img-caption"> | |
| <strong>Figure 1.</strong> System dialog prompting the user to grant or deny | |
| a permission. | |
| </p> | |
| </div> | |
| <p> | |
| In some circumstances, you might want to help the user understand why your | |
| app needs a permission. For example, if a user launches a photography app, | |
| the user probably won't be surprised that the app asks for permission to use | |
| the camera, but the user might not understand why the app wants access to the | |
| user's location or contacts. Before you request a permission, you should | |
| consider providing an explanation to the user. Keep in mind that you don't | |
| want to overwhelm the user with explanations; if you provide too many | |
| explanations, the user might find the app frustrating and remove it. | |
| </p> | |
| <p> | |
| One approach you might use is to provide an explanation only if the user has | |
| already turned down that permission request. If a user keeps trying to use | |
| functionality that requires a permission, but keeps turning down the | |
| permission request, that probably shows that the user doesn't understand why | |
| the app needs the permission to provide that functionality. In a situation | |
| like that, it's probably a good idea to show an explanation. | |
| </p> | |
| <p> | |
| To help find situations where the user might need an explanation, Android | |
| provides a utiltity method, {@link | |
| android.support.v4.app.ActivityCompat#shouldShowRequestPermissionRationale | |
| shouldShowRequestPermissionRationale()}. This method returns <code>true</code> if the app | |
| has requested this permission previously and the user denied the request. | |
| </p> | |
| <p class="note"> | |
| <strong>Note:</strong> If the user turned down the permission request in the | |
| past and chose the <strong>Don't ask again</strong> option in the permission | |
| request system dialog, this method returns <code>false</code>. The method | |
| also returns <code>false</code> if a device policy prohibits the app from | |
| having that permission. | |
| </p> | |
| <h3 id="make-the-request">Request the permissions you need</h3> | |
| <p> | |
| If your app doesn't already have the permission it needs, the app must call | |
| one of the {@link android.support.v4.app.ActivityCompat#requestPermissions | |
| requestPermissions()} methods to request the appropriate | |
| permissions. Your app passes the permissions it wants, and also | |
| an integer <em>request code</em> that you specify to identify this permission | |
| request. This method functions asynchronously: it | |
| returns right away, and after the user responds to the dialog box, the system | |
| calls the app's callback method with the results, passing the same request | |
| code that the app passed to | |
| {@link android.support.v4.app.ActivityCompat#requestPermissions | |
| requestPermissions()}. | |
| </p> | |
| <p> | |
| The following code checks if the app has permission to read the user's | |
| contacts, and requests the permission if necessary: | |
| </p> | |
| <pre>// Here, thisActivity is the current activity | |
| if (ContextCompat.checkSelfPermission(thisActivity, | |
| Manifest.permission.READ_CONTACTS) | |
| != PackageManager.PERMISSION_GRANTED) { | |
| // Should we show an explanation? | |
| if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, | |
| Manifest.permission.READ_CONTACTS)) { | |
| // Show an expanation 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, we can 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. | |
| } | |
| }</pre> | |
| <p class="note"> | |
| <strong>Note:</strong> When your app calls {@link | |
| android.support.v4.app.ActivityCompat#requestPermissions | |
| requestPermissions()}, the system shows a standard dialog box to the user. | |
| Your app <em>cannot</em> configure or alter that dialog box. If you need to | |
| provide any information or explanation to the user, you should do that before | |
| you call {@link android.support.v4.app.ActivityCompat#requestPermissions | |
| requestPermissions()}, as described in <a href="#explain">Explain why the app | |
| needs permissions</a>. | |
| </p> | |
| <h3 id="handle-response">Handle the permissions request response | |
| </h3> | |
| <p> | |
| When your app requests permissions, the system presents a dialog box to the | |
| user. When the user responds, the system invokes your app's {@link | |
| android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback#onRequestPermissionsResult | |
| onRequestPermissionsResult()} method, passing it the user response. Your app | |
| has to override that method to find out whether the permission was granted. | |
| The callback is passed the same request code you passed to | |
| {@link android.support.v4.app.ActivityCompat#requestPermissions | |
| requestPermissions()}. For example, if an app requests {@link | |
| android.Manifest.permission#READ_CONTACTS READ_CONTACTS} access it might have | |
| the following callback method: | |
| </p> | |
| <pre>@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 | |
| } | |
| }</pre> | |
| <p> | |
| The dialog box shown by the system describes the <a href= | |
| "{@docRoot}guide/topics/security/permissions.html#perm-groups">permission | |
| group</a> your app needs access to; it does not list the specific permission. | |
| For example, if you request the {@link | |
| android.Manifest.permission#READ_CONTACTS READ_CONTACTS} permission, the | |
| system dialog box just says your app needs access to the device's contacts. | |
| The user only needs to grant permission once for each permission group. If | |
| your app requests any other permissions in that group (that are listed in | |
| your app manifest), the system automatically grants them. When you request | |
| the permission, the system calls your {@link | |
| android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback#onRequestPermissionsResult | |
| onRequestPermissionsResult()} callback method and passes {@link | |
| android.content.pm.PackageManager#PERMISSION_GRANTED PERMISSION_GRANTED}, the | |
| same way it would if the user had explicitly granted your request through the | |
| system dialog box. | |
| </p> | |
| <p class="note"> | |
| <strong>Note:</strong> Your app still needs to explicitly request every | |
| permission it needs, even if the user has already granted another permission | |
| in the same group. In addition, the grouping of permissions into groups may | |
| change in future Android releases. Your code should not rely | |
| on the assumption that particular permissions are or are not in the | |
| same group. | |
| </p> | |
| <p> | |
| For example, suppose you list both {@link | |
| android.Manifest.permission#READ_CONTACTS READ_CONTACTS} and {@link | |
| android.Manifest.permission#WRITE_CONTACTS WRITE_CONTACTS} in your app | |
| manifest. If you request | |
| {@link android.Manifest.permission#READ_CONTACTS READ_CONTACTS} and the user | |
| grants the permission, and you then request {@link | |
| android.Manifest.permission#WRITE_CONTACTS WRITE_CONTACTS}, the system | |
| immediately grants you that permission without interacting with the user. | |
| </p> | |
| <p> | |
| If the user denies a permission request, your app should take appropriate | |
| action. For example, your app might show a dialog explaining why it could not | |
| perform the user's requested action that needs that permission. | |
| </p> | |
| <p> | |
| When the system asks the user to grant a permission, the user has the option | |
| of telling the system not to ask for that permission again. In that case, any | |
| time an app uses {@link | |
| android.support.v4.app.ActivityCompat#requestPermissions | |
| requestPermissions()} to ask for that permission again, the system | |
| immediately denies the request. The system calls your {@link | |
| android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback#onRequestPermissionsResult | |
| onRequestPermissionsResult()} callback method and passes {@link | |
| android.content.pm.PackageManager#PERMISSION_DENIED PERMISSION_DENIED}, the | |
| same way it would if the user had explicitly rejected your request again. | |
| This means that when you call {@link | |
| android.support.v4.app.ActivityCompat#requestPermissions | |
| requestPermissions()}, you cannot assume that any direct interaction with the | |
| user has taken place. | |
| </p> |