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>@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 && 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