๐Ÿ” Android Security and Privacy

Android Permissions and Privacy Best Practices

Every permission you request is a trust decision for the user, and a policy obligation for you. Modern Android offers privacy-preserving alternatives for many old permission requests. Here's how to request less, ask better, and stay compliant.

โœ๏ธ Yunok Tech ๐Ÿ“… Updated โฑ 3 min read ๐ŸŽฏ Beginner
On this page
  1. Principles
  2. Requesting permissions in Compose
  3. Permission-free alternatives
  4. Sensitive and restricted permissions
  5. Disclosure and Data safety
  6. Examples
  7. Frequently asked questions
  8. Conclusion

A camera app asking for contacts, a flashlight asking for location: users notice, and they uninstall. Google Play also restricts sensitive permissions and requires accurate data disclosures. Good permission design is both better UX and better compliance.

Principles

  1. Avoid the permission if a privacy-preserving API exists (Photo Picker, document picker, Credential Manager).
  2. Ask in context, when the user triggers the feature, not at app launch.
  3. Request the minimum: approximate instead of precise location, and foreground instead of background.
  4. Degrade gracefully when denied: the rest of the app must keep working.
Runtime permission request flow The user taps a feature. If the permission is already granted, use the feature. If not and a rationale should be shown, explain why in your own UI first. Then the system permission dialog appears. If granted, continue; if denied, offer a fallback; if permanently denied, offer a link to app settings. User taps"Scan receipt" Granted?check first yes Rationaleyour own UI System dialog use feature denied โ†’ fallback ยท permanently โ†’ Settings link
Explain before asking, and always have a path forward when the answer is no.

Requesting permissions in Compose

CameraPermissionGate.ktKotlin
@Composable
fun CameraFeatureButton(onCameraReady: () -> Unit) {
    val context = LocalContext.current
    var showRationale by remember { mutableStateOf(false) }
    var showSettingsHint by remember { mutableStateOf(false) }

    val launcher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
        if (granted) onCameraReady()
        else {
            val activity = context.findActivity()
            // If the system won't show a rationale after a denial, the user chose "don't ask again".
            showSettingsHint = activity != null &&
                !ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)
        }
    }

    Button(onClick = {
        when {
            ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) ==
                PackageManager.PERMISSION_GRANTED -> onCameraReady()
            else -> showRationale = true
        }
    }) { Text("Scan receipt") }

    if (showRationale) AlertDialog(
        onDismissRequest = { showRationale = false },
        title = { Text("Camera access") },
        text = { Text("We use the camera only to scan receipts. Photos stay on your device unless you choose to upload them.") },
        confirmButton = { TextButton(onClick = { showRationale = false; launcher.launch(Manifest.permission.CAMERA) }) { Text("Continue") } },
        dismissButton = { TextButton(onClick = { showRationale = false }) { Text("Not now") } },
    )

    if (showSettingsHint) TextButton(onClick = {
        context.startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package", context.packageName, null)))
    }) { Text("Enable camera in Settings") }
}

fun Context.findActivity(): Activity? = when (this) {
    is Activity -> this
    is ContextWrapper -> baseContext.findActivity()
    else -> null
}

Permission-free alternatives

NeedInstead ofUse
Pick photos/videosStorage or media read permissionsPhoto Picker (PickVisualMedia)
Open a documentBroad storage accessStorage Access Framework (OpenDocument)
Take one photoCAMERA in your own camera UI (if not needed)Camera intent (TakePicture)
Rough location (weather, city)ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION (approximate)
Sign-in with saved credentialsReading accountsCredential Manager
Photo Picker: no storage permission neededKotlin
val pickImage = rememberLauncherForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
    uri?.let(onImagePicked)
}
// pickImage.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))

Sensitive and restricted permissions

Background location, SMS and call log, all-files access, exact alarms, accessibility services and others are restricted by Google Play policy and require declarations or justifications. Use them only when they're core to your app's functionality, and check current Play policy before building features around them.

Disclosure and Data safety

  • Your Play Console Data safety form must accurately describe data collection and sharing, including by SDKs.
  • Provide a privacy policy that matches actual behaviour.
  • Use prominent in-app disclosure before collecting sensitive data where Play policy requires it.
  • Audit third-party SDKs: their collection counts as yours.

Examples

Profile photo

The Photo Picker, with no permission at all.

Weather app

Approximate location, requested when the user taps "Use my location", with manual city entry as a fallback.

Delivery notifications

POST_NOTIFICATIONS requested after the first order, not on first launch.

Frequently asked questions

Can I request several permissions at once?

You can, with RequestMultiplePermissions, but users trust focused, contextual requests more. Bundle only those needed for one feature.

What happens if the user selects "Only this time"?

The permission is granted temporarily and revoked later. Always re-check before use.

Do unused apps lose permissions?

Yes. Android can auto-reset permissions for apps that haven't been used for a while, so always check at runtime.

Conclusion

Request fewer, smaller, contextual permissions, explain why before asking, prefer privacy-preserving APIs like the Photo Picker, handle denial gracefully, and keep your Data safety disclosures accurate.

Next step: add strong, convenient authentication with Biometric Authentication on Android.

Official references

๐Ÿ“ฑ Apps built by Yunok Tech

Real Android apps on Google Play, free to download.

See all our apps โ†’

Ready to build real Android applications?

Security is easiest to get right when it is part of how you build from the first screen. Strengthen the Android fundamentals that secure, privacy-respecting apps are built on.

Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.

Explore the Android course and take your next step as an Android developer.

Share: LinkedIn X / Twitter WhatsApp