Files
frameworks_base/docs/html/preview/features/runtime-permissions.jd
Joe Fernandez a06ac3a0d8 docs: M Preview Content Sync #1
This change list is a snapshot of work in progress on other change
lists. If you have conflicts with this change, you should prefer your
own changes over what is contained in this change.

Change-Id: Ied44713d5078c938fab10d29a3b6e720559144b4
2015-05-15 15:46:21 -07:00

353 lines
14 KiB
Plaintext

page.title=Android M Preview Runtime Permissions
@jd:body
<p>
The M Developer Preview introduces a new app permissions model which makes it
less frustrating for users to install and upgrade apps. If an app running on
M supports the new permissions model, the user does not have to grant any
permissions when they install or upgrade the app. Instead, the app requests
permissions as they are needed, and the system shows a dialog to the user
asking for the permission.
</p>
<p>
If an app supports the new permissions model, it can still be installed and
run on devices running older versions of Android, using the old permissions
model on those devices.
</p>
<h2>
Overview
</h2>
<p>
If an app's target SDK version is the M developer preview, that indicates
that the app uses the new permissions model:
</p>
<ul>
<li>Permissions are divided into <em>permission groups</em>, based on their
functionality. For example, all permissions relating to the camera and photo
roll are grouped in the Camera permission group,
[link]android.permission-group.CAMERA[/link].
</li>
<li>The app declares all the permissions it needs in the manifest, as in
earlier Android platforms.
</li>
<li>When the user installs or updates the app, the app is granted just those
permissions it requests that fall under <a href=
"https://android-preview.googleplex.com/reference/android/content/pm/PermissionInfo.html#PROTECTION_NORMAL">
<code>PROTECTION_NORMAL</code></a>, as well as signature and system permissions, as
described below. The user is <em>not</em> prompted to grant any permissions
at this time.
</li>
<li>When the app needs to perform any action that requires a permission, it
first checks whether it has that permission already. If it does not, it
requests to be granted that permission.
</li>
<li>When the app requests a permission, the system shows a dialog box to the
user, then calls the app's callback function to notify it whether the
permission was granted. If a user grants a permission, the app is given all
permissions in that permission's functional area that were declared in the
app manifest.
</li>
<li>If the app is not granted an appropriate permission, it should handle the
failure cleanly. For example, if the permission is just needed for an added
feature, the app can disable that feature. If the permission is essential for
the app to function, the app might disable all its functionality and inform
the user that they need to grant that permission.
</li>
<li>Users can always go to the app's <b>Settings</b> screen and turn on or
off any of the app's permissions.
<!-- insert screenshot of settings screen-->
If a user turns off an app's permissions, the app is
<em>not</em> notified.
</li>
</ul>
<h3>
System Apps and Signature Permissions
</h3>
<p>
Ordinarily, an app is just granted the <a href=
"https://android-preview.googleplex.com/reference/android/content/pm/PermissionInfo.html#PROTECTION_NORMAL">
<code>PROTECTION_NORMAL</code></a> permissions when it is installed. However,
under some circumstances the app is granted more permissions:
</p>
<ul>
<li>If an app is part of the system image, it is automatically granted all
the permissions listed in its manifest.
</li>
<li>Apps are granted all permissions listed in the manifest that fall under
<a href=
"https://android-preview.googleplex.com/reference/android/content/pm/PermissionInfo.html#PROTECTION_SIGNATURE">
PROTECTION_SIGNATURE</a>, if the app's signature matches the signature of
the app that declares the permissions.
</li>
</ul>
<p>
In both cases, the user can still revoke permissions at any time by going to
the app's <b>Settings</b> screen, so the app should continue to check for
permissions at run time and request them if necessary.
</p>
<h3>
Forwards and Backwards Compatibility
</h3>
<p>
If an app does not target the M developer preview, it continues to use the
old permissions model even on M devices. When the app is installed, the
system asks the user to grant all permissions listed in the app's manifest.
</p>
<p>
If an app using the new permissions model is run on a pre-M device, the
system treats it the same as any other app. Once again, the system asks the
user to grant all declared permissions at install time.
</p>
<h2 id="">Coding for Runtime Permissions</h2>
<p>
If your app targets the new M Developer Preview, you must use the new
permissions model. This means that in addition to declaring your needed
permissions in the manifest, you must also check to see if you have the
permissions at run time, and request the permissions if you do not already
have them.
</p>
<h3>
Enabling the New Permissions Model
</h3>
<p>
To enable the new M Developer Preview permissions model, set the app's
<a href=
"http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target">
targetSdkVersion</a> attribute to "M". Doing this enables all the new
permissions features.
</p>
<!-- TODO: Insert manifest snippet -->
<h3>
Designating a Permission for M Only
</h3>
<p>
You can use the new <code>&lt;uses-permission-sdk-m&gt;</code> element in the
app manifest to indicate that a permission is only needed on the M platform.
If you declare a permission this way, then whenever the app is installed on
an older device, the user is not prompted to grant the permission and the
permission is not granted to the app. This allows you to add new permissions
to updated versions of your app without forcing users to grant permissions
when they install the update.
</p>
<p>
If the app is running on a device with the M developer preview,
<code>&lt;uses-permission-sdk-m&gt;</code> behaves the same as
<code>&lt;uses-permission&gt;</code>. The user is not prompted to grant any
permissions when the app is installed, and the app requests permissions as
they are needed.
</p>
<h3 id="prompting">
Prompting for Permissions on the M Preview
</h3>
<p>
If your app uses the new M Developer Preview permissions model, the user is
not asked to grant all permissions when the app is first launched on a device
running the M Preview. Instead, your app requests permissions as they are
needed. When your app requests a permission, the system shows a dialog to the
user.
</p>
<p>
An app should follow this workflow to request permissions on an Android M
device. The device can check what platform it's running on by checking the
value of {@link android.os.Build.VERSION#SDK_INT Build.VERSION.SDK_INT}. If
the device is running the M Developer Preview, {@link
android.os.Build.VERSION#SDK_INT SDK_INT} is 23.
<!-- TODO: Confirm this number -->
</p>
<ol>
<li>When the user tries to do something that requires a permission, the app
checks to see if it currently has permission to perform this operation. To do
this, the app calls
<a href="https://android-preview.googleplex.com/reference/android/content/Context.html#checkSelfPermission(java.lang.String)"><code>Context.CheckSelfPermission(<em>permission_name</em>)</code></a> . The
app should do this even if it knows the user has already granted that
permission, since the user can revoke an app's permissions at any time. For
example, if a user wants to use an app to take a picture, the app calls
<a href="https://android-preview.googleplex.com/reference/android/content/Context.html#checkSelfPermission(java.lang.String)"><code>Context.CheckSelfPermission(Manifest.permission.CAMERA)</code></a>.
</li>
<!-- TODO: Full list of permissions (or link to that list),
and how they break down by functional area]-->
<li>If the permission is not already granted to the app, the app calls
<a href=
"https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)">
<code>requestPermissions()</code></a> to request the
appropriate permission or permissions. This method functions
asynchronously.
<!-- TODO: insert code snippet showing permission check and request -->
</li>
<li>The system presents a dialog box to the user.
<!-- TODO: insert screenshot of permissions dialog box -->
When the user responds, the system calls <a href=
"https://android-preview.googleplex.com/reference/android/app/Activity.html#onRequestPermissionsResult(int,%20java.lang.String[],%20int[])">
<code>Activity.onRequestPermissionsResult()</code></a> with the
results; your app needs to override that method. The callback is passed the
same request code you passed to <a href=
"https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)">
<code>requestPermissions()</code></a>.
<!-- TODO: Insert code snippet of callback method -->
</li>
<li>If the user grants a permission, the app is given all permissions
in that functional area that are listed in the app manifest.
If the request is denied, you should take appropriate action. For
example, you might disable any menu actions that depend on this permission.
</li>
</ul>
<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,
when an app asks for that permission with <a href=
"https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)">
<code>requestPermissions()</code></a>, the
system immediately denies the request. For this reason, your app cannot
assume that any direct interaction with the user has taken place.
</p>
<p>
If your app runs on a device that has SDK 22 or lower, the app uses the old
permissions model. When the user installs the app, they are prompted to grant
all the permissions your app requests in its manifest, except for those
permissions which are labeled with <code>&lt;uses-permission-sdk-m&gt;</code>.
</p>
<h2 id="">Best Practices</h2>
<p>
The new permissions model gives users a smoother experience, and makes it
easier for them to install apps and feel comfortable with what the apps are
doing. We recommend the following best practices to take full advantage of
the new model.
</p>
<h3>
Don't Overwhelm the User
</h3>
<p>
If you confront the user with a lot of permissions requests 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. In that case, it might make sense to ask for all the permissions as soon
as the app launches.
<!-- TODO: insert screenshot of dialog box asking for several permissions -->
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 to give 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 that 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 app's essential
permissions at the end of the tutorial sequence.
</p>
<h3>
Explain Why You Need Permissions
</h3>
<p>
The permissions screen shown by the system when you call <a href=
"https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)">
<code>requestPermissions()</code></a> says what permission your app wants,
but doesn't say why you want it. 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 you call <a href=
"https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)">
<code>requestPermissions()</code></a>.
</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
wanted 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
<a href=
"https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)">
<code>requestPermissions()</code></a>.
</p>
<p>
As noted, one way to do this 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 demonstrate its "share photos with your contacts"
feature, then tell the user that they'll need to give permission for the app
to see the user's contacts, and <em>then</em> call <a href=
"https://android-preview.googleplex.com/reference/android/app/Activity.html#requestPermissions(java.lang.String[],%20int)">
<code>requestPermissions()</code></a>
to get that access. Of course, some users will want to skip the tutorial, so
you'll still need to check for and request permissions during the app's
normal operation.
</p>
<h3>
Opt Out If Necessary
</h3>
<p>
Until you are ready to use the new permissions model, you can opt out simply
by setting your app's <a href=
"http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target">
targetSdkVersion</a> to 22 or less. If you do this, the system will use the
old permissions model. When the user downloads the app, they will be prompted
to grant all the permissions listed in the manifest.
</p>
<p>
With the M Developer Preview, users can turn off permissions for <em>any</em>
app from the app's Settings page, regardless of what SDK version the app
targets. For this reason, it's a good idea to follow the steps described in
<a href="#prompting">"Prompting for Permissions on the M Preview"</a> even if
your app doesn't fully support the new permissions model.
</p>
<p class="note">
<strong>Note:</strong> If a user turns off permissions for a legacy app, the system
silently disables the appropriate functionality. When the app attempts to
perform an operation that requires that permission, the operation will not
necessarily cause an exception. Instead, it might return an empty data set or
otherwise signal an error.
</p>