Home | History | Annotate | Download | only in permissions
      1 page.title=Requesting Permissions at Run Time
      2 page.tags="runtime permissions",androidm,marshmallow
      3 page.image=images/permissions_check.png
      4 page.metaDescription=Learn about runtime permissions and how they make it easier for users to install and upgrade your apps.
      5 @jd:body
      6 
      7 <div id="tb-wrapper">
      8   <div id="tb">
      9   <h2>This lesson teaches you to</h2>
     10 
     11   <ul>
     12     <li>
     13       <a href="#perm-check">Check For Permissions</a>
     14     </li>
     15     <li>
     16       <a href="#perm-request">Request Permissions</a>
     17     </li>
     18   </ul>
     19 
     20   <h2>Dependencies and Prerequisites</h2>
     21 
     22   <ul>
     23     <li>Android 6.0 (API level 23)
     24     </li>
     25   </ul>
     26 
     27   <h2>You should also read</h2>
     28 
     29   <ul>
     30     <li>
     31       <a href=
     32       "{@docRoot}guide/topics/security/permissions.html#normal-dangerous">Normal
     33       and Dangerous Permissions</a>
     34     </li>
     35   </ul>
     36 </div>
     37 </div>
     38 
     39 <p>
     40   Beginning in Android 6.0 (API level 23), users grant
     41   permissions to apps while the app is running, not when they install the app.
     42   This approach streamlines the app
     43   install process, since the user does not need to grant permissions when they
     44   install or update the app. It also gives the user more control over the app's
     45   functionality; for example, a user could choose to give a camera app access
     46   to the camera but not to the device location. The user can revoke the
     47   permissions at any time, by going to the app's Settings screen.
     48 </p>
     49 
     50 <p>
     51   System permissions are divided into two categories, <em>normal</em> and
     52   <em>dangerous:</em>
     53 </p>
     54 
     55 <ul>
     56   <li>Normal permissions do not directly risk the user's privacy. If your app
     57   lists a normal permission in its manifest, the system grants the permission
     58   automatically.
     59   </li>
     60 
     61   <li>Dangerous permissions can give the app access to the user's confidential
     62   data. If your app lists a normal permission in its manifest, the system
     63   grants the permission automatically. If you list a dangerous permission, the
     64   user has to explicitly give approval to your app.
     65   </li>
     66 </ul>
     67 
     68 <p>
     69   For more information, see <a href=
     70   "{@docRoot}guide/topics/security/permissions.html#normal-dangerous">Normal
     71   and Dangerous Permissions</a>.
     72 </p>
     73 
     74 <p>
     75   On all versions of Android, your app needs to declare both the normal and the
     76   dangerous permissions it needs in its app manifest, as described in <a href=
     77   "declaring.html">Declaring Permissions</a>. However, the <em>effect</em> of
     78   that declaration is different depending on the system version and your
     79   app's target SDK level:
     80 </p>
     81 
     82 <ul>
     83   <li>If the device is running Android 5.1 or lower, <strong>or</strong> your app's target SDK
     84   is 22 or lower: If you list a dangerous permission in your manifest, the user
     85   has to grant the permission when they install the app; if they do not grant
     86   the permission, the system does not install the app at all.
     87   </li>
     88 
     89   <li>If the device is running Android 6.0 or higher, <strong>and</strong> your app's target SDK
     90   is 23 or higher: The app has to list the permissions in the manifest,
     91   <em>and</em> it must request each dangerous permission it needs while the app
     92   is running. The user can grant or deny each permission, and the app can
     93   continue to run with limited capabilities even if the user denies a
     94   permission request.
     95   </li>
     96 </ul>
     97 
     98 <p class="note">
     99   <strong>Note:</strong> Beginning with Android 6.0 (API level 23), users can
    100   revoke permissions from any app at any time, even if the app targets a lower
    101   API level. You should test your app to verify that it behaves properly when
    102   it's missing a needed permission, regardless of what API level your app
    103   targets.
    104 </p>
    105 
    106 <p>
    107   This lesson describes how to use the Android <a href=
    108   "{@docRoot}tools/support-library/index.html">Support Library</a> to check
    109   for, and request, permissions. The Android framework provides similar methods
    110   as of Android 6.0 (API level 23). However, using the support library is
    111   simpler, since your app doesn't need to check which version of Android it's
    112   running on before calling the methods.
    113 </p>
    114 
    115 <h2 id="perm-check">Check For Permissions</h2>
    116 
    117 <p>
    118   If your app needs a dangerous permission, you must check whether you have
    119   that permission every time you perform an operation that requires that
    120   permission. The user is always free to revoke the permission, so even if the
    121   app used the camera yesterday, it can't assume it still has that permission
    122   today.
    123 </p>
    124 
    125 <p>
    126   To check if you have a permission, call the {@link
    127   android.support.v4.content.ContextCompat#checkSelfPermission
    128   ContextCompat.checkSelfPermission()} method. For example, this snippet shows how to
    129   check if the activity has permission to write to the calendar:
    130 </p>
    131 
    132 <pre>// Assume thisActivity is the current activity
    133 int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
    134         Manifest.permission.WRITE_CALENDAR);</pre>
    135 
    136 <p>
    137   If the app has the permission, the method returns {@link
    138   android.content.pm.PackageManager#PERMISSION_GRANTED
    139   PackageManager.PERMISSION_GRANTED}, and the app can proceed with the
    140   operation. If the app does not have the permission, the method returns {@link
    141   android.content.pm.PackageManager#PERMISSION_DENIED PERMISSION_DENIED}, and
    142   the app has to explicitly ask the user for permission.
    143 </p>
    144 
    145 <h2 id="perm-request">Request Permissions</h2>
    146 
    147 <p>
    148   If your app needs a dangerous permission that was listed in the app manifest,
    149   it must ask the user to grant the permission. Android provides several
    150   methods you can use to request a permission. Calling these methods brings up a
    151   standard Android dialog, which you cannot customize.
    152 </p>
    153 <h3 id="explain">Explain why the app needs permissions</h3>
    154 
    155 <div class="figure" style="width:220px" id="fig-perms-dialog">
    156   <img src="{@docRoot}images/training/permissions/request_permission_dialog.png"
    157       srcset="{@docRoot}images/training/permissions/request_permission_dialog.png 1x,
    158       {@docRoot}images/training/permissions/request_permission_dialog_2x.png 2x"
    159       alt="" width="220" />
    160   <p class="img-caption">
    161     <strong>Figure 1.</strong> System dialog prompting the user to grant or deny
    162     a permission.
    163   </p>
    164 </div>
    165 
    166 <p>
    167   In some circumstances, you might want to help the user understand why your
    168   app needs a permission. For example, if a user launches a photography app,
    169   the user probably won't be surprised that the app asks for permission to use
    170   the camera, but the user might not understand why the app wants access to the
    171   user's location or contacts. Before you request a permission, you should
    172   consider providing an explanation to the user. Keep in mind that you don't
    173   want to overwhelm the user with explanations; if you provide too many
    174   explanations, the user might find the app frustrating and remove it.
    175 </p>
    176 
    177 <p>
    178   One approach you might use is to provide an explanation only if the user has
    179   already turned down that permission request. If a user keeps trying to use
    180   functionality that requires a permission, but keeps turning down the
    181   permission request, that probably shows that the user doesn't understand why
    182   the app needs the permission to provide that functionality. In a situation
    183   like that, it's probably a good idea to show an explanation.
    184 </p>
    185 
    186 <p>
    187   To help find situations where the user might need an explanation, Android
    188   provides a utiltity method, {@link
    189   android.support.v4.app.ActivityCompat#shouldShowRequestPermissionRationale
    190   shouldShowRequestPermissionRationale()}. This method returns <code>true</code> if the app
    191   has requested this permission previously and the user denied the request.
    192 </p>
    193 
    194 <p class="note">
    195   <strong>Note:</strong> If the user turned down the permission request in the
    196   past and chose the <strong>Don't ask again</strong> option in the permission
    197   request system dialog, this method returns <code>false</code>. The method
    198   also returns <code>false</code> if a device policy prohibits the app from
    199   having that permission.
    200 </p>
    201 
    202 <h3 id="make-the-request">Request the permissions you need</h3>
    203 
    204 <p>
    205   If your app doesn't already have the permission it needs, the app must call
    206   one of the {@link android.support.v4.app.ActivityCompat#requestPermissions
    207   requestPermissions()} methods to request the appropriate
    208   permissions. Your app passes the permissions it wants, and also
    209   an integer <em>request code</em> that you specify to identify this permission
    210   request. This method functions asynchronously: it
    211   returns right away, and after the user responds to the dialog box, the system
    212   calls the app's callback method with the results, passing the same request
    213   code that the app passed to
    214   {@link android.support.v4.app.ActivityCompat#requestPermissions
    215   requestPermissions()}.
    216 </p>
    217 
    218 <p>
    219   The following code checks if the app has permission to read the user's
    220   contacts, and requests the permission if necessary:
    221 </p>
    222 
    223 <pre>// Here, thisActivity is the current activity
    224 if (ContextCompat.checkSelfPermission(thisActivity,
    225                 Manifest.permission.READ_CONTACTS)
    226         != PackageManager.PERMISSION_GRANTED) {
    227 
    228     // Should we show an explanation?
    229     if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
    230             Manifest.permission.READ_CONTACTS)) {
    231 
    232         // Show an expanation to the user *asynchronously* -- don't block
    233         // this thread waiting for the user's response! After the user
    234         // sees the explanation, try again to request the permission.
    235 
    236     } else {
    237 
    238         // No explanation needed, we can request the permission.
    239 
    240         ActivityCompat.requestPermissions(thisActivity,
    241                 new String[]{Manifest.permission.READ_CONTACTS},
    242                 MY_PERMISSIONS_REQUEST_READ_CONTACTS);
    243 
    244         // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
    245         // app-defined int constant. The callback method gets the
    246         // result of the request.
    247     }
    248 }</pre>
    249 
    250 <p class="note">
    251   <strong>Note:</strong> When your app calls {@link
    252   android.support.v4.app.ActivityCompat#requestPermissions
    253   requestPermissions()}, the system shows a standard dialog box to the user.
    254   Your app <em>cannot</em> configure or alter that dialog box. If you need to
    255   provide any information or explanation to the user, you should do that before
    256   you call {@link android.support.v4.app.ActivityCompat#requestPermissions
    257   requestPermissions()}, as described in <a href="#explain">Explain why the app
    258   needs permissions</a>.
    259 </p>
    260 
    261 <h3 id="handle-response">Handle the permissions request response
    262 </h3>
    263 
    264 <p>
    265   When your app requests permissions, the system presents a dialog box to the
    266   user. When the user responds, the system invokes your app's {@link
    267   android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback#onRequestPermissionsResult
    268   onRequestPermissionsResult()} method, passing it the user response. Your app
    269   has to override that method to find out whether the permission was granted.
    270   The callback is passed the same request code you passed to
    271   {@link android.support.v4.app.ActivityCompat#requestPermissions
    272   requestPermissions()}. For example, if an app requests {@link
    273   android.Manifest.permission#READ_CONTACTS READ_CONTACTS} access it might have
    274   the following callback method:
    275 </p>
    276 
    277 <pre>&#64;Override
    278 public void onRequestPermissionsResult(int requestCode,
    279         String permissions[], int[] grantResults) {
    280     switch (requestCode) {
    281         case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
    282             // If request is cancelled, the result arrays are empty.
    283             if (grantResults.length > 0
    284                 &amp;&amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    285 
    286                 // permission was granted, yay! Do the
    287                 // contacts-related task you need to do.
    288 
    289             } else {
    290 
    291                 // permission denied, boo! Disable the
    292                 // functionality that depends on this permission.
    293             }
    294             return;
    295         }
    296 
    297         // other 'case' lines to check for other
    298         // permissions this app might request
    299     }
    300 }</pre>
    301 
    302 <p>
    303   The dialog box shown by the system describes the <a href=
    304   "{@docRoot}guide/topics/security/permissions.html#perm-groups">permission
    305   group</a> your app needs access to; it does not list the specific permission.
    306   For example, if you request the {@link
    307   android.Manifest.permission#READ_CONTACTS READ_CONTACTS} permission, the
    308   system dialog box just says your app needs access to the device's contacts.
    309   The user only needs to grant permission once for each permission group. If
    310   your app requests any other permissions in that group (that are listed in
    311   your app manifest), the system automatically grants them. When you request
    312   the permission, the system calls your {@link
    313   android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback#onRequestPermissionsResult
    314   onRequestPermissionsResult()} callback method and passes {@link
    315   android.content.pm.PackageManager#PERMISSION_GRANTED PERMISSION_GRANTED}, the
    316   same way it would if the user had explicitly granted your request through the
    317   system dialog box.
    318 </p>
    319 
    320 <p class="note">
    321   <strong>Note:</strong> Your app still needs to explicitly request every
    322   permission it needs, even if the user has already granted another permission
    323   in the same group. In addition, the grouping of permissions into groups may
    324   change in future Android releases. Your code should not rely
    325   on the assumption that particular permissions are or are not in the
    326   same group.
    327 </p>
    328 
    329 <p>
    330   For example, suppose you list both {@link
    331   android.Manifest.permission#READ_CONTACTS READ_CONTACTS} and {@link
    332   android.Manifest.permission#WRITE_CONTACTS WRITE_CONTACTS} in your app
    333   manifest. If you request
    334   {@link android.Manifest.permission#READ_CONTACTS READ_CONTACTS} and the user
    335   grants the permission, and you then request {@link
    336   android.Manifest.permission#WRITE_CONTACTS WRITE_CONTACTS}, the system
    337   immediately grants you that permission without interacting with the user.
    338 </p>
    339 
    340 <p>
    341   If the user denies a permission request, your app should take appropriate
    342   action. For example, your app might show a dialog explaining why it could not
    343   perform the user's requested action that needs that permission.
    344 </p>
    345 
    346 <p>
    347   When the system asks the user to grant a permission, the user has the option
    348   of telling the system not to ask for that permission again. In that case, any
    349   time an app uses {@link
    350   android.support.v4.app.ActivityCompat#requestPermissions
    351   requestPermissions()} to ask for that permission again, the system
    352   immediately denies the request. The system calls your {@link
    353   android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback#onRequestPermissionsResult
    354   onRequestPermissionsResult()} callback method and passes {@link
    355   android.content.pm.PackageManager#PERMISSION_DENIED PERMISSION_DENIED}, the
    356   same way it would if the user had explicitly rejected your request again.
    357   This means that when you call {@link
    358   android.support.v4.app.ActivityCompat#requestPermissions
    359   requestPermissions()}, you cannot assume that any direct interaction with the
    360   user has taken place.
    361 </p>
    362