ae70b69880
Change-Id: I9045f51578f211301a5feb20423b4aa3a5fa2d94
797 lines
26 KiB
Plaintext
797 lines
26 KiB
Plaintext
page.title=Permissions
|
|
page.tags=previewresources, androidm
|
|
page.keywords=permissions, runtime, preview
|
|
page.image=images/permissions_check.png
|
|
@jd:body
|
|
|
|
|
|
<div id="qv-wrapper">
|
|
<div id="qv">
|
|
<h2>Quickview</h2>
|
|
<ul>
|
|
<li>If your app targets the M Preview SDK, it prompts users to grant
|
|
permissions at runtime, instead of install time.</li>
|
|
<li>Users can revoke permissions at any time from the app Settings
|
|
screen.</li>
|
|
<li>Your app needs to check that it has the permissions it needs every
|
|
time it runs.</li>
|
|
</ul>
|
|
|
|
<h2>In this document</h2>
|
|
<ol>
|
|
<li><a href="#overview">Overview</a></li>
|
|
<li><a href="#coding">Coding for Runtime Permissions</a></li>
|
|
<li><a href="#testing">Testing Runtime Permissions</a></li>
|
|
<li><a href="#best-practices">Best Practices</a></li>
|
|
</ol>
|
|
|
|
<!--
|
|
<h2>Related Samples</h2>
|
|
<ol>
|
|
<li></li>
|
|
</ol>
|
|
-->
|
|
|
|
<!--
|
|
<h2>See also</h2>
|
|
<ol>
|
|
<li></li>
|
|
</ol>
|
|
-->
|
|
</div> <!-- qv -->
|
|
</div> <!-- qv-wrapper -->
|
|
|
|
|
|
<p>
|
|
The M Developer Preview introduces a new app permissions model which
|
|
streamlines the process for users to install and upgrade apps. If an app
|
|
running on the M Preview 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 it needs them, 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 id="overview">
|
|
Overview
|
|
</h2>
|
|
|
|
<p>
|
|
With the M Developer Preview, the platform introduces a new app permissions
|
|
model. Here's a summary of the key components of this new model:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<strong>Declaring Permissions:</strong> The app declares all the
|
|
permissions it needs in the manifest, as in earlier Android platforms.
|
|
</li>
|
|
|
|
<li>
|
|
<strong>Permission Groups:</strong> Permissions are divided into
|
|
<em>permission groups</em>, based on their functionality. For example, the
|
|
<code>CONTACTS</code> permission group contains permissions to read and
|
|
write the user's contacts and profile information.
|
|
</li>
|
|
|
|
<li>
|
|
<p><strong>Limited Permissions Granted at Install Time:</strong> When the
|
|
user installs or updates the app, the system grants the app all
|
|
permissions that the app requests that fall under {@link
|
|
android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}.
|
|
For example, alarm clock and internet permissions fall under {@link
|
|
android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}, so
|
|
they are automatically granted at install time.
|
|
</p>
|
|
|
|
<p>The system may also grant the app signature and system permissions, as
|
|
described in <a href="#system-apps">System apps and signature
|
|
permissions</a>. The user is <em>not</em> prompted to grant any permissions
|
|
at install time.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<strong>User Grants Permissions at Run-Time:</strong> When the app requests
|
|
a permission, the system shows a dialog 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>
|
|
|
|
</ul>
|
|
|
|
<p>
|
|
This permission model changes the way your app behaves for features that
|
|
require permissions. Here's a summary of the development practices you should
|
|
follow to adjust to this model:
|
|
</p>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
<strong>Always Check for Permissions:</strong> When the app needs to
|
|
perform any action that requires a permission, it should first check
|
|
whether it has that permission already. If it does not, it requests to be
|
|
granted that permission.
|
|
</li>
|
|
|
|
<li>
|
|
<strong>Handle Lack of Permissions Gracefully:</strong> 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>
|
|
|
|
<div class="figure" style="width:220px">
|
|
<img src="images/app-permissions-screen.png" srcset=
|
|
"images/app-permissions-screen@2x.png 2x" alt="" width="220" height=
|
|
"375">
|
|
<p class="img-caption">
|
|
<strong>Figure 2.</strong> Permission screen in the app's Settings.
|
|
</p>
|
|
</div>
|
|
|
|
<li>
|
|
<strong>Permissions are Revocable:</strong> Users can revoke an app's
|
|
permissions at any time. If a user turns off an app's permissions, the app
|
|
is <em>not</em> notified. Once again, your app should verify that it has
|
|
needed permissions before performing any restricted actions.
|
|
</li>
|
|
</ul>
|
|
|
|
<p class="note">
|
|
<strong>Note:</strong> If an app targets the M Developer Preview, it
|
|
<em>must</em> use the new permissions model.
|
|
</p>
|
|
|
|
<p>
|
|
As of the launch of the M Developer Preview, not all Google apps fully
|
|
implement the new permissions model. Google is updating these apps over
|
|
the course of the M Developer Preview to properly respect Permissions toggle
|
|
settings.
|
|
</p>
|
|
|
|
<p class="note">
|
|
<strong>Note:</strong> If your app has its own API surface, do not proxy
|
|
permissions without first ensuring the caller has the requisite permissions
|
|
to access that data.
|
|
</p>
|
|
|
|
<h3 id="system-apps">
|
|
System apps and signature permissions
|
|
</h3>
|
|
|
|
<p>
|
|
Ordinarily, when the user installs an app, the system only grants the app the
|
|
{@link android.content.pm.PermissionInfo#PROTECTION_NORMAL
|
|
PROTECTION_NORMAL}. However, under some circumstances the system grants the
|
|
app 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>If the app requests permissions in the manifest that fall under {@link
|
|
android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE},
|
|
and the app is signed with the same certificate as the app that declared
|
|
those permissions, the system grants the requesting app those permissions on
|
|
installation.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
In both cases, the user can still revoke permissions at any time by going to
|
|
the system's <strong>Settings</strong> screen and choosing <strong>Apps
|
|
></strong> <i>app_name</i> <strong>> Permissions</strong>. The app
|
|
should continue to check for permissions at run time and request them if
|
|
necessary.
|
|
</p>
|
|
|
|
<h3 id="compatibility">
|
|
Forwards and backwards compatibility
|
|
</h3>
|
|
|
|
<p>
|
|
If an app does not target the M Developer Preview, the app continues to use
|
|
the old permissions model even on M Preview devices. When the user installs
|
|
the app, the system asks the user to grant all permissions listed in the
|
|
app's manifest.
|
|
</p>
|
|
|
|
<p class="note">
|
|
<strong>Note:</strong> On devices running the M Developer Preview, a user can
|
|
turn off permissions for any app (including legacy apps) from the app's
|
|
Settings screen. 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,
|
|
signal an error, or otherwise exhibit unexpected behavior. For example, if you
|
|
query a calendar without permission, the method returns an empty data set.
|
|
</p>
|
|
|
|
<p>
|
|
If you install an app using the new permissions model on a device that is not
|
|
running the M Preview,
|
|
the system treats it the same as any other app: the system asks
|
|
the user to grant all declared permissions at install time.
|
|
</p>
|
|
|
|
<p class="note">
|
|
<strong>Note:</strong> For the preview release, you must set the minimum SDK
|
|
version to the M Preview SDK to compile with the preview SDK. This means you
|
|
will not be able to test such apps on older platforms during the developer
|
|
preview.
|
|
</p>
|
|
|
|
<h3 id="perms-vs-intents">Permissions versus intents</h3>
|
|
|
|
<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 intent 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
|
|
<code>android.permission.CAMERA</code> 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 control, you can just use an {@link
|
|
android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} intent
|
|
to request an image. When you start the intent, the user is prompted to
|
|
choose a camera app (if there isn't already a default camera app), and that
|
|
app takes the picture. The camera 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, the first time you perform
|
|
the operation. 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="coding">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 id="enabling">
|
|
Enabling the new permissions model
|
|
</h3>
|
|
|
|
<p>
|
|
To enable the new M Developer Preview permissions model, set the app's
|
|
<code>targetSdkVersion</code> attribute to <code>"MNC"</code>, and
|
|
<code>compileSdkVersion</code> to <code>"android-MNC"</code>. Doing so
|
|
enables all the new permissions features.
|
|
</p>
|
|
|
|
<p>
|
|
For the preview release, you must set <code>minSdkVersion</code> to
|
|
<code>"MNC"</code> to compile with the preview SDK.
|
|
</p>
|
|
|
|
<h3 id="m-only-perm">
|
|
Designating a permission for the M Preview 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 Developer Preview. If
|
|
you declare a permission this way, then whenever the app is installed on an
|
|
older device, the system does not prompt the user or grant the
|
|
permission to the app. By using the <code><uses-permission-sdk-m></code>
|
|
element, you can 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><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>.
|
|
The system does not prompt the user to grant any permissions when they install
|
|
the app, and the app requests permissions as they are needed.
|
|
</p>
|
|
|
|
<h3 id="prompting">
|
|
Prompting for permissions
|
|
</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>
|
|
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>
|
|
|
|
<h4 id="check-platform">Check what platform the app is running on</h4>
|
|
|
|
<p>
|
|
This permissions model is only supported on devices running the M Developer
|
|
Preview. Before calling any of these methods, the app should verify
|
|
what platform it's running on
|
|
by checking the value of {@link android.os.Build.VERSION#CODENAME
|
|
Build.VERSION.CODENAME}. If the device is running the M Developer Preview,
|
|
{@link android.os.Build.VERSION#CODENAME CODENAME} is <code>"MNC"</code>.
|
|
</p>
|
|
|
|
<h4 id="check-for-permission">Check if the app has the needed permission</h4>
|
|
|
|
<p>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
|
|
<code>Context.checkSelfPermission(<i>permission_name</i>)</code>. The app
|
|
should perform this check 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
|
|
<code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>.</p>
|
|
|
|
<p class="table-caption" id="permission-groups">
|
|
<strong>Table 1.</strong> Permissions and permission groups.</p>
|
|
<table>
|
|
<tr>
|
|
<th scope="col">Permission Group</th>
|
|
<th scope="col">Permissions</th>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>android.permission-group.CALENDAR</code></td>
|
|
<td>
|
|
<ul>
|
|
<li>
|
|
<code>android.permission.READ_CALENDAR</code>
|
|
</li>
|
|
</ul>
|
|
<ul>
|
|
<li>
|
|
<code>android.permission.WRITE_CALENDAR</code>
|
|
</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>android.permission-group.CAMERA</code></td>
|
|
<td>
|
|
<ul>
|
|
<li>
|
|
<code>android.permission.CAMERA</code>
|
|
</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>android.permission-group.CONTACTS</code></td>
|
|
<td>
|
|
<ul>
|
|
<li>
|
|
<code>android.permission.READ_CONTACTS</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.WRITE_CONTACTS</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.READ_PROFILE</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.WRITE_PROFILE</code>
|
|
</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>android.permission-group.LOCATION</code></td>
|
|
<td>
|
|
<ul>
|
|
<li>
|
|
<code>android.permission.ACCESS_FINE_LOCATION</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.ACCESS_COARSE_LOCATION</code>
|
|
</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>android.permission-group.MICROPHONE</code></td>
|
|
<td>
|
|
<ul>
|
|
<li>
|
|
<code>android.permission.RECORD_AUDIO</code>
|
|
</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>android.permission-group.PHONE</code></td>
|
|
<td>
|
|
<ul>
|
|
<li>
|
|
<code>android.permission.READ_PHONE_STATE</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.CALL_PHONE</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.READ_CALL_LOG</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.WRITE_CALL_LOG</code>
|
|
</li>
|
|
<li>
|
|
<code>com.android.voicemail.permission.ADD_VOICEMAIL</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.USE_SIP</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.PROCESS_OUTGOING_CALLS</code>
|
|
</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>android.permission-group.SENSORS</code></td>
|
|
<td>
|
|
<ul>
|
|
<li>
|
|
<code>android.permission.BODY_SENSORS</code>
|
|
</li>
|
|
</ul>
|
|
<ul>
|
|
<li>
|
|
<code>android.permission.USE_FINGERPRINT</code>
|
|
</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>android.permission-group.SMS</code></td>
|
|
<td>
|
|
<ul>
|
|
<li>
|
|
<code>android.permission.SEND_SMS</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.RECEIVE_SMS</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.READ_SMS</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.RECEIVE_WAP_PUSH</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.RECEIVE_MMS</code>
|
|
</li>
|
|
<li>
|
|
<code>android.permission.READ_CELL_BROADCASTS</code>
|
|
</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
<h4 id="request-permissions">Request permissions if necessary</h4>
|
|
|
|
<p>If the app doesn't already have the permission it needs, the app calls the
|
|
<code>Activity.requestPermissions(String[], int)</code> method to
|
|
request the appropriate permission or permissions. The app passes the
|
|
permission or permissions it wants, and also an integer "request code".
|
|
This method functions asynchronously: it returns right away, and after
|
|
the user responds to the dialog box, the system calls the app's callback
|
|
method with the results, passing the same "request code" that the app passed
|
|
to <code>requestPermissions()</code>.</p>
|
|
|
|
<p>The following code code checks if the app has permission to read the
|
|
user's contacts, and requests the permission if necessary:</p>
|
|
|
|
<pre>
|
|
if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
|
|
!= PackageManager.PERMISSION_GRANTED) {
|
|
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
|
|
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
|
|
|
|
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
|
|
// app-defined int constant
|
|
|
|
return;
|
|
}
|
|
</pre>
|
|
|
|
<h4 id="handle-response">Handle the permissions request response</h4>
|
|
|
|
<p>
|
|
When an app requests permissions, the system presents a dialog box to the
|
|
user. When the user responds, the system invokes your app's
|
|
<code>Activity.onRequestPermissionsResult(int, String[], int[])</code>
|
|
passing it the user response. Your app needs to override that method. The
|
|
callback is passed the same request code you passed to
|
|
<code>requestPermissions()</code>. For example, if an app requests
|
|
<code>READ_CONTACTS</code> access it might have the following callback
|
|
method:
|
|
</p>
|
|
|
|
<pre>
|
|
@Override
|
|
public void onRequestPermissionsResult(int requestCode,
|
|
String permissions[], int[] grantResults) {
|
|
switch (requestCode) {
|
|
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
|
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
|
|
// permission was granted, yay! do the
|
|
// calendar task you need to do.
|
|
|
|
} else {
|
|
|
|
// permission denied, boo! Disable the
|
|
// functionality that depends on this permission.
|
|
}
|
|
return;
|
|
}
|
|
|
|
// other 'switch' lines to check for other
|
|
// permissions this app might request
|
|
}
|
|
}
|
|
</pre>
|
|
|
|
<p>If the user grants a permission, the system gives the app all permissions
|
|
that the app manifest lists for that functional area. If the user denies the
|
|
request, you should take appropriate action. For example, you might disable
|
|
any menu actions that depend on this permission.
|
|
</li>
|
|
</p>
|
|
|
|
<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 uses <code>requestPermissions()</code> to ask for that permission,
|
|
the system immediately denies the request. In this case, the system calls
|
|
your <code>onRequestPermissionsResult()</code> the same way it would if the
|
|
user had explicitly rejected your request again. For this reason, your app
|
|
cannot assume that any direct interaction with the user has taken place.
|
|
</p>
|
|
|
|
<h2 id="testing">Testing Runtime Permissions</h2>
|
|
|
|
|
|
<p>
|
|
If your app targets the M Developer Preview, you must test that it
|
|
handles permissions properly. You cannot assume that your app has any
|
|
particular permissions when it runs. When the app is first launched, it is
|
|
likely to have no permissions, and the user can revoke or restore permissions
|
|
at any time.
|
|
</p>
|
|
|
|
<p>
|
|
You should test your app to make sure it behaves properly under all
|
|
permission situations. With the M Preview SDK, we have provided new
|
|
<a href="{@docRoot}tools/help/adb.html">Android
|
|
Debug Bridge (adb)</a> commands to enable you to test your app with whatever
|
|
permissions settings you need to try.
|
|
</p>
|
|
|
|
<h3>
|
|
New adb commands and options
|
|
</h3>
|
|
|
|
<p>
|
|
The M Preview SDK Platform-tools provides several new commands to let you test
|
|
how your app handles permissions.
|
|
</p>
|
|
|
|
<h4>
|
|
Install with permissions
|
|
</h4>
|
|
|
|
<p>
|
|
You can use the <a href="{@docRoot}tools/help/adb.html#move"><code>adb
|
|
install</code></a> command's new <code>-g</code> option, which installs the
|
|
app and grants all permissions listed in its manifest:
|
|
</p>
|
|
|
|
<pre class="no-pretty-print">
|
|
$ adb install -g <path_to_apk>
|
|
</pre>
|
|
|
|
<h4>
|
|
Grant and revoke permissions
|
|
</h4>
|
|
|
|
<p>
|
|
You can use new ADB <a href="{@docRoot}tools/help/adb.html#pm">package manager
|
|
(pm)</a> commands to grant and revoke permissions to an installed app.
|
|
This functionality can be useful for automated testing.
|
|
</p>
|
|
|
|
<p>
|
|
To grant a permission, use the package manager's <code>grant</code> command:
|
|
</p>
|
|
|
|
<pre class="no-pretty-print">
|
|
$ adb pm grant <package_name> <permission_name>
|
|
</pre>
|
|
|
|
<p>
|
|
For example, to grant the com.example.myapp package permission to record
|
|
audio, use this command:
|
|
</p>
|
|
|
|
<pre class="no-pretty-print">
|
|
$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
|
|
</pre>
|
|
|
|
<p>
|
|
To revoke a permission, use the package manager's <code>revoke</code> command:
|
|
</p>
|
|
|
|
<pre class="no-pretty-print">
|
|
$ adb pm revoke <package_name> <permission_name>
|
|
</pre>
|
|
|
|
<h2 id="best-practices">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 id="bp-what-you-need">Only ask for permissions you need</h3>
|
|
|
|
<p>
|
|
Every time you ask for a permission, you force the user to make a decision.
|
|
If the user turns down the request, that reduces your app's functionality.
|
|
You should minimize the number of times you make these requests.
|
|
</p>
|
|
|
|
<p>
|
|
For example, quite often your app can get needed functionality by using an
|
|
<a href="{@docRoot}guide/components/intents-filters.html">intent</a> instead
|
|
of asking for permissions. If your app needs to take pictures with the
|
|
phone's camera, your app can use a {@link
|
|
android.provider.MediaStore#ACTION_IMAGE_CAPTURE
|
|
MediaStore.ACTION_IMAGE_CAPTURE} intent. When your app executes the intent, the
|
|
system prompts the user to choose an already-installed camera app to take the
|
|
picture.
|
|
</p>
|
|
|
|
<h3 id="bp-dont-overwhelm">
|
|
Don't overwhelm the user
|
|
</h3>
|
|
|
|
<p>
|
|
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. In that case, it might make sense to ask for all the 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 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 the app's essential
|
|
permissions at the end of the tutorial sequence.
|
|
</p>
|
|
|
|
<h3 id="bp-explain">
|
|
Explain why you need permissions
|
|
</h3>
|
|
|
|
<p>
|
|
The permissions dialog shown by the system when you call
|
|
<code>requestPermissions()</code> 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 <code>requestPermissions()</code>.
|
|
</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
|
|
<code>requestPermissions()</code>.
|
|
</p>
|
|
|
|
<p>
|
|
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 can 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 can then call <code>requestPermissions()</code> 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>
|