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
353 lines
14 KiB
Plaintext
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><uses-permission-sdk-m></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><uses-permission-sdk-m></code> behaves the same as
|
|
<code><uses-permission></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><uses-permission-sdk-m></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>
|