Skip to content

Android Privacy and Permission Best Practices: How to Prepare for Stricter 2026 Controls

Android Security

I submitted my app to the Play Store and got rejected. The reason? “Inconsistent data disclosures” and “improper permission handling.” I thought I was following best practices - I asked for permissions at launch, displayed a nice splash screen, and documented everything in my privacy policy.

But apparently, that’s not enough anymore. Android’s 2026 privacy controls are much stricter, and the Play Store now uses AI-driven policy enforcement. Apps that worked fine last year are suddenly getting flagged for permission issues.

After digging through documentation and fixing my app, I figured out what I was doing wrong. Here’s what I learned about Android permission best practices for 2026.

The Problem: Permission Flow Mistakes

My app was doing three things that got flagged:

  1. Requesting all permissions at app launch - Users saw a wall of permission requests before they even understood what the app did
  2. Running background location without proper foreground service notification - The app tracked location silently in the background
  3. Inconsistent data disclosures - My privacy policy said “we use location for navigation” but the app metadata said “location for weather”

Each of these is now a Play Store violation.

Play Store rejection message
Your app requests permissions that are not clearly justified
by the declared functionality. Specifically:
- Background location access without visible foreground service
- Permission requests at app start without user context
- Data disclosure mismatch between app metadata and actual usage

Why This Matters Now

Android’s enforcement has changed. It’s no longer just about whether your code works - it’s about whether your permission flows match your documented behavior.

Key changes in 2026
Old approach: New requirements:
--------------------------------|--------------------------------
Request permissions at launch | Request at moment of use
Background location silently | Visible foreground notification
Generic privacy policy | Specific data disclosures
Self-declared functionality | AI-verified consistency

The Play Store now compares your declared data usage against actual SDK behavior. If you use a third-party SDK that performs hidden tracking, you’re responsible for disclosing it - even if you didn’t know it was happening.

Mistake #1: Permission Requests at App Launch

I had this in my main activity:

WRONG: Requesting all permissions upfront
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// BAD: Request everything at start
ActivityCompat.requestPermissions(
this,
arrayOf(
ACCESS_FINE_LOCATION,
CAMERA,
READ_CONTACTS,
WRITE_EXTERNAL_STORAGE
),
PERMISSION_REQUEST_CODE
)
}

Users saw four permission dialogs before the app even showed its main screen. Most people just denied everything because they had no context.

The Fix: Request at Moment of Use

Each permission should be requested when the user triggers the feature that needs it:

CORRECT: Request permission when needed
class MapActivity : AppCompatActivity() {
private fun showUserLocation() {
when {
// Already granted
ContextCompat.checkSelfPermission(
this, ACCESS_FINE_LOCATION
) == PERMISSION_GRANTED -> {
startLocationUpdates()
}
// Show rationale first
ActivityCompat.shouldShowRequestPermissionRationale(
this, ACCESS_FINE_LOCATION
) -> {
showPermissionRationaleDialog(
message = "Location is needed to show your position on the map",
onAccept = {
requestLocationPermission()
}
)
}
// First time - just request
else -> {
requestLocationPermission()
}
}
}
private fun requestLocationPermission() {
ActivityCompat.requestPermissions(
this,
arrayOf(ACCESS_FINE_LOCATION),
LOCATION_REQUEST_CODE
)
}
}

The key difference: the user has already clicked “Show My Location” before the permission request appears. They understand the context.

Building a Rationale Dialog

When the user has denied permission once, Android recommends showing an explanation:

Permission rationale dialog implementation
fun showPermissionRationaleDialog(
message: String,
onAccept: () -> Unit
) {
AlertDialog.Builder(this)
.setTitle("Permission Required")
.setMessage(message)
.setPositiveButton("Grant Permission") { _, _ ->
onAccept()
}
.setNegativeButton("Cancel") { dialog, _ ->
dialog.dismiss()
}
.show()
}

I reuse this dialog for different permissions, passing different messages:

Contextual rationale messages
Location: "Location is needed to show your position on the map"
Camera: "Camera access is required to scan QR codes"
Contacts: "Contacts permission lets you share with friends"

Mistake #2: Background Location Without Foreground Service

My app tracked location in a background service but didn’t show any notification. Users had no idea their location was being tracked.

WRONG: Background location without notification
class LocationService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// BAD: No notification, silent tracking
startLocationTracking()
return START_STICKY
}
}

This worked on older Android versions. But starting with Android 14, background location requires a visible foreground service with a notification.

The Fix: Foreground Service Declaration

First, declare the service type in your manifest:

AndroidManifest.xml - Foreground service declaration
<service
android:name=".LocationTrackingService"
android:foregroundServiceType="location"
android:exported="false" />

Then start the service with a notification:

CORRECT: Foreground service with notification
class LocationTrackingService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val notification = createNotification()
// Start as foreground service with type
startForeground(
NOTIFICATION_ID,
notification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION
)
startLocationTracking()
return START_STICKY
}
private fun createNotification(): Notification {
return NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Location Tracking Active")
.setContentText("Your location is being tracked for navigation")
.setSmallIcon(R.drawable.ic_location)
.setPriority(NotificationCompat.PRIORITY_LOW)
.build()
}
}

The notification must be visible within 5 seconds of starting the foreground service. If you don’t show it, Android will crash your app.

Mistake #3: Inconsistent Data Disclosures

My privacy policy said one thing, but my app metadata said another. This inconsistency got flagged during the automated review.

Data disclosure mismatch example
Privacy policy: "We use location for weather updates"
App metadata: "Location required for navigation features"
Actual usage: Location SDK also tracks for advertising

I hadn’t reviewed the third-party SDKs I was using. One of them was collecting location data for ad targeting - something I never disclosed.

The Fix: Complete Data Safety Documentation

The Play Store’s Data Safety section requires you to disclose:

Data Safety checklist
1. What data you collect
2. How you use each data type
3. Whether data is shared with third parties
4. Whether data is encrypted
5. Whether users can request deletion

I created a table mapping each permission to its usage:

Permission usage documentation
Permission | My usage | Third-party SDK usage
--------------------|------------------|----------------------
ACCESS_FINE_LOCATION| Navigation only | Ad targeting (needs disclosure)
CAMERA | QR scanning | None
READ_CONTACTS | Sharing feature | None

The ad targeting disclosure was missing. I had to either:

  1. Remove the SDK that tracked for ads
  2. Add the disclosure to my Data Safety section

I chose option 1 - I didn’t want my users’ location used for ads.

The Permission Flow Diagram

Here’s how a proper permission request flow should work:

Permission request sequence
User action App response
------------------------|---------------------------
Tap "Show My Location" |
| Check if permission granted
| If yes: Show location
| If no: Check if rationale needed
|
| [Rationale needed?]
| Yes: Show dialog explaining why
| User accepts: Request permission
| User cancels: Don't request again
|
| No: First request
| Request permission
|
Permission dialog shown |
| User grants: Show location
| User denies: Show manual enable option

The user drives the flow. Permission requests happen only when needed, with clear context.

Common SDK Issues

Many rejections come from third-party SDKs doing things you didn’t expect:

SDK data collection audit checklist
SDK type | Known issues
----------------------|--------------------------------
Analytics SDKs | May collect location for targeting
Ad SDKs | Often track across apps
Social login SDKs | May collect device identifiers
Map SDKs | Some track location history
Push notification SDKs| May collect usage patterns

I now audit each SDK before adding it:

  1. Check the SDK’s privacy policy
  2. Review what permissions it requests
  3. Test with network logging to see actual data flows
  4. Document everything in my Data Safety section

Permission Best Practices Summary

After fixing my app, here’s what I now follow:

Permission checklist for 2026
✓ Request permissions at the moment of use
✓ Show rationale after first denial
✓ Use foreground services with notifications for background work
✓ Declare foreground service types in manifest
✓ Audit all third-party SDKs for hidden tracking
✓ Document actual data usage (not just intended usage)
✓ Keep privacy policy and app metadata consistent
✓ Provide users with data deletion options

The enforcement is automated. If your declared behavior doesn’t match your actual behavior, you’ll get flagged - regardless of whether you knew about the discrepancy.

What Got My App Approved

After implementing these changes:

  1. Permission requests moved to feature-trigger points
  2. Background location now shows a foreground notification
  3. Removed the ad-tracking SDK
  4. Updated Data Safety section with accurate disclosures
  5. Privacy policy matches app metadata
Approved app structure
Splash screen: No permission requests
Main screen: User explores app features
Feature trigger: Permission request with context
Background work: Visible foreground notification
Data disclosure: Matches actual SDK behavior

The second submission passed review within 24 hours.


Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments