Android Permissions Handling Runtime Permissions Step by step Implementation and Top 10 Questions and Answers
 .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    Last Update: April 01, 2025      22 mins read      Difficulty-Level: beginner

Android Permissions Handling: Runtime Permissions

Permissions are an essential aspect of Android security, allowing apps to access specific resources or capabilities on a user's device. Prior to Android 6.0 (API level 23), all permissions required by an app were declared in the AndroidManifest.xml file and requested during the app installation process. This approach, while straightforward, often led to apps being granted more permissions than necessary, potentially compromising user privacy and security.

Starting with Android 6.0, Google introduced a new concept called Runtime Permissions. With this change, apps are required to request permissions at runtime when they need them and explain why they need them. This ensures that users can make informed decisions about granting permissions to applications and can revoke them at any time.

Why Runtime Permissions?

  1. User Trust and Control: Users are more likely to trust an app if it requests permissions only when needed.
  2. Enhanced Security: By granting permissions selectively, the risk of malicious or unwanted access to sensitive resources is minimized.
  3. Better User Experience: Apps can perform actions seamlessly without interrupting the user with permission prompts during installation.

How Runtime Permissions Work

When developing an app targeting Android 6.0 (Marshmallow) or higher, you need to account for two types of permissions:

  • Normal Permissions: These are low-risk permissions that do not affect the user’s private data significantly. Examples include network access, Wi-Fi scans, and bluetooth pairing. Normal permissions are automatically granted by the system when you declare them in the AndroidManifest.xml.
  • Dangerous Permissions: These permissions give your application access to the user’s sensitive data. Dangerous permissions require explicit confirmation from the user via a runtime permissions dialog. Examples include reading contacts, accessing location services, and recording audio.
Steps for Requesting Runtime Permissions:
  1. Check the Permission: Before performing an action that requires a dangerous permission, your app must check whether it has already been granted using ContextCompat.checkSelfPermission().

    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
    }
    
  2. Request the Permission: If the permission has not been granted, you must call Activitycompat.requestPermissions() to request the permission. This method shows a standard system dialog to the user explaining why the permission is needed.

    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);
    
  3. Handle Permission Request Response: After the permission dialog has been displayed, the system calls your app’s onRequestPermissionsResult() method. You should override this method to handle the user’s response.

    @Override
    public void onRequestPermissionsResult(int requestCode,
            String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission was granted, proceed with the operation you requested.
                } else {
                    // Permission denied, disable functionality that depends on this permission.
                }
                return;
            }
            // Add other cases if needed for other permissions.
        }
    }
    
  4. Inform Users About Importance of Permissions: It is recommended to display explanations before requesting runtime permissions, especially if multiple permissions are needed. For example, you might use a Snackbar or AlertDialog to explain why your app needs access to the camera or location services.

  5. Use System Settings for Revoked Permissions: Users can grant or deny permissions both when prompted and through the app settings. To inform users about how their permissions can be managed, you can direct them to the system settings using an Intent.

    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    Uri uri = Uri.fromParts("package", getPackageName(), null);
    intent.setData(uri);
    startActivity(intent);
    

Important Information and Best Practices

  • Permissions Grouping: Starting with Android 6.0, dangerous permissions are grouped into categories such as calendar, contacts, and location. If an app has been granted one permission in a group, it will automatically have the rest. However, apps should request individual permissions since this behavior could change in future versions.

  • Permission Lifecycle Management: An app should always check for permissions before accessing protected functionalities. Even if the user had previously granted a permission, it can be revoked at any time via the system settings. Therefore, apps should manage permissions lifecycle carefully.

  • User Interface Considerations: Provide clear rationale for requesting each permission. A well-designed dialog provides context about why the permission is necessary. Avoid overwhelming users with too many permissions at once; ask for them in chunks as they’re needed within the app.

  • Backward Compatibility: When targeting an Android version above 5.1 (API level 22), your app still needs to support older devices that rely on the pre-M permission model. Always check for permissions programmatically before performing protected operations and fall back gracefully if the permissions aren’t available.

  • Handling Permission Denial Politely: If the user denies a permission request, provide a graceful failure path in your app. Do not crash or show error dialogs without explanation. Consider providing alternative functionality that does not require the denied permission.

  • Explaining Permission Rationale: Use ActivityCompat.shouldShowRequestPermissionRationale() to determine if a permission denial rationale dialog should be shown to the user. This method returns true if the app has previously requested this permission and the user denied the request. In such cases, you can present a custom dialog explaining why the permission is important before making another request.

    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
             Manifest.permission.READ_CONTACTS)) {
         // Show an explanation to the user *asynchronously* — don't block
         // this thread waiting for the user's response! After the user
         // sees the explanation, try again to request the permission.
    } else {
         // No explanation needed, we can request the permission.
    }
    
  • Using Permissions in Libraries: Libraries should avoid requesting permissions directly. Instead, they should document which permissions are required and instruct the developer to add these permissions to the app’s manifest and request them at runtime. This keeps the library independent of the context in which it runs and avoids issues with the permission granting flow.

Practical Example

Let's consider an example where an app needs to request camera access to take a profile picture.

  1. Manifest Declaration: First, declare the required permission in the AndroidManifest.xml file.

    <uses-permission android:name="android.permission.CAMERA"/>
    
  2. Check and Request Permission: Check if the permission has been granted and request it if necessary.

    private static final int MY_PERMISSIONS_REQUEST_CAMERA = 100;
    
    private void askForCameraPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) 
                != PackageManager.PERMISSION_GRANTED) {
    
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.CAMERA},
                    MY_PERMISSIONS_REQUEST_CAMERA);
        } else {
            // Permission already granted, start the camera feature.
            openCamera();
        }
    }
    
  3. Handle Permission Result: Override onRequestPermissionsResult() to handle the user’s response.

    @Override
    public void onRequestPermissionsResult(int requestCode,
            String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == MY_PERMISSIONS_REQUEST_CAMERA) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission granted, proceed with the operation.
                openCamera();
            } else {
                // Permission denied, show a rationale or disable the feature.
                Snackbar.make(findViewById(R.id.main_layout),
                        "Camera permission is required to take profile pictures.",
                        Snackbar.LENGTH_LONG).show();
            }
        }
    }
    
    private void openCamera() {
        Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(intent, CAMERA_REQUEST_CODE);
    }
    

With Runtime Permissions, developers need to focus more on explaining the necessity of requested permissions and handling various scenarios gracefully. This leads to more secure and user-friendly applications. Despite the additional complexity, adopting Runtime Permissions is crucial for adhering to modern Android security practices and maintaining a positive relationship with users.




Android Permissions Handling: Runtime Permissions - Step-by-Step Guide for Beginners

Introduction to Android Permissions

Permissions are an essential part of Android app development, ensuring that your application has access only to the resources it needs. Starting from Android 6.0 (API level 23), apps must request permissions at runtime. This change gives users more control over what their applications can do, enhancing privacy and security.

In this guide, we will walk you through the process of setting up, requesting, and handling runtime permissions in an Android application using a practical example. We'll use a simple scenario where our app needs to access the device's camera and location services to illustrate these concepts step-by-step.

Step 1: Set Up Your Project

  1. Create New Project:

    • Open Android Studio.
    • Go to "File" > "New" > "New Project".
    • Select "Empty Activity" and click "Next".
    • Name your project (e.g., "PermissionsApp").
    • Choose the language (Java or Kotlin — for this guide, I’ll use Kotlin).
    • Set the minimum API level to 23 (or higher).
    • Click "Finish" to create the project.
  2. Add Permissions to Manifest:

    • Open AndroidManifest.xml.
    • Declare the permissions your app needs using the <uses-permission> tag. For our example, add:
      <uses-permission android:name="android.permission.CAMERA"/>
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
      

    Note: These permissions are declared here but are not granted automatically from Android 6.0 onwards.

Step 2: Design the Layout

  1. Open res/layout/activity_main.xml:
    • Use the XML editor to design your UI.
    • Add a Button for accessing the camera and another for accessing location services.
    • Example layout:
      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical"
          android:padding="16dp">
      
          <Button
              android:id="@+id/button_camera"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Access Camera" />
      
          <Button
              android:id="@+id/button_location"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Access Location" />
      </LinearLayout>
      

Step 3: Code the Main Activity

  1. Open MainActivity.kt:

    • Implement the functionality to handle permission requests when buttons are clicked.
    • Example code for handling camera and location permissions:
    package com.example.permissionsapp
    
    import android.Manifest
    import android.content.pm.PackageManager
    import android.os.Bundle
    import android.widget.Button
    import android.widget.Toast
    import androidx.appcompat.app.AppCompatActivity
    import androidx.core.app.ActivityCompat
    import androidx.core.content.ContextCompat
    
    class MainActivity : AppCompatActivity() {
    
        // Define permission codes
        private val REQUEST_CAMERA_PERMISSION = 100
        private val REQUEST_LOCATION_PERMISSION = 200
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            // Find buttons by ID
            val buttonCamera: Button = findViewById(R.id.button_camera)
            val buttonLocation: Button = findViewById(R.id.button_location)
    
            // Set OnClickListener for Camera Button
            buttonCamera.setOnClickListener {
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                    == PackageManager.PERMISSION_GRANTED) {
                    // Permission already granted
                    openCamera()
                } else {
                    // Permission not granted, request it
                    ActivityCompat.requestPermissions(
                        this,
                        arrayOf(Manifest.permission.CAMERA),
                        REQUEST_CAMERA_PERMISSION
                    )
                }
            }
    
            // Set OnClickListener for Location Button
            buttonLocation.setOnClickListener {
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) {
                    // Permission already granted
                    getLocation()
                } else {
                    // Permission not granted, request it
                    ActivityCompat.requestPermissions(
                        this,
                        arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                        REQUEST_LOCATION_PERMISSION
                    )
                }
            }
        }
    
        // Method to open Camera
        private fun openCamera() {
            Toast.makeText(this, "Camera accessed successfully!", Toast.LENGTH_SHORT).show()
            // Add code to open your camera here
        }
    
        // Method to get Location
        private fun getLocation() {
            Toast.makeText(this, "Location accessed successfully!", Toast.LENGTH_SHORT).show()
            // Add code to get the current location here
        }
    
        // Handle the result of the permission request
        override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
            when (requestCode) {
                REQUEST_CAMERA_PERMISSION -> {
                    if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                        // Permission was granted
                        openCamera()
                    } else {
                        // Permission denied
                        Toast.makeText(this, "Camera permission denied", Toast.LENGTH_SHORT).show()
                    }
                    return
                }
                REQUEST_LOCATION_PERMISSION -> {
                    if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                        // Permission was granted
                        getLocation()
                    } else {
                        // Permission denied
                        Toast.makeText(this, "Location permission denied", Toast.LENGTH_SHORT).show()
                    }
                    return
                }
            }
        }
    }
    

Step 4: Run Your Application

  1. Connect a Device or Start an Emulator:

    • Ensure that your development environment is connected to a real Android device or an emulator running API level 23 or higher.
  2. Build and Run the App:

    • Click the "Run" button in Android Studio. The app will be built and installed on your connected device/emulator.
  3. Test the Buttons:

    • Tap the "Access Camera" button first. You should see a system dialog asking for camera permissions. Grant or deny the permission as per your choice.
    • Tap the "Access Location" button next. Similar to above, a system dialog should appear asking for location permissions. Again, grant or deny based on your preference.

Step 5: Understand the Data Flow

  1. Permission Check:

    • When a button is tapped, the app checks if it already has the required permission using ContextCompat.checkSelfPermission(this, permission). It returns either PackageManager.PERMISSION_GRANTED or PackageManager.PERMISSION_DENIED.
  2. Requesting Permission:

    • If the permission is not granted, the app uses ActivityCompat.requestPermissions(this, arrayOf(permission), REQUEST_CODE) to request the necessary permission from the user.
  3. Handling Permission Result:

    • The onRequestPermissionsResult(requestCode, permissions, grantResults) method receives the user's response.
    • If grantResults[0] == PackageManager.PERMISSION_GRANTED, the requested permission is granted, and the app can proceed with the desired operation (e.g., opening the camera or getting the location).
    • If grantResults[0] == PackageManager.PERMISSION_DENIED, the app must handle this appropriately; typically, the app will show a message to the user explaining why the permission is needed.
  4. User Interaction:

    • The user decides whether to allow or deny each permission request via system dialogs.
    • After granting or denying, the control returns to onRequestPermissionsResult() method in your activity for further action based on the decision.

Step 6: Additional Best Practices

  1. Explain Why Permission is Needed:

    • Before requesting a permission, consider showing an explanation dialog to explain why your app needs that particular permission.
    • Use shouldShowRequestPermissionRationale() to determine if you should show an explanation. Example:
      if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
          // Show a rationale explaining why the permission is needed
          Toast.makeText(this, "This permission is needed for camera functionality", Toast.LENGTH_LONG).show()
      } else {
          // Directly request the permission
          ActivityCompat.requestPermissions(
              this,
              arrayOf(Manifest.permission.CAMERA),
              REQUEST_CAMERA_PERMISSION
          )
      }
      
  2. Handle Multiple Permissions:

    • Sometimes, your app may need multiple permissions at once. You can request these permissions together by adding them to the array passed to requestPermissions() method.
    • Example:
      ActivityCompat.requestPermissions(
          this,
          arrayOf(Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION),
          REQUEST_MULTIPLE_PERMISSIONS
      )
      
    • Ensure to handle all responses appropriately in onRequestPermissionsResult() method.
  3. Design for Failure:

    • Always anticipate that users may deny a permission. Design your app to provide alternative ways to perform the same tasks without the restricted permission.

Conclusion

By following this step-by-step guide, you have learned how to implement and handle runtime permissions in an Android application. Understanding and properly implementing permissions is crucial not only for providing the necessary features within your app but also for respecting user privacy and complying with Android guidelines. Remember to always request permissions at runtime and provide clear, user-friendly explanations for why they are needed. Continue practicing and experimenting with different scenarios to become proficient in managing permissions effectively. Happy coding!




Certainly! Understanding Android permissions handling, especially runtime permissions, is crucial for developers creating applications that respect user privacy and follow best security practices. Below are the Top 10 questions with corresponding answers on this important topic.

1. What are runtime permissions in Android?

Answer: Introduced in Android 6.0 (API level 23), runtime permissions provide users more control over which app features can access potentially sensitive data or perform certain actions. Before Android 6.0, all requested permissions were granted at install time, with the user only having the option to accept or reject the entire permission bundle during installation. Runtime permissions require apps to request specific permissions from the user while the app is running, giving users a better understanding of exactly why an app needs access to particular resources.

2. Why are runtime permissions important?

Answer: Runtime permissions enhance user trust and privacy by allowing users to grant or deny specific features of an app access to sensitive user data or actions. They also enable app developers to tailor their app to the permissions a user grants, potentially offering reduced functionality if some permissions are denied. This granular control allows Android to better balance the need for apps to function properly and the need to protect user privacy.

3. When and how should you request a permission?

Answer: You should request runtime permissions when your app tries to perform an operation that requires a dangerous permission (such as reading contacts, accessing location data, or writing to external storage). The best practice is to request permissions just before performing the action. This helps in providing context to the user about why the permission is needed.

Here’s a basic example of requesting permissions:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
    != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
}
  • checkSelfPermission() checks if the permission has already been granted.
  • If not, ActivityCompat.requestPermissions() requests the permission from the user.

4. How do you handle the result of a runtime permission request in Android?

Answer: When you request a permission using ActivityCompat.requestPermissions(), the result is delivered via the onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) method. In this method, you must check whether the user granted the requested permission.

Here’s how to handle the result:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission was granted, so do the action that required it.
                readContacts();
            } else {
                // Permission denied, inform the user.
                Toast.makeText(this, "Permission denied to read contacts", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        // Add other cases as necessary.
    }
}

5. What are the types of permissions in Android?

Answer: There are two types of permissions in Android:

  1. Normal Permissions: These permissions cover areas of low risk and do not directly affect the user's privacy. They are declared in the AndroidManifest.xml and are automatically granted when the app installs. Examples include VIBRATE, INTERNET, and WAKE_LOCK.
  2. Dangerous Permissions: These permissions involve user data or device state that can affect the user's experience when used maliciously. Dangerous permissions require explicit user consent through runtime permission dialogs. Examples include ACCESS_FINE_LOCATION, READ_EXTERNAL_STORAGE, and CAMERA.

6. How does Android categorize dangerous permissions?

Answer: Dangerous permissions are grouped into six categories for easier management. These categories are:

  1. Calendar Permissions: Accessing and modifying the user’s calendar.
  2. Camera Permissions: Taking photos and recording video.
  3. Contacts Permissions: Reading or writing the user’s contacts.
  4. Location Permissions: Accessing approximate location and precise location.
  5. Microphone Permissions: Recording audio.
  6. Phone Permissions: Making calls and reading phone status.
  7. Sensors Permissions: Using body sensors like heart rate monitors.
  8. SMS Permissions: Sending or receiving SMS messages.
  9. Storage Permissions: Reading and writing files to storage.
  10. Notifications Permissions: Post notifications to the notification shade.
  11. Activity Recognition Permissions: Recognize the user's physical activity.

Each category contains a group of related permissions. For example, accessing the user’s camera is categorized under the "Camera Permission."

7. What happens if a user denies a permission request?

Answer: If a user denies a permission request, the app should respond gracefully by:

  • Informing the user that the feature is unavailable due to denied permissions.
  • Optionally, showing rationale explaining why the app needs the permission.
  • Disabling the UI feature that depends on the permission until the user grants it.
  • Allowing the user to enable the permission via the app's settings page if needed.

Handling denial well enhances user trust and satisfaction.

8. Can you explain how to show permission rationale in Android?

Answer: Permission rationale provides an explanation to the user about why an app needs a particular permission before making a request. This isn’t shown every time a permission request is made, but only when the user has previously denied the permission (not including the first time), and the app can provide justification.

Use ActivityCompat.shouldShowRequestPermissionRationale() method to check if the app needs to provide rationale:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
    != PackageManager.PERMISSION_GRANTED) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
        // Show an explanation to the user *asynchronously*.
        new AlertDialog.Builder(this)
            .setMessage("Camera permission is required to take photos")
            .setPositiveButton("OK", (dialog, id) -> ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA))
            .create()
            .show();
    } else {
        // No explanation needed, request the permission.
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA);
    }
}

If shouldShowRequestPermissionRationale() returns true, it means the user has denied the permission before without checking the "Never ask again" box.

9. How do you handle multiple permission requests in Android?

Answer: When dealing with multiple permissions, it's common to request them together. However, you should still handle each permission individually in onRequestPermissionsResult(). Here’s a basic way to request multiple permissions:

String[] permissions = {Manifest.permission.LOCATION, Manifest.permission.CAMERA};
ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE_MULTIPLE_PERMISSIONS);

And in the onRequestPermissionsResult(), handle each permission:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch(requestCode) {
        case REQUEST_CODE_MULTIPLE_PERMISSIONS: {
            if (grantResults.length > 0) {
                boolean locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                boolean cameraAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                if (locationAccepted && cameraAccepted) {
                    // Both permissions granted
                    startUsingLocationAndCamera();
                } else {
                    // Check which permission is denied and handle accordingly
                    if (!locationAccepted && ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.LOCATION)) {
                        showRationaleForLocationPermission();
                    } else if (!cameraAccepted && ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
                        showRationaleForCameraPermission();
                    }
                }
            }
        }
    }
}

This involves handling each permission individually to ensure you understand the user's choices and can provide appropriate feedback.

10. What steps should be taken after obtaining a granted permission?

Answer: Once a permission is granted, the app can proceed with the intended operation. However, it’s essential to handle permissions responsibly:

  1. Implement the feature: Use the granted permission to implement the desired functionality.
  2. Keep the permission scope limited: Only request and use the permissions absolutely necessary for the feature.
  3. Update app behavior: Continuously monitor and update app behavior based on the user's granted permissions.
  4. Re-check permissions: Re-check permissions at runtime, even if they were granted previously, since users can go to app settings and revoke them at any time.
  5. Handle changes gracefully: Provide user feedback when a feature becomes unavailable because a permission has been revoked.

Example:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == MY_PERMISSIONS_REQUEST_CAMERA) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Camera permissions were granted, open the camera.
            openCamera();
        } else {
            // Permission denial handling.
            handlePermissionDenial();
        }
    }
}

In this snippet, once the camera permission is granted, the openCamera() method is called to activate the camera functionality.


Summary: Properly handling runtime permissions in Android is essential for building trustworthy apps that maintain user privacy. Developers need to request permissions when necessary, handle permission denial appropriately, provide rationales, and manage permissions throughout the app lifecycle. Following these guidelines ensures a smooth and responsible user experience.