Home | History | Annotate | Download | only in permissions
      1 page.title=Permissions Best Practices
      2 page.tags=permissions
      3 helpoutsWidget=true
      4 
      5 @jd:body
      6 
      7 <div id="tb-wrapper">
      8   <div id="tb">
      9 
     10 <h2>In this document</h2>
     11 <ul>
     12   <li><a href="#perms-vs-intents">Consider Using an Intent</a></li>
     13 
     14   <li><a href="#dont-overwhelm">Don't Overwhelm the User</a></li>
     15 
     16   <li><a href="#explain">Explain Why You Need Permissions</a></li>
     17 
     18   <li><a href="#testing">Test for Both Permissions Models</a></li>
     19 
     20 </ul>
     21 
     22 <h2>You should also read</h2>
     23   <ul>
     24     <li><a href="{@docRoot}training/basics/intents/index.html">Interacting
     25       with Other Apps</a></li>
     26   </ul>
     27 
     28 </div>
     29 </div>
     30 
     31 
     32 <p>
     33 It's easy for an app to overwhelm a user with permission requests. If a user
     34 finds the app frustrating to use, or the user is worried about what the app
     35 might be doing with the user's information, they may avoid using the app or
     36 uninstall it entirely. The following best practices can help you avoid such
     37 bad user experiences.
     38 </p>
     39 
     40 <h2 id="perms-vs-intents">Consider Using an Intent</h2>
     41 
     42 <p>
     43   In many cases, you can choose between two ways for your app to perform a
     44   task. You can have your app ask for permission to perform the operation
     45   itself. Alternatively, you can have the app use an <em>intent</em> to have
     46   another app perform the task.
     47 </p>
     48 
     49 <p>
     50   For example, suppose your app needs to be able to take pictures with the
     51   device camera. Your app can request the {@link
     52   android.Manifest.permission#CAMERA CAMERA} permission, which allows your app
     53   to access the camera directly. Your app would then use the camera APIs to
     54   control the camera and take a picture. This approach gives your app full
     55   control over the photography process, and lets you incorporate the camera UI
     56   into your app.
     57 </p>
     58 
     59 <p>
     60   However, if you don't need such complete control, you can use an {@link
     61   android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} intent
     62   to request an image. When you send the intent, the system prompts the user to
     63   choose a camera app (if there isn't already a default camera app).
     64   The user takes a picture with the selected camera app, and that app returns
     65   the picture to your app's {@link
     66   android.app.Activity#onActivityResult onActivityResult()} method.
     67 </p>
     68 
     69 <p>
     70   Similarly, if you need to make a phone call, access the user's contacts, and
     71   so on, you can do that by creating an appropriate intent, or you can request
     72   the permission and access the appropriate objects directly. There are
     73   advantages and disadvantages to each approach.
     74 </p>
     75 
     76 <p>
     77   If you use permissions:
     78 </p>
     79 
     80 <ul>
     81   <li>Your app has full control over the user experience when you perform the
     82   operation. However, such broad control adds to the complexity of your task,
     83   since you need to design an appropriate UI.
     84   </li>
     85 
     86   <li>The user is prompted to give permission once, either at run time or at
     87   install time (depending on the user's Android version). After that, your app
     88   can perform the operation without requiring additional interaction from the
     89   user. However, if the user doesn't grant the permission (or revokes it later
     90   on), your app becomes unable to perform the operation at all.
     91   </li>
     92 </ul>
     93 
     94 <p>
     95   If you use an intent:
     96 </p>
     97 
     98 <ul>
     99   <li>You do not have to design the UI for the operation. The app that handles
    100   the intent provides the UI. However, this means you have
    101   no control over the user experience. The user could be interacting with an
    102   app you've never seen.
    103   </li>
    104 
    105   <li>If the user does not have a default app for the operation, the system
    106   prompts the user to choose an app. If the user does not designate a default
    107   handler, they may have to go
    108   through an extra dialog every time they perform the operation.
    109   </li>
    110 </ul>
    111 
    112 <h2 id="ask-neccessary">Only Ask for Permissions You Need</h2>
    113 
    114 <p>
    115   Every time you ask for a permission, you force the user to make a decision.
    116   You should minimize the number of times you make these requests. If the user
    117   is running Android 6.0 (API level 23) or later, every time the user tries
    118   some new app feature that requires a permission, the app has to interrupt the
    119   user's work with a permission request. If the user is running an earlier
    120   version of Android, the user has to grant every one of the app's permissions
    121   when installing the app; if the list is too long or seems inappropriate, the
    122   user may decide not to install your app at all. For these reasons, you should
    123   minimize the number of permissions your app needs.
    124 </p>
    125 
    126 <p>
    127   Quite often your app can avoid requesting a permission by using an
    128   <em>intent</em> instead. If a feature is not a core part of your app's
    129   functionality, you should consider handing the work over to another app, as
    130   described in <a href="#perms-vs-intents">Consider Using An Intent</a>.
    131 </p>
    132 
    133 <h2 id="dont-overwhelm">Don't Overwhelm the User</h2>
    134 
    135 <p>
    136   If the user is running Android 6.0 (API level 23) or later, the user has to
    137   grant your app its permissions while they are running the app. If you
    138   confront the user with a lot of requests for permissions at once, you may
    139   overwhelm the user and cause them to quit your app. Instead, you should ask
    140   for permissions as you need them.
    141 </p>
    142 
    143 <p>
    144   In some cases, one or more permissions might be absolutely essential to your
    145   app. It might make sense to ask for all of those permissions as soon as the
    146   app launches. For example, if you make a photography app, the app would need
    147   access to the device camera. When the user launches the app for the first
    148   time, they won't be surprised to be asked for permission to use the camera.
    149   But if the same app also had a feature to share photos with the user's
    150   contacts, you probably should <em>not</em> ask for the {@link
    151   android.Manifest.permission#READ_CONTACTS READ_CONTACTS} permission at first
    152   launch. Instead, wait until the user tries to use the "sharing" feature and
    153   ask for the permission then.
    154 </p>
    155 
    156 <p>
    157   If your app provides a tutorial, it may make sense to request the app's
    158   essential permissions at the end of the tutorial sequence.
    159 </p>
    160 
    161 <h2 id="explain">Explain Why You Need Permissions</h2>
    162 
    163 <p>
    164   The permissions dialog shown by the system when you call
    165   {@link android.support.v4.app.ActivityCompat#requestPermissions
    166   requestPermissions()} says what permission your app wants, but doesn't say
    167   why. In some cases, the user may find that puzzling. It's a good idea to
    168   explain to the user why your app wants the permissions before calling
    169   {@link android.support.v4.app.ActivityCompat#requestPermissions
    170   requestPermissions()}.
    171 </p>
    172 
    173 <p>
    174   For example, a photography app might want to use location services so it can
    175   geotag the photos. A typical user might not understand that a photo can
    176   contain location information, and would be puzzled why their photography app
    177   wants to know the location. So in this case, it's a good idea for the app to
    178   tell the user about this feature <em>before</em> calling
    179   {@link android.support.v4.app.ActivityCompat#requestPermissions
    180   requestPermissions()}.
    181 </p>
    182 
    183 <p>
    184   One way to inform the user is to incorporate these requests into an app
    185   tutorial. The tutorial can show each of the app's features in turn, and as it
    186   does this, it can explain what permissions are needed. For example, the
    187   photography app's tutorial could demonstrate its "share photos with your
    188   contacts" feature, then tell the user that they need to give permission for
    189   the app to see the user's contacts. The app could then call {@link
    190   android.support.v4.app.ActivityCompat#requestPermissions
    191   requestPermissions()} to ask the user for that access. Of course, not every
    192   user is going to follow the tutorial, so you still need to check for and
    193   request permissions during the app's normal operation.
    194 </p>
    195 
    196 <h2 id="testing">Test for Both Permissions Models</h2>
    197 
    198 <p>
    199   Beginning with Android 6.0 (API level 23), users grant and revoke app
    200   permissions at run time, instead of doing so when they install the app. As a
    201   result, you'll have to test your app under a wider range of conditions. Prior
    202   to Android 6.0, you could reasonably assume that if your app is running at
    203   all, it has all the permissions it declares in the app manifest. Under the
    204   new permissions model, you can no longer make that assumption.
    205 </p>
    206 
    207 <p>
    208   The following tips will help you identify permissions-related code problems
    209   on devices running API level 23 or higher:
    210 </p>
    211 
    212 <ul>
    213   <li>Identify your apps current permissions and the related code paths.
    214   </li>
    215 
    216   <li>Test user flows across permission-protected services and data.
    217   </li>
    218 
    219   <li>Test with various combinations of granted or revoked permissions. For
    220   example, a camera app might list {@link android.Manifest.permission#CAMERA
    221   CAMERA}, {@link android.Manifest.permission#READ_CONTACTS READ_CONTACTS}, and
    222   {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}
    223   in its manifest. You should test the app with each of these permissions
    224   turned on and off, to make sure the app can handle all permission
    225   configurations gracefully. Remember, beginning with Android 6.0 the user can
    226   turn permissions on or off for <em>any</em> app, even an app that targets API
    227   level 22 or lower.
    228   </li>
    229 
    230   <li>Use the <a href="{@docRoot}tools/help/adb.html">adb</a> tool to manage
    231   permissions from the command line:
    232     <ul>
    233       <li>List permissions and status by group:
    234 
    235         <pre class="no-pretty-print">$ adb shell pm list permissions -d -g</pre>
    236       </li>
    237 
    238       <li>Grant or revoke one or more permissions:
    239 
    240         <pre class="no-pretty-print">$ adb shell pm [grant|revoke] &lt;permission-name&gt; ...</pre>
    241       </li>
    242     </ul>
    243   </li>
    244 
    245   <li>Analyze your app for services that use permissions.
    246   </li>
    247 </ul>
    248