How does Permission best practices work internally in Android SDK?

In Android, permission best practices are essential for ensuring user privacy and security while allowing apps to access sensitive data or device features. The Android SDK implements a permission model that comprises two primary types of permissions: normal and dangerous. Understanding these distinctions and how to request permissions effectively can enhance user experience and app reliability.

Types of Permissions

Android permissions fall into two categories:

  • Normal Permissions: These do not pose a significant risk to the user's privacy. The system automatically grants these permissions during installation. Examples include internet access, accessing the network state, etc.
  • Dangerous Permissions: These are permissions that can affect the user's privacy or the device's operation. Examples include accessing the user's location, contacts, and camera. For these permissions, the app must explicitly request them at runtime.

Requesting Permissions at Runtime

For dangerous permissions, the app must check whether it has the permission, and if not, request it from the user. Here's an example of how to properly request a dangerous permission:

    // Check for the permission
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {
        
        // If permission is not granted, request it
        ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
            LOCATION_PERMISSION_REQUEST_CODE);
    } else {
        // Permission has already been granted; proceed with accessing location features
        accessLocation();
    }

    // Handle the user's response to the permission request
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case LOCATION_PERMISSION_REQUEST_CODE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission was granted, proceed with accessing location
                    accessLocation();
                } else {
                    // Permission denied; handle appropriately
                }
                return;
            }
        }
    }
    

Best Practices

To help ensure a positive user experience regarding permissions:

  • Request only the permissions you need to function.
  • Explain why certain permissions are being requested using dialog prompts.
  • Gracefully handle cases where users deny permissions.
  • Utilize the system's permission rationale dialog to provide context.

Android permissions runtime permissions dangerous permissions normal permissions app security user privacy permission requests