Undo Do Not Ask Again in Android
Every Android app runs in a limited-admission sandbox. If your app needs to use resources or data outside of its own sandbox, you tin can declare a permission and set up a permission request that provides this admission. These steps are part of the workflow for using permissions.
If you declare any unsafe permissions, and if your app is installed on a device that runs Android vi.0 (API level 23) or higher, you must request the dangerous permissions at runtime by following the steps in this guide.
If you don't declare any dangerous permissions, or if your app is installed on a device that runs Android v.1 (API level 22) or lower, the permissions are automatically granted, and you don't need to complete any of the remaining steps on this folio.
Basic principles
The bones principles for requesting permissions at runtime are equally follows:
- Inquire for permissions in context, when the user starts to collaborate with the feature that requires it.
- Don't block the user. Always provide the option to cancel an educational UI flow related to permissions.
- If the user denies or revokes a permission that a feature needs, gracefully degrade your app so that the user can proceed using your app, peradventure by disabling the feature that requires the permission.
- Don't assume any organisation behavior. For instance, don't assume that permissions appear in the same permission group. A permission group just helps the system minimize the number of system dialogs that are presented to the user when an app requests closely-related permissions.
Workflow for requesting permissions
Before you declare and request runtime permissions in your app, evaluate whether your app needs to exercise so. You tin can fulfill many use cases in your app, such as taking photos, pausing media playback, and displaying relevant ads, without needing to declare whatsoever permissions.
If you conclude that your app needs to declare and request runtime permissions, complete these steps:
- In your app'due south manifest file, declare the permissions that your app might demand to request.
- Design your app's UX so that specific actions in your app are associated with specific runtime permissions. Users should know which actions might crave them to grant permission for your app to access individual user data.
- Expect for the user to invoke the task or activeness in your app that requires admission to specific private user data. At that fourth dimension, your app can request the runtime permission that's required for accessing that data.
-
Check whether the user has already granted the runtime permission that your app requires. If so, your app can admission the individual user data. If not, continue to the next step.
You must bank check whether yous have that permission every time you perform an operation that requires that permission.
-
Check whether your app should testify a rationale to the user, explaining why your app needs the user to grant a item runtime permission. If the system determines that your app shouldn't show a rationale, continue to the next pace directly, without showing a UI element.
If the organisation determines that your app should prove a rationale, withal, present the rationale to the user in a UI chemical element. This rationale should conspicuously explain what information your app is trying to access, and what benefits the app can provide to the user if they grant the runtime permission. After the user acknowledges the rationale, go along to the next step.
-
Request the runtime permission that your app requires in order to admission the private user data. The arrangement displays a runtime permission prompt, such every bit the one shown on the permissions overview page.
-
Check the user's response, whether they chose to grant or deny the runtime permission.
-
If the user granted the permission to your app, you tin can admission the private user data. If the user denied the permission instead, gracefully dethrone your app experience so that it provides functionality to the user, even without the information that's protected by that permission.
Effigy 1 illustrates the workflow and set of decisions associated with this procedure:
Determine whether your app was already granted the permission
To check if the user has already granted your app a particular permission, pass that permission into the ContextCompat.checkSelfPermission()
method. This method returns either PERMISSION_GRANTED
or PERMISSION_DENIED
, depending on whether your app has the permission.
Explain why your app needs the permission
The permissions dialog shown by the organisation when you call requestPermissions()
says what permission your app wants, but doesn't say why. In some cases, the user may find that puzzling. It'southward a expert thought to explain to the user why your app wants the permissions before yous call requestPermissions()
.
Research shows that users are much more than comfy with permissions requests if they know why the app needs them. A user written report showed that:
...a user's willingness to grant a given permission to a given mobile app is strongly influenced past the purpose associated with such a permission. For instance a user's willingness to grant access to their location will vary based on whether the asking is required to support the app's core functionality or whether it is to share this information with an advert network or an analytics company. 1
Subsequently collaborating with others on research into this topic, Professor Jason Hong from CMU ended that, in general:
...when people know why an app is using something equally sensitive as their location — for example, for targeted advertizement — it makes them more comfortable than when merely told an app is using their location. ane
As a result, if you're only using a fraction of the API calls that autumn nether a permission grouping, it helps to explicitly listing which of those permissions yous're using, and why. For instance:
- If you're only using coarse location, let the user know this in your app description or in help manufactures about your app.
-
If you need access to SMS messages to receive authentication codes that protect the user from fraud, let the user know this in your app clarification and when your app first needs to admission the information.
Notation: If your app targets Android viii.0 (API level 26) or higher, don't request the
READ_SMS
permission as part of verifying a user's credentials. Instead, generate an app-specific token usingcreateAppSpecificSmsToken()
, then pass this token to some other app or service that can send a verification SMS message.
Under certain weather, it'southward also advantageous to let users know nearly sensitive data accesses in existent time. For case, if you lot're accessing the camera or microphone, it'southward ordinarily a skillful idea to let the user know with a notification icon somewhere in your app, or in the notification tray (if the application is running in the background), and then it doesn't seem like you're collecting information surreptitiously.
Ultimately, if yous demand to asking a permission to make something in your app piece of work, merely the reason is not articulate to the user, find a way to let the user know why you need the most sensitive permissions.
If the ContextCompat.checkSelfPermission()
method returns PERMISSION_DENIED
, call shouldShowRequestPermissionRationale()
. If this method returns true
, evidence an educational UI to the user. In this UI, describe why the feature, which the user wants to enable, needs a item permission.
Additionally, if your app requests a permission related to location, microphone, or camera, consider explaining why your app needs access to this information.
Asking permissions
Later the user views an educational UI, or the return value of shouldShowRequestPermissionRationale()
indicates that you don't need to show an educational UI this fourth dimension, request the permission. Users see a system permission dialog, where they can cull whether to grant a particular permission to your app.
Traditionally, you lot manage a request code yourself every bit part of the permission request and include this asking code in your permission callback logic. Another pick is to use the RequestPermission
contract, included in an AndroidX library, where yous allow the system to manage the permission request code for you. Considering using the RequestPermission
contract simplifies your logic, it's recommended that you use information technology when possible.
Allow the system to manage the permission request code
To allow the system to manage the asking code that's associated with a permissions asking, add dependencies on the following libraries in your module's build.gradle
file:
-
androidx.activity
, version i.2.0 or afterwards. -
androidx.fragment
, version 1.3.0 or later.
Yous can then use i of the following classes:
- To request a single permission, use
RequestPermission
. - To request multiple permissions at the same time, use
RequestMultiplePermissions
.
The post-obit steps prove how to utilise the RequestPermission
contract. The procedure is most the same for the RequestMultiplePermissions
contract.
-
In your activity or fragment's initialization logic, pass in an implementation of
ActivityResultCallback
into a call toregisterForActivityResult()
. TheActivityResultCallback
defines how your app handles the user's response to the permission asking.Go on a reference to the return value of
registerForActivityResult()
, which is of blazonActivityResultLauncher
. -
To brandish the system permissions dialog when necessary, call the
launch()
method on the instance ofActivityResultLauncher
that you lot saved in the previous footstep.Afterwards
launch()
is called, the organization permissions dialog appears. When the user makes a choice, the system asynchronously invokes your implementation ofActivityResultCallback
, which y'all defined in the previous step.Note: Your app cannot customize the dialog that appears when you call
launch()
. To provide more information or context to the user, change your app's UI so that information technology'southward easier for users to understand why a feature in your app needs a particular permission. For example, you might change the text in the button that enables the feature.Too, the text in the system permission dialog references the permission grouping associated with the permission that you requested. This permission group is designed for arrangement ease-of-use, and your app shouldn't rely on permissions being inside or outside of a specific permission group.
The post-obit lawmaking snippet shows how to handle the permissions response:
Kotlin
// Register the permissions callback, which handles the user's response to the // system permissions dialog. Save the return value, an instance of // ActivityResultLauncher. You tin can use either a val, as shown in this snippet, // or a lateinit var in your onAttach() or onCreate() method. val requestPermissionLauncher = registerForActivityResult(RequestPermission() ) { isGranted: Boolean -> if (isGranted) { // Permission is granted. Keep the action or workflow in your // app. } else { // Explain to the user that the feature is unavailable because the // features requires a permission that the user has denied. At the // same time, respect the user's decision. Don't link to system // settings in an effort to convince the user to change their // decision. } }
Coffee
// Register the permissions callback, which handles the user'south response to the // system permissions dialog. Save the render value, an instance of // ActivityResultLauncher, as an case variable. individual ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(new RequestPermission(), isGranted -> { if (isGranted) { // Permission is granted. Continue the action or workflow in your // app. } else { // Explain to the user that the feature is unavailable because the // features requires a permission that the user has denied. At the // same time, respect the user's conclusion. Don't link to system // settings in an effort to convince the user to alter their // decision. } });
And this code snippet demonstrates the recommended procedure of checking for a permission, and requesting a permission from the user when necessary:
Kotlin
when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // You lot tin use the API that requires the permission. } shouldShowRequestPermissionRationale(...) -> { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected. In this UI, // include a "cancel" or "no thanks" button that allows the user to // go along using your app without granting the permission. showInContextUI(...) } else -> { // Yous can direct ask for the permission. // The registered ActivityResultCallback gets the result of this request. requestPermissionLauncher.launch( Manifest.permission.REQUESTED_PERMISSION) } }
Java
if (ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION) == PackageManager.PERMISSION_GRANTED) { // You tin employ the API that requires the permission. performAction(...); } else if (shouldShowRequestPermissionRationale(...)) { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to acquit equally expected. In this UI, // include a "cancel" or "no thanks" button that allows the user to // continue using your app without granting the permission. showInContextUI(...); } else { // You lot can straight inquire for the permission. // The registered ActivityResultCallback gets the result of this asking. requestPermissionLauncher.launch( Manifest.permission.REQUESTED_PERMISSION); }
Manage the permission asking lawmaking yourself
Every bit an alternative to allowing the system to manage the permission request code, you tin manage the permission request lawmaking yourself. To do so, include the request lawmaking in a telephone call to requestPermissions()
.
The following lawmaking snippet demonstrates how to request a permission using a request code:
Kotlin
when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // Yous can use the API that requires the permission. performAction(...) } shouldShowRequestPermissionRationale(...) -> { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected. In this UI, // include a "abolish" or "no thank you" push button that allows the user to // continue using your app without granting the permission. showInContextUI(...) } else -> { // You lot tin can directly ask for the permission. requestPermissions(CONTEXT, arrayOf(Manifest.permission.REQUESTED_PERMISSION), REQUEST_CODE) } }
Java
if (ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION) == PackageManager.PERMISSION_GRANTED) { // You can use the API that requires the permission. performAction(...); } else if (shouldShowRequestPermissionRationale(...)) { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected. In this UI, // include a "cancel" or "no thanks" button that allows the user to // keep using your app without granting the permission. showInContextUI(...); } else { // You tin direct ask for the permission. requestPermissions(CONTEXT, new String[] { Manifest.permission.REQUESTED_PERMISSION }, REQUEST_CODE); }
Later on the user responds to the system permissions dialog, the arrangement and then invokes your app's implementation of onRequestPermissionsResult()
. The arrangement passes in the user response to the permission dialog, too as the request code that you defined, as shown in the following code snippet:
Kotlin
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { when (requestCode) { PERMISSION_REQUEST_CODE -> { // If request is cancelled, the consequence arrays are empty. if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { // Permission is granted. Go on the action or workflow // in your app. } else { // Explain to the user that the feature is unavailable because // the features requires a permission that the user has denied. // At the same time, respect the user's decision. Don't link to // system settings in an attempt to convince the user to change // their decision. } return } // Add together other 'when' lines to check for other // permissions this app might request. else -> { // Ignore all other requests. } } }
Java
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { example PERMISSION_REQUEST_CODE: // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission is granted. Continue the action or workflow // in your app. } else { // Explain to the user that the characteristic is unavailable considering // the features requires a permission that the user has denied. // At the same time, respect the user'due south determination. Don't link to // system settings in an effort to convince the user to change // their decision. } return; } // Other 'instance' lines to cheque for other // permissions this app might request. } }
Requesting multiple permissions
When y'all request location permissions, follow the aforementioned best practices as you would for any other runtime permission. One important deviation when it comes to location permissions is that the system includes multiple permissions related to location. Which permissions you request, and how you asking them, depend on the location requirements for your app's apply case.
Foreground location
If your app contains a feature that shares or receives location data only one time, or for a defined amount of fourth dimension, then that feature requires foreground location access. Some examples include the post-obit:
- Within a navigation app, a feature allows users to go turn-by-turn directions.
- Within a messaging app, a feature allows users to share their current location with some other user.
The system considers your app to exist using foreground location if a feature of your app accesses the device's current location in one of the following situations:
- An activeness that belongs to your app is visible.
-
Your app is running a foreground service. When a foreground service is running, the system raises user sensation past showing a persistent notification. Your app retains access when it's placed in the groundwork, such as when the user presses the Dwelling house button on their device or turns their device's display off.
Additionally, it's recommended that you declare a foreground service type of
location
, as shown in the following code snippet. On Android ten (API level 29) and college, y'all must declare this foreground service type.<!-- Recommended for Android 9 (API level 28) and lower. --> <!-- Required for Android 10 (API level 29) and higher. --> <service android:name="MyNavigationService" android:foregroundServiceType="location" ... > <!-- Whatsoever inner elements would go hither. --> </service>
You declare a need for foreground location when your app requests either the ACCESS_COARSE_LOCATION
permission or the ACCESS_FINE_LOCATION
permission, equally shown in the following snippet:
<manifest ... > <!-- Always include this permission --> <uses-permission android:proper noun="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Include only if your app benefits from precise location access. --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> </manifest>
Groundwork location
An app requires background location access if a characteristic within the app constantly shares location with other users or uses the Geofencing API. Several examples include the post-obit:
- Within a family location sharing app, a characteristic allows users to continuously share location with family members.
- Inside an IoT app, a feature allows users to configure their home devices such that they turn off when the user leaves their home and turn dorsum on when the user returns home.
The organization considers your app to be using background location if it accesses the device's electric current location in whatsoever situation other than the ones described in the foreground location section. The background location precision is the same as the foreground location precision, which depends on the location permissions that your app declares.
On Android 10 (API level 29) and higher, yous must declare the ACCESS_BACKGROUND_LOCATION
permission in your app'south manifest in gild to request background location admission at runtime. On earlier versions of Android, when your app receives foreground location access, it automatically receives background location access every bit well.
<manifest ... > <!-- Required only when requesting groundwork location access on Android 10 (API level 29) and college. --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> </manifest>
Handle permission denial
If the user denies a permission request, your app should assistance users understand the implications of denying the permission. In particular, your app should make users aware of the features that don't work because of the missing permission. When you do and so, proceed the following all-time practices in heed:
-
Guide the user's attention. Highlight a specific office of your app'due south UI where there'south limited functionality because your app doesn't accept the necessary permission. Several examples of what you could exercise include the post-obit:
- Prove a bulletin where the characteristic's results or information would have appeared.
- Brandish a different push that contains an error icon and color.
-
Be specific. Don't display a generic bulletin; instead, mention which features are unavailable because your app doesn't accept the necessary permission.
-
Don't block the user interface. In other words, don't display a full-screen warning message that prevents users from continuing to employ your app at all.
Tip: Your app should encourage the all-time user feel possible, even later on permission denials. For example, if microphone access is denied, you should still promote full usability of text functionality.
At the aforementioned time, your app should respect the user's decision to deny a permission. Starting in Android 11 (API level 30), if the user taps Deny for a specific permission more than once during your app'southward lifetime of installation on a device, the user doesn't run into the system permissions dialog if your app requests that permission once more. The user'due south action implies "don't inquire over again." On previous versions, users would meet the organization permissions dialog each time your app requested a permission, unless the user had previously selected a "don't ask once again" checkbox or choice.
If a user denies a permission asking more than once, this is considered a permanant denial. It's very important to but prompt users for permissions when they need access to a specific feature, otherwise y'all may inadvertently lose the ability to re-asking permissions.
In certain situations, the permission might be denied automatically, without the user taking any action. (Similarly, a permission might be granted automatically as well.) It's of import to non assume anything about automated behavior. Each time your app needs to access functionality that requires a permission, y'all should check that your app is withal granted that permission.
To provide the all-time user experience when asking for app permissions, besides see App permissions best practices.
I-time permissions
Starting in Android 11 (API level 30), whenever your app requests a permission related to location, microphone, or camera, the user-facing permissions dialog contains an option called Simply this time, equally shown in Figure 2. If the user selects this option in the dialog, your app is granted a temporary old permission.
Your app tin and so access the related data for a menses of time that depends on your app's behavior and the user's actions:
- While your app's activity is visible, your app can admission the data.
- If the user sends your app to the background, your app tin can proceed to access the information for a short catamenia of time.
- If yous launch a foreground service while the activity is visible, and the user so moves your app to the groundwork, your app can continue to admission the data until that foreground service stops.
- If the user revokes the one-time permission, such as in arrangement settings, your app cannot access the data, regardless of whether you launched a foreground service. As with whatsoever permission, if the user revokes your app's erstwhile permission, your app's procedure terminates.
When the user next opens your app and a characteristic in your app requests access to location, microphone, or camera, the user is prompted for the permission again.
Android auto-resets permissions of unused apps
If your app targets Android 11 (API level thirty) or higher and isn't used for a few months, the organisation protects user data by automatically resetting the sensitive runtime permissions that the user had granted your app. Learn more in the guide near app hibernation.
Request to become the default handler if necessary
Some apps depend on access to sensitive user information related to call logs and SMS messages. If y'all want to request the permissions specific to call logs and SMS letters and publish your app to the Play Store, you lot must prompt the user to set your app equally the default handler for a cadre system function before requesting these runtime permissions.
For more information on default handlers, including guidance on showing a default handler prompt to users, come across the guide on permissions used but in default handlers.
Grant all runtime permissions for testing purposes
To grant all runtime permissions automatically when y'all install an app on an emulator or test device, use the -1000
option for the adb shell install
control, as demonstrated in the following code snippet:
adb crush install -g PATH_TO_APK_FILE
Additional resources
For additional information most permissions, read these articles:
- Permissions overview
- App permissions best practices
To learn more than near requesting permissions, download the following sample apps:
- Android RuntimePermissionsBasic Sample Java | Kotlin
Source: https://developer.android.com/training/permissions/requesting
0 Response to "Undo Do Not Ask Again in Android"
Post a Comment