| 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> |