Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2bd0b99 authored by Andrew Solovay's avatar Andrew Solovay
Browse files

docs: New permissions training class.

Describes how to declare that your app needs system permissions;
also describes how (on M and later) to request those permissions at
runtime.

There's a companion CL which updates various existing API docs for
the new M permissions model (http://ag/762405 ).

See first comment for doc stage location.

bug: 23725768

Change-Id: I7c3babdb9348969d1b0b019e7e9ef7116b04c658
parent 4e4a920a
Loading
Loading
Loading
Loading
+117 KiB
Loading image diff...
+416 KiB
Loading image diff...
+245 −0
Original line number Diff line number Diff line
page.title=Permissions Best Practices
page.tags=permissions
helpoutsWidget=true

@jd:body

<div id="tb-wrapper">
  <div id="tb">

<h2>In this document</h2>
<ul>
  <li><a href="#perms-vs-intents">Consider Using an Intent</a></li>

  <li><a href="#dont-overwhelm">Don't Overwhelm the User</a></li>

  <li><a href="#explain">Explain Why You Need Permissions</a></li>

  <li><a href="#testing">Test for Both Permissions Models</a></li>

</ul>

<h2>You should also read</h2>
  <ul>
    <li><a href="{@docRoot}training/basics/intents/index.html">Interacting
      with Other Apps</a></li>
  </ul>

</div>
</div>


<p>
It's easy for an app to overwhelm a user with permission requests. If a user
finds the app frustrating to use, or the user is worried about what the app
might be doing with the user's information, they may avoid using the app or
uninstall it entirely. The following best practices can help you avoid such
bad user experiences.
</p>

<h2 id="perms-vs-intents">Consider Using an Intent</h2>

<p>
  In many cases, you can choose between two ways for your app to perform a
  task. You can have your app ask for permission to perform the operation
  itself. Alternatively, you can have the app use an <em>intent</em> to have
  another app perform the task.
</p>

<p>
  For example, suppose your app needs to be able to take pictures with the
  device camera. Your app can request the {@link
  android.Manifest.permission#CAMERA CAMERA} permission, which allows your app
  to access the camera directly. Your app would then use the camera APIs to
  control the camera and take a picture. This approach gives your app full
  control over the photography process, and lets you incorporate the camera UI
  into your app.
</p>

<p>
  However, if you don't need such complete control, you can use an {@link
  android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} intent
  to request an image. When you send the intent, the system prompts the user to
  choose a camera app (if there isn't already a default camera app).
  The user takes a picture with the selected camera app, and that app returns
  the picture to your app's {@link
  android.app.Activity#onActivityResult onActivityResult()} method.
</p>

<p>
  Similarly, if you need to make a phone call, access the user's contacts, and
  so on, you can do that by creating an appropriate intent, or you can request
  the permission and access the appropriate objects directly. There are
  advantages and disadvantages to each approach.
</p>

<p>
  If you use permissions:
</p>

<ul>
  <li>Your app has full control over the user experience when you perform the
  operation. However, such broad control adds to the complexity of your task,
  since you need to design an appropriate UI.
  </li>

  <li>The user is prompted to give permission once, either at run time or at
  install time (depending on the user's Android version). After that, your app
  can perform the operation without requiring additional interaction from the
  user. However, if the user doesn't grant the permission (or revokes it later
  on), your app becomes unable to perform the operation at all.
  </li>
</ul>

<p>
  If you use an intent:
</p>

<ul>
  <li>You do not have to design the UI for the operation. The app that handles
  the intent provides the UI. However, this means you have
  no control over the user experience. The user could be interacting with an
  app you've never seen.
  </li>

  <li>If the user does not have a default app for the operation, the system
  prompts the user to choose an app. If the user does not designate a default
  handler, they may have to go
  through an extra dialog every time they perform the operation.
  </li>
</ul>

<h2 id="ask-neccessary">Only Ask for Permissions You Need</h2>

<p>
  Every time you ask for a permission, you force the user to make a decision.
  You should minimize the number of times you make these requests. If the user
  is running Android 6.0 (API level 23) or later, every time the user tries
  some new app feature that requires a permission, the app has to interrupt the
  user's work with a permission request. If the user is running an earlier
  version of Android, the user has to grant every one of the app's permissions
  when installing the app; if the list is too long or seems inappropriate, the
  user may decide not to install your app at all. For these reasons, you should
  minimize the number of permissions your app needs.
</p>

<p>
  Quite often your app can avoid requesting a permission by using an
  <em>intent</em> instead. If a feature is not a core part of your app's
  functionality, you should consider handing the work over to another app, as
  described in <a href="#perms-vs-intents">Consider Using An Intent</a>.
</p>

<h2 id="dont-overwhelm">Don't Overwhelm the User</h2>

<p>
  If the user is running Android 6.0 (API level 23) or later, the user has to
  grant your app its permissions while they are running the app. If you
  confront the user with a lot of requests for permissions at once, you may
  overwhelm the user and cause them to quit your app. Instead, you should ask
  for permissions as you need them.
</p>

<p>
  In some cases, one or more permissions might be absolutely essential to your
  app. It might make sense to ask for all of those permissions as soon as the
  app launches. For example, if you make a photography app, the app would need
  access to the device camera. When the user launches the app for the first
  time, they won't be surprised to be asked for permission to use the camera.
  But if the same app also had a feature to share photos with the user's
  contacts, you probably should <em>not</em> ask for the {@link
  android.Manifest.permission#READ_CONTACTS READ_CONTACTS} permission at first
  launch. Instead, wait until the user tries to use the "sharing" feature and
  ask for the permission then.
</p>

<p>
  If your app provides a tutorial, it may make sense to request the app's
  essential permissions at the end of the tutorial sequence.
</p>

<h2 id="explain">Explain Why You Need Permissions</h2>

<p>
  The permissions dialog shown by the system when you call
  {@link android.support.v4.app.ActivityCompat#requestPermissions
  requestPermissions()} says what permission your app wants, but doesn't say
  why. In some cases, the user may find that puzzling. It's a good idea to
  explain to the user why your app wants the permissions before calling
  {@link android.support.v4.app.ActivityCompat#requestPermissions
  requestPermissions()}.
</p>

<p>
  For example, a photography app might want to use location services so it can
  geotag the photos. A typical user might not understand that a photo can
  contain location information, and would be puzzled why their photography app
  wants to know the location. So in this case, it's a good idea for the app to
  tell the user about this feature <em>before</em> calling
  {@link android.support.v4.app.ActivityCompat#requestPermissions
  requestPermissions()}.
</p>

<p>
  One way to inform the user is to incorporate these requests into an app
  tutorial. The tutorial can show each of the app's features in turn, and as it
  does this, it can explain what permissions are needed. For example, the
  photography app's tutorial could demonstrate its "share photos with your
  contacts" feature, then tell the user that they need to give permission for
  the app to see the user's contacts. The app could then call {@link
  android.support.v4.app.ActivityCompat#requestPermissions
  requestPermissions()} to ask the user for that access. Of course, not every
  user is going to follow the tutorial, so you still need to check for and
  request permissions during the app's normal operation.
</p>

<h2 id="testing">Test for Both Permissions Models</h2>

<p>
  Beginning with Android 6.0 (API level 23), users grant and revoke app
  permissions at run time, instead of doing so when they install the app. As a
  result, you'll have to test your app under a wider range of conditions. Prior
  to Android 6.0, you could reasonably assume that if your app is running at
  all, it has all the permissions it declares in the app manifest. Under the
  new permissions model, you can no longer make that assumption.
</p>

<p>
  The following tips will help you identify permissions-related code problems
  on devices running API level 23 or higher:
</p>

<ul>
  <li>Identify your app’s current permissions and the related code paths.
  </li>

  <li>Test user flows across permission-protected services and data.
  </li>

  <li>Test with various combinations of granted or revoked permissions. For
  example, a camera app might list {@link android.Manifest.permission#CAMERA
  CAMERA}, {@link android.Manifest.permission#READ_CONTACTS READ_CONTACTS}, and
  {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}
  in its manifest. You should test the app with each of these permissions
  turned on and off, to make sure the app can handle all permission
  configurations gracefully.
  </li>

  <li>Use the <a href="{@docRoot}tools/help/adb.html">adb</a> tool to manage
  permssions from the command line:
    <ul>
      <li>List permissions and status by group:

        <pre class="no-pretty-print">$ adb shell pm list permissions -d -g</pre>
      </li>

      <li>Grant or revoke one or more permissions:

        <pre class="no-pretty-print">$ adb shell pm [grant|revoke] &lt;permission-name&gt; ...</pre>
      </li>
    </ul>
  </li>

  <li>Analyze your app for services that use permissions.
  </li>
</ul>
+115 −0
Original line number Diff line number Diff line
page.title=Declaring Permissions
helpoutsWidget=true

@jd:body

<div id="tb-wrapper">
  <div id="tb">
  <h2>This lesson teaches you to</h2>
  <ul>
    <li>
      <a href="#perm-needed">Determine What Permissions Your App Needs</a>
    </li>
    <li>
      <a href="#perm-add">Add Permissions to the Manifest</a>
    </li>
  </ul>

<!--
    <h2>Dependencies and Prerequisites</h2>
    <ul>
      <li></li>
    </ul>
-->

<h2>You should also read</h2>
  <ul>
    <li><a href="{@docRoot}guide/topics/security/permissions.html#permissions">
      Using Permissions</a></li>  <ul>
    <li><a href="{@docRoot}guide/topics/security/permissions.html#normal-dangerous">
      Normal and Dangerous Permissions</a></li>
  </ul>
</div>
</div>

<p>
  Every Android app runs in a limited-access sandbox. If an app needs to use
  resources or information outside of its own sandbox, the app has to request
  the appropriate <i>permission.</i> You declare that your app needs a
  permission by listing the permission in the <a href=
  "{@docRoot}guide/topics/manifest/manifest-intro.html">App Manifest</a>.
</p>

<p>
  Depending on how sensitive the permission is, the system might grant the
  permission automatically, or the device user might have to grant
  the request. For example, if your app requests permission to turn on the
  device's flashlight, the system grants that permission automatically. But
  if your app needs to read the user's contacts, the system asks the user
  to approve that permission. Depending on the platform version, the user
  grants the permission either when they install the app (on Android 5.1 and
  lower) or while running the app (on Android 6.0 and higher).
</p>

<h2 id="perm-needed">Determine What Permissions Your App Needs</h2>

<p>
  As you develop your app, you should note when your app is using capabilities
  that require a permission. Typically, an app is going to need permissions
  whenever it uses information or resources that the app doesn't create, or
  performs actions that affect the behavior of the device or other apps. For
  example, if an app needs to access the internet, use the device camera, or
  turn Wi-Fi on or off, the app needs the appropriate permission. For a list of
  system permissions, see <a href=
  "{@docRoot}guide/topics/security/permissions.html#normal-dangerous">Normal
  and Dangerous Permissions</a>.
</p>

<p>
  Your app only needs permissions for actions that it performs directly. Your
  app does not need permission if it is requesting that another app perform the
  task or provide the information. For example, if your app needs to read the
  user's address book, the app needs the {@link
  android.Manifest.permission#READ_CONTACTS READ_CONTACTS} permission. But if
  your app uses an <em>intent</em> to request information from the user's
  Contacts app, your app does not need any permissions, but the
  Contacts app <em>does</em> need to have that permission. For more
  information, see <a href="best-practices.html#perms-vs-intents">Consider
  Using an Intent</a>.
</p>

<h2 id="perm-add">Add Permissions to the Manifest</h2>

<p>
  To declare that your app needs a permission, put a <a href=
  "{@docRoot}guide/topics/manifest/uses-permission-element.html"
  ><code>&lt;uses-permission&gt;</code></a>
  element in your <a href=
  "{@docRoot}guide/topics/manifest/manifest-intro.html">app manifest</a>, as a
  child of the top-level <a href=
  "{@docRoot}guide/topics/manifest/manifest-element.html"><code>&lt;manifest&gt;</code></a>
  element. For example, an app that needs to send SMS messages would have this
  line in the manifest:
</p>

<pre>&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.snazzyapp"&gt;

    <strong>&lt;uses-permission android:name="android.permission.SEND_SMS"/&gt;</strong>
    <!-- other permissions go here -->

    &lt;application ...&gt;
        ...
    &lt;/application&gt;

&lt;/manifest&gt;</pre>

<p>
  The system's behavior after you declare a permission depends on how sensitive
  the permission is. If the permission does not affect user privacy, the system
  grants the permission automatically. If the permission might grant access to
  sensitive user information, the system asks the user to approve the request.
  For more information about the different kinds of permissions, see
  <a href="{@docRoot}guide/topics/security/permissions.html#normal-dangerous">Normal
  and Dangerous Permissions</a>.
</p>
+76 −0
Original line number Diff line number Diff line
page.title=Working with System Permissions
page.tags=permissions
helpoutsWidget=true

@jd:body

<div id="tb-wrapper">

  <div id="tb">
<!--
    <h2>Dependencies and Prerequisites</h2>
    <ul>
      <li></li>
    </ul>
-->
<h2>You should also read</h2>
  <ul>
    <li><a href="{@docRoot}guide/topics/security/permissions.html">
      System Permissions</a></li>
    <li><a href="{@docRoot}training/basics/intents/index.html">
      Interacting with other apps</a></li>
  </ul>
  </div>
</div>

<a class="notice-designers wide"
  href="https://www.google.com/design/spec/patterns/permissions.html">
  <div>
    <h3>Design Patterns</h3>
    <p>Permissions</p>
  </div>
</a>

<p>
  To protect the system's integrity and the user's privacy, Android runs each
  app in a limited access sandbox. If the app wants to use resources or
  information outside of its sandbox, the app has to explicitly request
  permission. Depending on the type of permission the app requests, the system
  may grant the permission automatically, or the system may ask the user to
  grant the permission.
</p>

<p>
  This class shows you how to declare and request permissions for your app.
</p>

<h2>Lessons</h2>

<dl>
  <dt>
    <a href="declaring.html">Declaring Permissions</a>
  </dt>

  <dd>
    Learn how to declare the permissions you need in your app manifest.
  </dd>

  <dt>
    <a href="requesting.html">Requesting Permissions at Run Time</a>
  </dt>

  <dd>
    Learn how to request permissions from the user while the app is running.
    This lesson only applies to apps on devices running Android 6.0 (API level
    23) and higher.
  </dd>

  <dt>
    <a href="best-practices.html">Permissions Best Practices</a>
  </dt>

  <dd>
    Guidelines for creating the best user experience in requesting and using
    permissions.
  </dd>
</dl>
Loading