Android Runtime Permissions Dont Ask Again
Every Android app runs in a express-access sandbox. If your app needs to use resources or information outside of its ain sandbox, you can declare a permission and set up a permission asking that provides this access. These steps are part of the workflow for using permissions.
If you lot declare any dangerous permissions, and if your app is installed on a device that runs Android half dozen.0 (API level 23) or higher, yous must asking the dangerous permissions at runtime by following the steps in this guide.
If you don't declare whatsoever dangerous permissions, or if your app is installed on a device that runs Android 5.1 (API level 22) or lower, the permissions are automatically granted, and you lot don't need to complete any of the remaining steps on this page.
Basic principles
The bones principles for requesting permissions at runtime are as follows:
- Enquire for permissions in context, when the user starts to interact with the characteristic 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 characteristic needs, gracefully dethrone your app so that the user can continue using your app, peradventure by disabling the characteristic that requires the permission.
- Don't assume any arrangement behavior. For case, don't assume that permissions appear in the same permission group. A permission group merely helps the arrangement minimize the number of organization 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 do so. You tin fulfill many employ cases in your app, such equally taking photos, pausing media playback, and displaying relevant ads, without needing to declare any permissions.
If you conclude that your app needs to declare and request runtime permissions, complete these steps:
- In your app's manifest file, declare the permissions that your app might demand to asking.
- Blueprint your app's UX and then that specific actions in your app are associated with specific runtime permissions. Users should know which deportment might require them to grant permission for your app to access private user data.
- Wait for the user to invoke the task or action in your app that requires admission to specific private user data. At that fourth dimension, your app tin 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 private user data. If not, continue to the next step.
Yous must bank check whether you have that permission every time you perform an operation that requires that permission.
-
Cheque whether your app should show a rationale to the user, explaining why your app needs the user to grant a particular runtime permission. If the arrangement determines that your app shouldn't show a rationale, go along to the next pace direct, without showing a UI element.
If the system determines that your app should show a rationale, nonetheless, present the rationale to the user in a UI chemical element. This rationale should clearly explicate 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, continue to the adjacent step.
-
Request the runtime permission that your app requires in order to access the individual user data. The organization displays a runtime permission prompt, such as the 1 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, yous tin can access the private user information. If the user denied the permission instead, gracefully degrade 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 prepare 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 system when y'all call requestPermissions()
says what permission your app wants, just doesn't say why. In some cases, the user may find that puzzling. It'due south a good thought to explain to the user why your app wants the permissions earlier you lot call requestPermissions()
.
Research shows that users are much more comfortable with permissions requests if they know why the app needs them. A user study showed that:
...a user'southward willingness to grant a given permission to a given mobile app is strongly influenced by the purpose associated with such a permission. For instance a user's willingness to grant admission to their location will vary based on whether the request is required to support the app'southward core functionality or whether it is to share this data with an advertising network or an analytics company. 1
After collaborating with others on research into this topic, Professor Jason Hong from CMU concluded that, in general:
...when people know why an app is using something as sensitive as their location — for example, for targeted advertising — it makes them more comfortable than when merely told an app is using their location. 1
Every bit a result, if you're simply using a fraction of the API calls that fall under a permission group, it helps to explicitly list which of those permissions you're using, and why. For instance:
- If you're only using fibroid location, permit the user know this in your app clarification or in help articles near your app.
-
If you need access to SMS letters to receive hallmark codes that protect the user from fraud, let the user know this in your app description and when your app commencement needs to access the data.
Note: If your app targets Android viii.0 (API level 26) or higher, don't request the
READ_SMS
permission every bit role of verifying a user's credentials. Instead, generate an app-specific token usingcreateAppSpecificSmsToken()
, so laissez passer this token to another app or service that can ship a verification SMS message.
Under certain weather condition, information technology's too advantageous to let users know most sensitive data accesses in real time. For instance, if you're accessing the camera or microphone, it's usually a adept 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 groundwork), so it doesn't seem similar you're collecting data surreptitiously.
Ultimately, if y'all need to request a permission to brand something in your app work, but the reason is not clear to the user, find a way to let the user know why you need the well-nigh sensitive permissions.
If the ContextCompat.checkSelfPermission()
method returns PERMISSION_DENIED
, call shouldShowRequestPermissionRationale()
. If this method returns true
, prove an educational UI to the user. In this UI, describe why the feature, which the user wants to enable, needs a particular permission.
Additionally, if your app requests a permission related to location, microphone, or camera, consider explaining why your app needs access to this information.
Request permissions
After the user views an educational UI, or the return value of shouldShowRequestPermissionRationale()
indicates that yous don't need to show an educational UI this time, asking the permission. Users see a system permission dialog, where they tin choose whether to grant a detail permission to your app.
Traditionally, yous manage a asking code yourself every bit function of the permission request and include this request code in your permission callback logic. Another option is to use the RequestPermission
contract, included in an AndroidX library, where yous allow the system to manage the permission request code for you. Because using the RequestPermission
contract simplifies your logic, information technology's recommended that you apply it when possible.
Allow the organization to manage the permission request code
To permit the system to manage the asking code that's associated with a permissions request, add dependencies on the following libraries in your module'south build.gradle
file:
-
androidx.activity
, version 1.2.0 or later. -
androidx.fragment
, version 1.three.0 or afterward.
You lot can and so utilize i of the following classes:
- To request a single permission, use
RequestPermission
. - To request multiple permissions at the same fourth dimension, apply
RequestMultiplePermissions
.
The following steps show how to utilise the RequestPermission
contract. The process is nearly the same for the RequestMultiplePermissions
contract.
-
In your activity or fragment's initialization logic, laissez passer in an implementation of
ActivityResultCallback
into a call toregisterForActivityResult()
. TheActivityResultCallback
defines how your app handles the user's response to the permission asking.Proceed a reference to the return value of
registerForActivityResult()
, which is of typeActivityResultLauncher
. -
To display the arrangement permissions dialog when necessary, call the
launch()
method on the instance ofActivityResultLauncher
that you saved in the previous step.Later on
launch()
is called, the organisation permissions dialog appears. When the user makes a pick, the system asynchronously invokes your implementation ofActivityResultCallback
, which you defined in the previous stride.Note: Your app cannot customize the dialog that appears when you call
launch()
. To provide more than information or context to the user, change your app's UI so that information technology's easier for users to understand why a feature in your app needs a item permission. For example, you lot might alter the text in the push button that enables the characteristic.Also, the text in the system permission dialog references the permission group associated with the permission that you requested. This permission grouping is designed for system 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 // arrangement permissions dialog. Save the render value, an instance of // ActivityResultLauncher. You 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. Go on the activeness or workflow in your // app. } else { // Explain to the user that the characteristic is unavailable because the // features requires a permission that the user has denied. At the // aforementioned fourth dimension, respect the user'southward determination. Don't link to organisation // settings in an attempt to convince the user to change their // determination. } }
Java
// Register the permissions callback, which handles the user's response to the // system permissions dialog. Relieve the render value, an example of // ActivityResultLauncher, as an case variable. private ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(new RequestPermission(), isGranted -> { if (isGranted) { // Permission is granted. Go on the action or workflow in your // app. } else { // Explain to the user that the characteristic is unavailable because the // features requires a permission that the user has denied. At the // same fourth dimension, respect the user'due south decision. Don't link to system // settings in an attempt to convince the user to change their // conclusion. } });
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 tin can apply 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 // keep using your app without granting the permission. showInContextUI(...) } else -> { // You tin directly enquire 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 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 conduct as expected. In this UI, // include a "abolish" or "no thanks" button that allows the user to // go on using your app without granting the permission. showInContextUI(...); } else { // You can directly enquire for the permission. // The registered ActivityResultCallback gets the result of this request. requestPermissionLauncher.launch( Manifest.permission.REQUESTED_PERMISSION); }
Manage the permission request code yourself
As an alternative to allowing the system to manage the permission asking lawmaking, you tin can manage the permission request code yourself. To practice so, include the asking code in a call to requestPermissions()
.
The following lawmaking snippet demonstrates how to request a permission using a request lawmaking:
Kotlin
when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // You can utilize 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 characteristic to bear equally expected. In this UI, // include a "cancel" or "no thanks" button that allows the user to // go on using your app without granting the permission. showInContextUI(...) } else -> { // You lot 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, explicate 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 on using your app without granting the permission. showInContextUI(...); } else { // You can directly inquire for the permission. requestPermissions(CONTEXT, new String[] { Manifest.permission.REQUESTED_PERMISSION }, REQUEST_CODE); }
Subsequently the user responds to the system permissions dialog, the system and then invokes your app's implementation of onRequestPermissionsResult()
. The system passes in the user response to the permission dialog, too as the request lawmaking that you lot defined, as shown in the following code snippet:
Kotlin
override fun onRequestPermissionsResult(requestCode: Int, permissions: Assortment<Cord>, grantResults: IntArray) { when (requestCode) { PERMISSION_REQUEST_CODE -> { // If request is cancelled, the issue arrays are empty. if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { // Permission is granted. Continue the activity 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'south decision. Don't link to // organisation settings in an effort to convince the user to change // their conclusion. } render } // Add 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 upshot arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission is granted. Go along the action or workflow // in your app. } else { // Explain to the user that the characteristic is unavailable because // the features requires a permission that the user has denied. // At the aforementioned time, respect the user's conclusion. Don't link to // system settings in an effort to convince the user to change // their conclusion. } return; } // Other 'instance' lines to check for other // permissions this app might request. } }
Requesting multiple permissions
When you asking location permissions, follow the same best practices as you would for any other runtime permission. 1 important difference when information technology comes to location permissions is that the organization includes multiple permissions related to location. Which permissions you request, and how yous request them, depend on the location requirements for your app'southward use case.
Foreground location
If your app contains a feature that shares or receives location data simply once, or for a divers amount of time, then that characteristic requires foreground location access. Some examples include the following:
- Inside a navigation app, a feature allows users to go turn-by-plow directions.
- Inside a messaging app, a feature allows users to share their electric current location with some other user.
The system considers your app to be using foreground location if a characteristic of your app accesses the device'south current location in 1 of the following situations:
- An activity that belongs to your app is visible.
-
Your app is running a foreground service. When a foreground service is running, the organization raises user awareness by showing a persistent notification. Your app retains admission when it's placed in the background, such as when the user presses the Dwelling house push 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 post-obit code snippet. On Android 10 (API level 29) and higher, y'all must declare this foreground service type.<!-- Recommended for Android ix (API level 28) and lower. --> <!-- Required for Android 10 (API level 29) and higher. --> <service android:proper name="MyNavigationService" android:foregroundServiceType="location" ... > <!-- Whatsoever inner elements would get here. --> </service>
You declare a demand for foreground location when your app requests either the ACCESS_COARSE_LOCATION
permission or the ACCESS_FINE_LOCATION
permission, as shown in the following snippet:
<manifest ... > <!-- Always include this permission --> <uses-permission android:name="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>
Background location
An app requires background location access if a feature within the app constantly shares location with other users or uses the Geofencing API. Several examples include the following:
- Within a family location sharing app, a feature 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 system considers your app to be using background location if it accesses the device's electric current location in any 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, you lot must declare the ACCESS_BACKGROUND_LOCATION
permission in your app'south manifest in guild to request background location access at runtime. On before versions of Android, when your app receives foreground location access, it automatically receives background location admission every bit well.
<manifest ... > <!-- Required only when requesting background location access on Android 10 (API level 29) and higher. --> <uses-permission android:proper noun="android.permission.ACCESS_BACKGROUND_LOCATION" /> </manifest>
Handle permission denial
If the user denies a permission request, your app should assistance users sympathise the implications of denying the permission. In particular, your app should brand users aware of the features that don't work because of the missing permission. When you do so, keep the following best practices in listen:
-
Guide the user'southward attention. Highlight a specific part of your app'due south UI where at that place's limited functionality because your app doesn't have the necessary permission. Several examples of what you could practice include the following:
- Show a message where the feature's results or information would have appeared.
- Display a unlike button that contains an error icon and color.
-
Exist specific. Don't brandish a generic message; 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 bulletin that prevents users from continuing to apply your app at all.
Tip: Your app should encourage the all-time user experience possible, fifty-fifty after permission denials. For instance, if microphone access is denied, you lot should nevertheless promote full usability of text functionality.
At the same time, your app should respect the user's decision to deny a permission. Starting in Android xi (API level 30), if the user taps Deny for a specific permission more than than once during your app's lifetime of installation on a device, the user doesn't see the system permissions dialog if your app requests that permission again. The user'due south activeness implies "don't ask again." On previous versions, users would see the system permissions dialog each time your app requested a permission, unless the user had previously selected a "don't inquire once more" checkbox or pick.
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 characteristic, otherwise you may inadvertently lose the ability to re-request permissions.
In certain situations, the permission might be denied automatically, without the user taking any activity. (Similarly, a permission might be granted automatically equally well.) It'due south important to not assume annihilation about automatic behavior. Each time your app needs to access functionality that requires a permission, you should cheque that your app is nevertheless granted that permission.
To provide the best user experience when request for app permissions, as well see App permissions best practices.
One-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, as shown in Figure 2. If the user selects this option in the dialog, your app is granted a temporary sometime permission.
Your app tin then admission the related data for a period of time that depends on your app's behavior and the user'southward actions:
- While your app's activity is visible, your app can access the information.
- If the user sends your app to the background, your app tin can continue to access the data for a curt period of time.
- If you launch a foreground service while the activity is visible, and the user then moves your app to the groundwork, your app can continue to admission the data until that foreground service stops.
- If the user revokes the 1-fourth dimension permission, such as in system settings, your app cannot access the data, regardless of whether yous launched a foreground service. As with any permission, if the user revokes your app's one-time permission, your app'south process terminates.
When the user next opens your app and a feature in your app requests access to location, microphone, or camera, the user is prompted for the permission over again.
Android auto-resets permissions of unused apps
If your app targets Android xi (API level 30) or higher and isn't used for a few months, the system protects user data past automatically resetting the sensitive runtime permissions that the user had granted your app. Acquire more in the guide most app hibernation.
Request to become the default handler if necessary
Some apps depend on access to sensitive user information related to phone call logs and SMS messages. If y'all want to request the permissions specific to phone call logs and SMS messages and publish your app to the Play Shop, you must prompt the user to set up your app as the default handler for a cadre system office earlier requesting these runtime permissions.
For more information on default handlers, including guidance on showing a default handler prompt to users, see the guide on permissions used but in default handlers.
Grant all runtime permissions for testing purposes
To grant all runtime permissions automatically when you install an app on an emulator or test device, use the -grand
option for the adb crush install
control, equally demonstrated in the post-obit code snippet:
adb beat out install -yard PATH_TO_APK_FILE
Additional resources
For additional information about permissions, read these articles:
- Permissions overview
- App permissions best practices
To learn more near requesting permissions, download the following sample apps:
- Android RuntimePermissionsBasic Sample Java | Kotlin
Source: https://developer.android.com/training/permissions/requesting
0 Response to "Android Runtime Permissions Dont Ask Again"
Post a Comment