Article image Handling Android Permissions

54. Handling Android Permissions

Page 72 | Listen in audio

Handling permissions in Android is a crucial aspect of app development, especially when dealing with user data and device capabilities. In the context of Android app development using Kotlin, understanding how to manage permissions effectively is vital to ensure both functionality and user privacy.

Android permissions are divided into two categories: normal permissions and dangerous permissions. Normal permissions cover areas where there's minimal risk to the user's privacy or the operation of other apps. These permissions are automatically granted by the system upon installation. On the other hand, dangerous permissions involve access to sensitive user data or features that could affect the user's stored data or the operation of other apps. Therefore, these permissions require explicit user consent.

Starting from Android 6.0 (API level 23), a new permissions model was introduced. This model requires developers to request permissions at runtime, rather than at installation time. This change was made to give users more control and transparency over the permissions they grant to apps. In this model, apps must check for permissions at runtime and request them if they have not been granted.

In Kotlin, handling permissions involves several key steps:

1. Declare Permissions in the Manifest

Before requesting permissions at runtime, you must declare the permissions your app needs in the AndroidManifest.xml file. This step is necessary for both normal and dangerous permissions. Here's an example of how to declare permissions:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">

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

</manifest>

In this example, the app declares the need for camera access and fine location access.

2. Check for Permissions

Before using a feature that requires a dangerous permission, check whether the app already has that permission. You can do this using the ContextCompat.checkSelfPermission() method. Here's how you might check for camera permission:

val cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)

if (cameraPermission != PackageManager.PERMISSION_GRANTED) {
    // Permission is not granted
}

If the permission is not granted, you need to request it from the user.

3. Request Permissions

To request a permission, use the ActivityCompat.requestPermissions() method. This method will display a system dialog to the user, asking them to grant or deny the requested permissions. Here's how you can request camera permission:

ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQUEST_CAMERA_PERMISSION)

The REQUEST_CAMERA_PERMISSION is a constant integer that you define to identify this particular permission request. You will use this request code when handling the user's response.

4. Handle Permission Request Response

After the user responds to the permission request dialog, the system invokes your activity's onRequestPermissionsResult() method, passing the request code, permissions array, and grant results array. You need to override this method to handle the user's response:

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    when (requestCode) {
        REQUEST_CAMERA_PERMISSION -> {
            if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                // Permission granted, proceed with camera operation
            } else {
                // Permission denied, disable the functionality that depends on this permission.
            }
            return
        }
        // Handle other permission requests
    }
}

In this method, you check if the permission was granted or denied and proceed accordingly. If the permission is denied, you should disable the functionality that requires the permission or provide an alternative solution.

5. Provide Additional Explanation

In some cases, users might need additional context about why your app needs a particular permission. Android provides a method called shouldShowRequestPermissionRationale() that returns true if the user has previously denied the request, and you should show an explanation. You can use this method to display a rationale before requesting the permission again:

if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
    // Show an explanation to the user
    // You can use a dialog or a snackbar to provide the rationale
} else {
    // No explanation needed; request the permission
    ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQUEST_CAMERA_PERMISSION)
}

Providing a rationale helps users understand why the permission is necessary, which can increase the likelihood of them granting it.

6. Handle Permission Denial

If a user denies a permission request, you should handle this gracefully. Consider providing alternative functionality where possible. For instance, if camera access is denied, you might allow users to upload images from their gallery instead. Additionally, you should respect the user’s decision and not continuously prompt for the same permission.

7. Considerations for Android 11 and Above

With Android 11 (API level 30), further changes were introduced to permissions. One-time permissions allow users to grant temporary access to their location, microphone, or camera. This means that apps can use the permission only while the user is actively using the app. Once the app is closed or goes to the background, the permission is revoked. This requires developers to handle permission requests more dynamically and consider the app’s lifecycle.

Additionally, Android 11 introduced the concept of auto-resetting permissions. If users haven’t used an app for a few months, the system automatically resets the app’s sensitive permissions. Users are notified of this reset, and the app can request the permissions again when needed.

8. Best Practices

  • Request Permissions in Context: Only request permissions when they are needed for a specific feature. This helps users understand why the permission is necessary.
  • Provide Clear Explanations: Use rationale dialogs to explain why a permission is needed, especially if the user has denied it before.
  • Handle Denials Gracefully: Always provide alternative functionality or gracefully degrade features if permissions are denied.
  • Respect User Decisions: Avoid repeatedly requesting permissions if the user has denied them and opted not to be asked again.
  • Test Across Devices: Permissions can behave differently across devices and Android versions, so thorough testing is essential.

In conclusion, handling permissions in Android using Kotlin involves a structured approach of checking, requesting, and handling user responses to permissions. By following best practices and understanding the nuances of the permissions model, developers can create apps that are both functional and respectful of user privacy.

Now answer the exercise about the content:

What is the primary reason for requesting permissions at runtime in Android app development starting from Android 6.0 (API level 23)?

You are right! Congratulations, now go to the next page

You missed! Try again.

Article image Kotlin Flow for Reactive Programming

Next page of the Free Ebook:

73Kotlin Flow for Reactive Programming

6 minutes

Earn your Certificate for this Course for Free! by downloading the Cursa app and reading the ebook there. Available on Google Play or App Store!

Get it on Google Play Get it on App Store

+ 6.5 million
students

Free and Valid
Certificate with QR Code

48 thousand free
exercises

4.8/5 rating in
app stores

Free courses in
video, audio and text