Showing posts with label permissions. Show all posts
Showing posts with label permissions. Show all posts

Tuesday, February 2, 2016

Marshmallow and User Data



Posted by Joanna Smith, Developer Advocate and Giles Hogben, Google Privacy Team



Marshmallow introduced several changes that were designed to help your app look after user data. The goal was to make it easier for developers to do the right thing. So as Android 6.0, Marshmallow, gains traction, we challenge you to do just that.



This post highlights the key considerations for user trust when it comes to runtime permissions and hardware identifiers, and points you to new best practices documentation to clarify what to aim for in your own app.



Permission Changes


With Marshmallow, permissions have moved from install-time to runtime. This is a mandatory change for SDK 23+, meaning it will affect all developers and all applications targeting Android 6.0. Your app will need to be updated anyway, so your challenge is to do so thoughtfully.



Runtime permissions mean that your app can now request access to sensitive information in the context that it will be used. This gives you a chance to explain the need for the permission, without scaring users with a long list of requests.



Permissions are also now organized into groups, so that users can make an informed decision without needing to understand technical jargon. By allowing your users to make a decision, they may decide not to grant a permission or to revoke a previously-granted permission. So, your app needs to be thoughtful when handling API calls requiring permissions that may have been denied, and about building in graceful failure-handling so that your users can still interact with the rest of your app.



Identifier Changes



The other aspect of user trust is doing the right thing with user data. With Marshmallow, we are turning off access to some kinds of data in order to direct developers down this path.



Most notably, Local WiFi and Bluetooth MAC addresses are no longer available. The getMacAddress() method of a WifiInfo object and the BluetoothAdapter.getDefaultAdapter().getAddress() method will both return 02:00:00:00:00:00 from now on.




However, Google Play Services now provides Instance IDs, which identify an application instance running on a device. Instance IDs provide a reliable alternative to non-resettable, device-scoped hardware IDs, as they will not persist across a factory reset and are scoped to an app instance. See the Google Developer's What is Instance ID? help article for more information.



What’s Next


User trust depends largely on what users see and how they feel. Mishandling permissions and identifiers increases the risk of unwanted/unintended tracking, and can result in users feeling that your app doesn’t actually care about the user. So to help you get it right, we’ve created new documentation that should enable developers to be certain that their app is doing the right thing for their users.







So happy developing! May your apps make users happy, and may your reviews reflect that. :)


Sunday, January 24, 2016

Play Games Permissions are changing in 2016

Play Games Permissions are changing in 2016

Posted by Wolff Dobson, Developer Advocate



We’re taking steps to reduce sign-in friction and unnecessary permission requests for players by moving the Games APIs to a new model. The new interaction is:




  • Players are prompted to sign-in once per account, rather than once per game

  • Players no longer need their account upgraded to Google+ to use Play Games services

  • Once players have signed-in for the first time, they will no longer need to sign in to any future games; they will be automatically signed in

  • Note: Players can turn off auto-sign-in through the Play Games App’s settings



Advantages:


  • Once a user signs in for first time, new games will generally be able to sign in without any user interaction

  • There is no consent screen required for signing in on any particular game. Sign-in will be automatic to each new game.



In order to respect user’s privacy and avoid revealing their real name, we also have to change the way player IDs work.




  • For existing players: Games will continue to get their Google+ ID (also called “player ID” in previous documentation) when they sign in.

  • For new players: Games will get a new player ID which is not the same as the previous IDs we’ve used.



Potential issues



Most games should see no interruption or change in service. There are a handful of cases, however, where some change is required.



Below are some issues, along with potential solutions.



These are:



  1. Asking for the Google+ scope unnecessarily

    • Issue: Your users will get unnecessary, potentially disturbing pop-up consent windows
    • Solution: Don’t request any additional scopes unless you absolutely need them

  2. Using the Play Games player ID for other Google APIs that are not games

    • Issue: You will not get valid data back from these other endpoints.
    • Solution: Don’t use player ID for other Google APIs.

  3. Using mobile/client access tokens on the server

    • Issue: Your access token may not contain the information you’re looking for

      • ...and this is not recommended in the first place.

    • Solution: Use the new GetServerAuthCode API instead.



Let’s cover each of these issues in detail.



Issue: Asking for unnecessary scopes


Early versions of our samples and documentation created a GoogleApiClient as follows:



 // Don’t do it this way!  
GoogleApiClient gac = new GoogleApiClient.Builder(this, this, this)
.addApi(Games.API)
.addScope(Plus.SCOPE_PLUS_LOGIN) // The bad part
.build();
// Don’t do it this way!


In this case, the developer is specifically requesting the plus.login scope. If you ask for plus.login, your users will get a consent dialog.



Solution: Ask only for the scopes you need


Remove any unneeded scopes from your GoogleApiClient construction along with any APIs you no longer use.


 // This way you won’t get a consent screen  
GoogleApiClient gac = new GoogleApiClient.Builder(this, this, this)
.addApi(Games.API)
.build();
// This way you won’t get a consent screen


For Google+ users


If your app uses specific Google+ features, such as requiring access to the player’s real-world Google+ social graph, be aware that new users will still be required to have a G+ profile to use your game. (Existing users who have already signed in won’t be asked to re-consent).



To require Google+ accounts to use your game, change your Games.API declaration to the following:


 .addApi(Games.API, new GamesOptions.Builder()  
.setRequireGooglePlus(true).build())


This will ensure that your game continues to ask for the necessary permissions/scopes to continue using the player’s real-world social graph and real name profile.



Issue: Using the Player ID as another ID


If you call the Games.getCurrentPlayerId() API, the value returned here is the identifier that Games uses for this player.



Traditionally, this value could be passed into other APIs such as Plus.PeopleApi.load. In the new model, this is no longer the case. Player IDs are ONLY valid for use with Games APIs.



Solution - Don’t mix IDs


The Games APIs (those accessed from com.google.android.gms.games) all use the Player ID, and as long as you use only those, they are guaranteed to work with the new IDs.



Issue: Using mobile/client access tokens on the server


A common pattern we’ve seen is:



  • Use GoogleAuthUtil to obtain an access token

  • Send this token to a server

  • On the server, call Google to verify the authenticity. This is most commonly done by calling https://www.googleapis.com/oauth2/v1/tokeninfo and looking at the response



This is not recommended in the first place, and is even more not-recommended after the shift in scopes.



Reasons not to do this:



  • It requires your app to know the current account the user is using, which requires holding the GET_ACCOUNTS permission. On Android M, this will result in the user being asked to share their contacts with your app at runtime, which can be intimidating.

  • The tokeninfo endpoint isn’t really designed for this use case - it’s primarily designed as a debugging tool, not as a production API. This means that you may be rate limited in the future if you call this API.

  • The user_id returned by token info may no longer be present with the new model. And even if it is present, the value won’t be the same as the new player ID. (See problem 2 above)

  • The token could expire at any time (access token expiration times are not a guarantee).

  • Using client tokens on the server require extra validation checks to make sure the token is not granted to a different application.



Solution: Use the new GetServerAuthCode flow



Fortunately, the solution is known, and is basically the same as our server-side auth recommendations for web.





  1. Upgrade to the latest version of Google Play Services SDK - at least 8.4.87.

  2. Create a server client ID if you don’t already have one

    1. Go to the Google Developer Console, and select your project

    2. From the left nav, select API Manager, then select Credentials

    3. Select “New Credentials” and choose “OAuth Client ID”

    4. Select “Web Application” and name it something useful for your application

    5. The client id for this web application is now your server client id.

  3. In your game, connect your GoogleApiClient as normal.

  4. Once connected, call the following API:

    1. Games.getGamesServerAuthCode(googleApiClient, “your_server_client_id”)

    2. If you were using GoogleAuthUtil before, you were probably calling this on a background thread - in which case the code looks like this:




 // Good way  
{
GetServerAuthCodeResult result =
Games.getGamesServerAuthCode(gac, clientId).await();
if (result.isSuccess()) {
String authCode = result.getCode();
// Send code to server.
}
}
// Good way



  1. Send the auth code to your server, exactly the same as before.

  2. On your server, make an RPC to https://www.googleapis.com/oauth2/v4/token to exchange the auth code for an access token, probably using a Google Apis Client Library.

    1. You’ll have to provide the server client ID, server client secret (listed in the Developer Console when you created the server client ID), and the auth code.

    2. See more details here: https://developers.google.com/identity/protocols/OAuth2WebServer?utm_campaign=play games_discussion_permissions_012316&utm_source=anddev&utm_medium=blog#handlingresponse

    3. No, really:  You should use a Google Apis Client Library to make this process easier.

  3. Once you have the access token, you can now call www.googleapis.com/games/v1/applications/<app_id>/verify/ using that access token.

    1. Pass the auth token in a header as follows:

      1. “Authorization: OAuth <access_token>”

    2. The response value will contain the player ID for the user. This is the correct player ID to use for this user.

    3. This access token can be used to make additional server-to-server calls as needed.

Note: This API will only return a 200 if the access token was actually issued to your web app.




In summary


Let’s be very clear: If you do nothing, unless you are depending explicitly on Google+ features, you will see no change in functionality, and a smoother sign-in experience.



If you are:




  • Requesting Google+ scopes without using them, it’s a good idea to stop using them from here out.

  • Sending client access tokens to your server, we strongly suggest you use getGamesServerAuthCode() instead.



Thanks, and keep making awesome games!













Thursday, November 19, 2015

API 23 SDK now available for Android Wear

Posted by Wayne Piekarski, Developer Advocate



The new LG Watch Urbane 2nd Edition LTE is the first watch to run Android 6.0 Marshmallow (API 23) for Android Wear. Currently, all other Android Wear watches implement API 22, and in the coming months, these will receive an OTA update for API 23 as well.



So what does this mean for you as an Android Wear developer? You will need to ensure that your apps are compatible with both API 23 and API 22 watches. While you can start implementing the new features in this post, you still need to maintain backwards compatibility until all watches are upgraded.



New permissions model and samples


API 23 introduces a new runtime permissions model for both phones and watches. The new permissions model allows users to pick and choose which permissions to grant apps at the time of use. In addition, new permissions settings allow users to turn on and off app permissions at any time.



To use the new permissions model on Wear, read Permissions on Android Wear. This training guide provides an in-depth discussion of Wear-specific scenarios, such as when your Wear app relies on a phone-side permission. In addition, all of the Android Wear samples have been updated to use the new permissions model, and a new RuntimePermissionsWear sample shows how to handle permission requests across devices.



When you are ready, you can update your application on both the phone and watch side to use compileSdkVersion 23 and targetSdkVersion 23. Make sure that you check and request the permissions needed by your app at runtime, on both the phone and the watch. It is important that you do not change targetSdkVersion to 23 until you have implemented the permission checks properly, since it changes how the system installs and runs the app. For example, an API call that might have previously returned a result could now fail, causing the app to behave in unexpected ways.






-round and -notround resource qualifiers


API 23 makes it easier to build apps for both round and square Android Wear watches. We listened to your feedback and added new resource qualifiers for -round and -notround, so you can use the resource system to load the appropriate images, layouts, and strings based on the type of watch you are working with. You can also combine this with existing resource qualifiers -hdpi, -tvdpi, -280dpi, and -360dpi for the various Android Wear watches that are currently available. All of the existing classes in the wearable UI library, such as WatchViewStub, BoxInsetLayout, and WearableFrameLayout will continue to work as well, so you do not need to change your code. The -round and -notround resource qualifiers will not work on API 22 devices, so you cannot assume they will be available until all devices are on API 23.



Watches with speakers


The LG Watch Urbane 2nd Edition LTE is the first watch to include speaker support, so you can now add sounds to your Wear app. You can play audio files using the same APIs that are available on Android phones, such as AudioTrack, MediaPlayer, and ExoPlayer. Check out the sample and documentation to learn how to detect when the speaker is available on a Wear device and play sounds through it.



Intel x86 support


The new TAG Heuer Connected, along with other upcoming Android Wear watches, is based on Intel x86 processors. If you are working only with Java code, your apps will automatically work on any architecture. However, if you’re using the NDK, you’ll need to provide both armeabi-v7a and x86 shared libraries in your wearable APK. Since only one wearable app can be bundled in a phone app, it is not possible to deliver different APKs to different watches based on architecture. If your wearable APK is missing an x86 library, it will fail to install on x86 watches with INSTALL_FAILED_NO_MATCHING_ABIS and code -113.



If you are using Android Studio, you will need to adjust your build.gradle file to include:


ndk {
abiFilters = ['armeabi-v7a','x86']
}

If you are using the NDK directly, you will need to modify your Application.mk file to use:


APP_ABI := armeabi-v7a x86


These changes should only be made for the wearable APK, and you can continue to support other ABIs on the phone side. You can test your application by checking if it works on the x86 emulator provided by the SDK Manager.



Updated emulator


New Android Wear emulator images for API 23 and x86 watches are available to download from the SDK Manager in Android Studio. We have also added profiles that represent every available Android Wear watch, so you can easily test on any device you want. It is also important that you understand and test all the combinations of phones (API <= 22, API = 23) and wearables (API 22, API 23), so that your app works for all users.



Updates to existing watches


The new emulator images allow you to get started immediately with testing and deploying updated apps for users with API 23 watches. The schedule for updating existing Android Wear watches via OTA updates has not been announced yet. We will announce the update schedule on the Android Wear Developers Google+ community. We’ll also let you know when the rollout is complete, and API 22 support for Android Wear is no longer needed.


Friday, September 25, 2015

Google Play services 8.1: Get ready for Marshmallow!

Posted by, Laurence Moroney, Developer Advocate



With the rollout of Google Play services 8.1 finally finished, there’s a lot of new information to share with developers about the release!



Marshmallow Permissions



Android 6.0 (Marshmallow) has introduced a new permissions model allowing users to control app permissions at runtime. As an app developer, it’s important for you to adopt this and give your users good control over the permissions your app needs. You can find more details here.



If your app is using Google Play services SDK versions prior to 8.1, you must update to use this new version to ensure your app is fully compatible with Android 6.0. This will enable you to manage the permission flows appropriately for your app and avoid any potential connection issues. For more details, and a step-by-step guide to what your app should do for the best user experience, take a look at this blog post on the Android Developers site.





App Invites



App Invites allows you to grow your apps audience by letting existing Android and iOS users invite their Google contacts via email or SMS to try your app out. Google Play services 8.1 adds the ability for developers to customize the email invitation, including adding a custom image, and specifying a call-to-action button text. These improvements should help developers increase user engagement and conversions with app invites.



Ambient Mode Maps



Android Wear provides a feature called ambient mode, enabling apps to stay visible, even when they aren’t actively being used. Now, with Google Play services 8.1, the Google Maps Android API supports ambient mode. In this mode, a simplified low-color rendering of the map will be seen. This reduces power consumption by lighting fewer pixels, but the camera and zoom level are retained, so user context will be kept. To learn more about ambient mode, check out this blog post.



Nearby Status Listener



Google Nearby allows you to build simple interactions between nearby devices. A new addition in Google Play services allows your app to receive callbacks when an active Nearby publish or subscribe expires. This frees you from tracking the TTL and allows your app's UI to accurately reflect whether Nearby is active or not.



Play Games Player Stats API



The new Play Games Player Stats API allows you to build better, smarter, games. It will let you tailor user experiences to specific segments of players and different stages of the player lifecycle. For example, you can give your most valuable players that are returning from a break in play a special welcome back message and reward.



Breaking Changes



In this release, there are some changes to GoogleApiClient and PendingResult, making them abstract classes, which may lead to breaking changes in your code. Learn more about these changes and how to handle them in the release notes.







SDK Now available!



You can get started developing today by downloading the Google Play services SDK from the Android SDK Manager. To learn more about Google Play services and the APIs available to you through it, visit our documentation on Google Developers.



Google Play services 8.1 and Android 6.0 Permissions

Google Play services 8.1 and Android 6.0 Permissions

Posted by, Laurence Moroney, Developer Advocate



Along with new platform features, Android 6.0 Marshmallow has a new permissions model that streamlines the app install and auto-update process. Google Play services 8.1 is the first release to support runtime permissions on devices running Android 6.0. and will obtain all the permissions it needs to support its APIs. As a result, your apps won’t normally need to request permissions to use them. However, if you update your apps to target API level 23, they will still need to check and request runtime permissions, as necessary.



To update your Google Play services apps to handle the latest permissions model, it’s good practice to manage the user’s expectations in setting permissions that the runtime may require. Below are some best practices to help you get started.



Before you begin...



For the purposes of this post, ensure that your API level and Target SDK are set to at least 23. Additionally, ensure that, for backwards compatibility, you are using the V4 support library to verify and request permissions. If you don’t have it already, add it to your gradle file:



 
com.android.support:support-v4:23.0.1


You’ll also need to declare Permissions in your AndroidManifest.xml file. There’s no change here. Whatever permissions your app has always needed should be declared in your AndroidManifest.xml file with the uses-permission tag. Here’s an example:



 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>


Documentation on maps and location, including a walkthrough on connecting may be found here.



Step 1. Manage Connections to the GoogleApiClient



Make sure that you are handling connection failures on GoogleApiClient correctly, and that you are using the proper resolution process as outlined here. Note that if Google Play services itself is missing permissions, the user flow to fix them will be handled for you automatically if you follow this methodology.

Here’s an example:



 
@Override
public void onConnectionFailed(ConnectionResult result) {
if (mResolvingError) {
// Already attempting to resolve an error.
return;
} else if (result.hasResolution()) {
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (SendIntentException e) {
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect();
}
} else {
// Show dialog using GooglePlayServicesUtil.getErrorDialog()
showErrorDialog(result.getErrorCode());
mResolvingError = true;
}
}




Step 2. Verify Permissions before calling APIs



It’s easy to assume that once you can connect, and you’ve declared the required permissions for APIs that you want to use in your AndroidManifest.xml file, that future calls will be fine. However, it is vital to ensure that you have the required permission before calling an API or connecting to the GoogleApiClient. This can be done using the checkSelfPermission method of ActivityCompat, Fragment or ContextCompat.



If the call returns false, i.e. the permissions aren’t granted, you’ll use requestPermissions to request them. The response to this will be returned in a callback which you will see in the next step.



Here’s an example:



 
private static final int REQUEST_CODE_LOCATION = 2;

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Request missing location permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_LOCATION);
} else {
// Location permission has been granted, continue as usual.
Location myLocation =
LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}


Step 3. Implement the request permission callback.



In step 2, if the permission wasn’t granted by the user, the requestPermissions method was called to ask the user to grant them. The response from the user is captured in the onRequestPermissionsResult callback. You need to implement this, and always check the return values because the request could be denied or cancelled. Note that you might need to request multiple permissions here -- this sample just checks for a single permission -- you may need to check for more.



 
public void onRequestPermissionsResult(int requestCode,
String[] permissions,
int[] grantResults) {
if (requestCode == REQUEST_CODE_LOCATION) {
if(grantResults.length == 1
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// success!
Location myLocation =
LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
} else {
// Permission was denied or request was cancelled
}
}


Step 4. Show permission rationale



If the user has previously denied the permission request, your app should display an additional explanation before requesting the permission again. Indeed, if the permissions are non trivial for the core features of the app, and the user is confused as to why they are needed, it would be recommended to guide them.



In this case, before the call to requestPermissions (step 2, above), you should call shouldShowRequestPermissionRationale, and if it returns true, you should create some UI to display additional context for the permission.



As such your code from Step 2 might look like this:




private static final int REQUEST_CODE_LOCATION = 2;

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now

if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Display UI and wait for user interaction
} else {
ActivityCompat.requestPermissions(
this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_LOCATION);

}
} else {
// permission has been granted, continue as usual
Location myLocation =
LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}





Note that in this case your user may still deny the permissions, in which case you will need to craft your app so as not to be in a situation where a denied permission affects parts of the app where it shouldn’t. Refer to the best practices section on the Android developer’s site for more details and guidance.



If you’ve built any applications that use Google Play services, I’d recommend that you download the Google Play services 8.1 SDK, and rebuild your applications using it, testing against the most recent versions of Android 6.0, which you can download from the Android Developers site.



Useful resources:



Get started with building for Android 6.0



Android Permissions design guidelines



Google IO 2015 Session on Android M Permissions



Samples for Google Play services 8.1 with coding best practices



Thursday, September 10, 2015

New permissions requirements for Android TV

New permissions requirements for Android TV

Posted by Anirudh Dewani, Developer Advocate



Android 6.0 introduces a new runtime permission model that gives users more granular control over granting permissions requested from their apps and leads to faster app installs. Users can also revoke these permissions from Settings at any point of time. 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. Developers should check for permissions that require runtime grant from users, and request them if the app doesn’t already have them.



To list all permissions that require runtime grant from users on Android 6.0 -




adb shell pm list permissions -g -d


RECORD_AUDIO



Apps should generally request as few permissions as possible. Voice search is an integral part of Android TV content discovery experience. When using the internal SpeechRecognizer to enable Voice Search, apps must declare RECORD_AUDIO permission in the manifest. RECORD_AUDIO requires explicit user grant during runtime in Android 6.0. When using the Android TV Leanback support library, apps can eliminate the need for requesting RECORD_AUDIO during runtime by using SpeechRecognitionCallback instead of SpeechRecognizer.



SearchActivity.java



Commit from Android TV Leanback Sample repository.





mFragment = (SearchFragment) getFragmentManager()
.findFragmentById(R.id.search_fragment);

if (!USE_INTERNAL_SPEECH_RECOGNIZER) {

mSpeechRecognitionCallback = new SpeechRecognitionCallback() {

@Override
public void recognizeSpeech() {
if (DEBUG) Log.v(TAG, "recognizeSpeech");

// ACTION_RECOGNIZE_SPEECH
startActivityForResult(mFragment.getRecognizerIntent(), REQUEST_SPEECH);
}
};
mFragment.setSpeechRecognitionCallback(mSpeechRecognitionCallback);
}




When SpeechRecognitionCallback is set, Android Leanback support library will let the your activity process the voice search action instead of using the internal SpeechRecognizer. The app can then use RecognizerIntent to support speech recognition.



If you have an Android TV app targeting API Level 23, please update the app to use SpeechRecognitionCallback and remove RECORD_AUDIO permission from your manifest.

Thursday, August 27, 2015

Building better apps with Runtime Permissions

Posted by Ian Lake, Developer Advocate



Android devices do a lot, whether it is taking pictures, getting directions or making phone calls. With all of this functionality comes a large amount of very sensitive user data including contacts, calendar appointments, current location, and more. This sensitive information is protected by permissions, which each app must have before being able to access the data. Android 6.0 Marshmallow introduces one of the largest changes to the permissions model with the addition of runtime permissions, a new permission model that replaces the existing install time permissions model when you target API 23 and the app is running on an Android 6.0+ device.



Runtime permissions give your app the ability to control when and with what context you’ll ask for permissions. This means that users installing your app from Google Play will not be required to accept a list of permissions before installing your app, making it easy for users to get directly into your app. It also means that if your app adds new permissions, app updates will not be blocked until the user accepts the new permissions. Instead, your app can ask for the newly added runtime permissions as needed.



Finding the right time to ask for runtime permissions has an important impact on your app’s user experience. We’ve gathered a number of design patterns in our new Permission design guidelines including best practices around when to request permissions, how to explain why permissions are needed, and how to handle permissions being denied.




Ask up front for permissions that are obvious


In many cases, you can avoid permissions altogether by using the existing intents system to utilize other existing specialized apps rather than building a full experience within your app. An example of this is using ACTION_IMAGE_CAPTURE to start an existing camera app the user is familiar with rather than building your own camera experience. Learn more about permissions versus intents.



However, if you do need a runtime permission, there’s a number of tools to help you. Checking for whether your app has a permission is possible with ContextCompat.checkSelfPermission() (available as part of revision 23 of the support-v4 library for backward compatibility) and requesting permissions can be done with requestPermissions(), bringing up the system controlled permissions dialog to allow the user to grant you the requested permission(s) if you don’t already have them. Keep in mind that users can revoke permissions at any time through the system settings so you should always check permissions every time.



A special note should be made around shouldShowRequestPermissionRationale(). This method returns true if the user has denied your permission request at least once yet have not selected the ‘Don’t ask again’ option (which appears the second or later time the permission dialog appears). This gives you an opportunity to provide additional education around the feature and why you need the given permission. Learn more about explaining why the app needs permissions.



Read through the design guidelines and our developer guide for all of the details in getting your app ready for Android 6.0 and runtime permissions. Making it easy to install your app and providing context around accessing user’s sensitive data are key changes you can make to build better apps.