All Articles
CategoryAndroid
Reading Time
15 min read
Published
2026-09-24
Word Count
3,753words

Grab a coffee — this one is a deep dive!

Google Play Permission Policy 2027: Contacts, Location, SMS

Summary

Google Play's 2027 permission policy overhauls contacts, sensitive location, and SMS/call log verification. The January 27 timeline, plus Contact Picker and location button migration, with code.

  • Four Google Play permission policy items take effect together on January 27, 2027: contacts, location, SMS/call log, and foreground service.
  • September 30, 2026 has two layers: Play Console registration is a GLOBAL requirement (global removal risk for unregistered apps), while the device-side new-install block only starts in Brazil, Indonesia, Singapore, and Thailand.
  • In apps targeting Android 17+, Contact Picker replaces broad READ_CONTACTS, and onlyForLocationButton becomes the recommended minimum scope for sensitive location.
  • Play Console pre-review warnings start October 27, 2026 and cover only contacts and location permissions; filling out the Declaration form before that date reduces rejection risk.
Google Play Permission Policy 2027: Contacts, Location, SMS

Google Play permission policy is undergoing a fundamental revision toward 2027: contact access shifts from broad permission to a picker-based model, "location button" becomes the recommended minimum scope for sensitive location, and call log permission for phone verification is disabled. Below: the timeline, what changes at the code level, and what to check in Play Console — all in one place.

💡 Pro Tip: Most of the changes take effect on January 27, 2027, but pre-review warnings in Play Console start appearing from October 27, 2026 — preparing your code by October prevents a surprise rejection on enforcement day.

Table of Contents

The 2026-2027 compliance timeline in one table

Google is rolling out Android developer verification and permission policy changes in the same period; it's important not to mix them up because their scope and dates differ.

September 30, 2026 brings two separate layers

General registration for developer verification opened to all developers in March 2026. September 30, 2026 brings two separate things at once, and mixing them up gets expensive.

The first layer is global: Play Console registration. You must keep the apps you distribute on Play registered in Play Console, and this rule has no geographic boundary. The policy page's September 30, 2026 "Play Console Requirements" line says verbatim: "To meet Android developer verification requirements and Play Console requirements, you must register your Play apps in Play Console." The same line says 99% of apps are automatically registered on Play, and for the rest you need to check the Play Console Home page and complete registration manually, otherwise the risk of "global removal from Google Play" arises. In other words, being in Turkey doesn't exempt you from this date.

The second layer is regional: a device-side new-install block in four countries. On the same date, in Brazil, Indonesia, Singapore, and Thailand, on certified Android devices, apps from unregistered developers can't be installed through the normal install flow; installation via adb is independent of this requirement, and there is also a separate "advanced flow" sideload path for unregistered apps. The global expansion of device-side protection is planned for 2027. We covered the details of this layer one by one in our developer verification and sideload article.

Four items taking effect on January 27, 2027

On the permission policy side, four changes take effect at once on January 27, 2027:

Area
Change
Effective
Preparation window
Contacts
In apps targeting Android 17+, Contact Picker becomes mandatory instead of broad READ_CONTACTS
January 27, 2027
Declaration form opens before October 2026
Location
"location button" (onlyForLocationButton) becomes the recommended minimum scope for sensitive location
January 27, 2027
Play policy insights (Android Studio) arrives by October 2026
SMS / Call Log
Account verification via phone call using READ_CALL_LOG is no longer accepted
January 27, 2027
Migration to Digital Credentials API / SMS Retriever API
Foreground Service
Geofencing stops being an approved use case for foreground service
January 27, 2027
Migration to Geofence API

Pre-review checks in Play Console kick in from October 27, 2026; in the announcement's wording, these checks flag "potential contacts or location permissions policy issues" — meaning the scope is limited to contacts and location permissions, and the SMS/call log and foreground service items are not covered by pre-review. Still, three months before the enforcement date, you'll start seeing warnings during submission for your contacts and location flows.

Why you should learn this timeline now

Although all four changes take effect on the same day (January 27, 2027), the code-side work concerns three separate teams (contacts, location, authentication), each with its own test cycle. The Declaration form opening before October 2026 shows Google designed this as a review process, not a one-time "flip a flag" — the justification you submit is subject to review, so the application-review-approval cycle can take time. Pre-review warnings starting three months early are part of the same logic: a visible early-warning window to fix your code.

Contacts access: moving from broad permission to picker

The current policy already requires requesting permissions contextually and progressively, and getting renewed consent if you use data beyond its originally collected purpose. The layer added on January 27, 2027: in apps targeting Android 17+, an app's need for continuous access to all contacts must be justified when the Android Contact Picker is insufficient — submitted via the Play Developer Declaration form in Play Console.

With Contact Picker, the user decides which contact to share; the developer only specifies the fields it needs (phone, email, etc.), and READ_CONTACTS permission is never requested. The documentation describes this integration via the ContactsPickerSessionContract.ACTION_PICK_CONTACTS intent; the requested fields are passed as an ArrayList<String> of ContactsContract.CommonDataKinds MIME types in the EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS extra. Contact data isn't the only path: Play's restricted permissions policy also counts Sharesheet among the privacy-oriented alternatives, saying "System pickers and alternatives like Sharesheet are designed to support a privacy-oriented path for developers."

Before the code — fetching the contact list with broad permission:

kotlin
1// Common pattern before Android 17: requesting access to the entire address book
2if (ContextCompat.checkSelfPermission(
3 context, Manifest.permission.READ_CONTACTS
4 ) != PackageManager.PERMISSION_GRANTED
5) {
6 ActivityCompat.requestPermissions(
7 activity, arrayOf(Manifest.permission.READ_CONTACTS), REQUEST_CODE
8 )
9}
10// If granted, the entire address book is queried via ContentResolver

After the code — field-based selection with Contact Picker (Android 17 / API 37):

kotlin
1// ContactPickerActivity.kt
2import android.app.Activity
3import android.content.Intent
4import android.net.Uri
5import android.os.Bundle
6import android.provider.ContactsContract
7import android.provider.ContactsContract.CommonDataKinds.Email
8import android.provider.ContactsContract.CommonDataKinds.Phone
9import android.provider.ContactsPickerSessionContract.ACTION_PICK_CONTACTS
10import android.provider.ContactsPickerSessionContract.EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS
11import android.util.Log
12import androidx.activity.ComponentActivity
13import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
14 
15class ContactPickerActivity : ComponentActivity() {
16 
17 // The picker returns a single Session Uri; no separate Uri query per contact is needed.
18 private val pickContacts =
19 registerForActivityResult(StartActivityForResult()) { result ->
20 if (result.resultCode != Activity.RESULT_OK) return@registerForActivityResult
21 val sessionUri: Uri = result.data?.data ?: return@registerForActivityResult
22 readSelectedContacts(sessionUri)
23 }
24 
25 override fun onCreate(savedInstanceState: Bundle?) {
26 super.onCreate(savedInstanceState)
27 // READ_CONTACTS permission is never requested; only the needed fields are declared.
28 val requestedFields = arrayListOf(
29 Phone.CONTENT_ITEM_TYPE,
30 Email.CONTENT_ITEM_TYPE
31 )
32 val pickIntent = Intent(ACTION_PICK_CONTACTS).apply {
33 putStringArrayListExtra(
34 EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS,
35 requestedFields
36 )
37 }
38 pickContacts.launch(pickIntent)
39 }
40 
41 private fun readSelectedContacts(sessionUri: Uri) {
42 val projection = arrayOf(
43 ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
44 ContactsContract.Data.MIMETYPE,
45 ContactsContract.Data.DATA1
46 )
47 // Session Uri doesn't support custom selection/selectionArgs; it's queried directly.
48 contentResolver.query(sessionUri, projection, null, null, null)?.use { cursor ->
49 val nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY)
50 val mimeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE)
51 val dataIdx = cursor.getColumnIndex(ContactsContract.Data.DATA1)
52 while (cursor.moveToNext()) {
53 val name = cursor.getString(nameIdx).orEmpty()
54 val mimeType = cursor.getString(mimeIdx).orEmpty()
55 val value = cursor.getString(dataIdx).orEmpty()
56 // value only contains the field the user chose to share
57 when (mimeType) {
58 Phone.CONTENT_ITEM_TYPE -> Log.d("picker", "$name phone: $value")
59 Email.CONTENT_ITEM_TYPE -> Log.d("picker", "$name email: $value")
60 else -> Unit
61 }
62 }
63 }
64 }
65}

If your app genuinely needs continuous, broad contact access (for example, a backup or CRM app), you need to justify this need in the Play Developer Declaration form; the form becomes available in Play Console before October 2026.

Why progressive permission requesting still matters

The current policy expects you to request permissions progressively, showing the user contextually why you're asking — instead of asking for everything back-to-back at launch, trigger the request when the user touches the feature that needs it. Contact Picker aligns with this: when the user taps "share contact," the picker opens, and there isn't even a separate permission-request step. If your app later wants to use contact data for a different purpose (e.g. marketing analysis), you still need separate, explicit consent — this isn't new, and Contact Picker doesn't remove that obligation.

Narrowing the location scope

The same logic applies to location: narrow-scoped, context-specific access instead of broad, continuous permission. Google defines the location button as the recommended minimum scope for sensitive location. The docs' definition, verbatim: "a customizable system UI element designed to simplify how you request session-scoped precise location access" — meaning when the user taps the button, the app gets session-scoped precise location; no continuous background access needed.

On the manifest side, three lines are needed together; the onlyForLocationButton flag is just one of them and is marked "Optional" in the docs. USE_LOCATION_BUTTON, required for the button to be rendered on screen, is given with the note "CRITICAL: Required system permission for rendering the LocationButton":

xml
1<!-- AndroidManifest.xml -->
2<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
3 
4<!-- Optional: only if you get sensitive location via the location button -->
5<uses-permission
6 android:name="android.permission.ACCESS_FINE_LOCATION"
7 android:usesPermissionFlags="onlyForLocationButton" />
8 
9<!-- CRITICAL: Required for the LocationButton to be rendered -->
10<uses-permission android:name="android.permission.USE_LOCATION_BUTTON" />

You don't draw the button by hand: the docs describe the integration via the androidx.core.locationbutton Jetpack library, and explicitly note that this library is experimental and subject to change. So keep in mind that while you're testing it in a build, the API surface can shift across versions.

If your app genuinely needs continuous or background sensitive location — for example, a navigation or fleet-tracking app — you need to justify this too in the Play Developer Declaration form; otherwise onlyForLocationButton may be flagged as insufficient scope. The "Only this time" option, which has existed since Android 11, is the runtime counterpart of the same philosophy: the user grants location once, and access ends a short time after the app goes to the background; if you launched a foreground service while the activity was visible, access continues after the app moves to the background until that foreground service stops; if the user revokes it in settings, access is cut off immediately and the app's process is terminated.

The difference between location button and the current runtime flow

Until now, your flow for precise location was probably requesting ACCESS_FINE_LOCATION directly via requestPermissions(); the user chose between "Only this time," "While using the app," or "Deny." Location button reverses this: access starts directly from the user tapping the system button in the app's UI, and stays limited to session scope. In the doc's wording, this reduces the friction of repeated dialogs typical of "only this time" temporary permissions — shortening the UX while enforcing Google's "only when needed, as much as needed" principle at the code level. Continuous background tracking (delivery, fleet management) still needs separate justification.

Alternatives to call log for phone verification

The policy on SMS and Call Log permissions is already strict: before requesting these permissions, your app must be registered as the actively default handler for SMS, Phone, or Assistant. Starting January 27, 2027, a new restriction is added to this — READ_CALL_LOG permission can no longer be used for account verification via phone call.

Google shows two alternatives for this use case: Digital Credentials API and SMS Retriever API. SMS Retriever API lets you automatically capture the incoming verification SMS and read it in code, without asking the user for SMS read permission:

kotlin
1val client = SmsRetriever.getClient(context)
2client.startSmsRetriever().addOnSuccessListener {
3 // Start listening for the retriever broadcast, without requesting SMS permission
4}
5 
6val smsVerifyReceiver = object : BroadcastReceiver() {
7 override fun onReceive(context: Context, intent: Intent) {
8 if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) {
9 val extras = intent.extras
10 val status = extras?.get(SmsRetriever.EXTRA_STATUS) as? Status
11 if (status?.statusCode == CommonStatusCodes.SUCCESS) {
12 val message = extras.getString(SmsRetriever.EXTRA_SMS_MESSAGE)
13 // Extract the verification code from the message
14 }
15 }
16 }
17}

When a restricted permission (e.g. Call Log) is denied by the user, the current policy also requires the app to offer a reasonable alternative — for example, letting the user enter their phone number manually. This requirement is already in effect under the current policy, not because of the 2027 change; the new rule only closes off the "call log = verification method" mapping.

Background location and foreground service justifications

For foreground service use, the policy wants the reason for starting the service to be visible and consistent to the user. Starting January 27, 2027, geofencing is no longer an approved use case for foreground service — meaning a flow like "show a notification when the user enters/exits a certain area" needs to be built via the platform's own Geofence API, not via foreground service.

In practice: if your app currently listens for location inside a foreground service and hand-writes its own geofence logic (coordinate comparison, distance calculation), that approach risks rejection after 2027. Geofence API provides the same functionality system-side, battery-friendly, without a foreground service — a win for both compliance and battery.

Rejection scenarios and the appeal process

Apps that don't meet policy requirements or don't submit the required Declaration form can be removed from Google Play. The current policy text states this clearly: "Apps that fail to meet policy requirements or lack a Permissions Declaration Form may be removed from Google Play."

To protect yourself from this risk, pay attention to three points:

  • Fill out the Declaration form early. The form becomes available in Play Console before October 2026; submitting your justified application early, without waiting for the enforcement date (January 27, 2027), reduces rejection risk.
  • Show the runtime rationale completely. For restricted permission requests (including examples like READ_CALENDAR), you need to present a clear justification and not manipulate the user; skipping the shouldShowRequestPermissionRationale() flow can be considered a policy violation.
  • Don't forget the alternative flow. Your app shouldn't crash or become non-functional when the user denies permission — you're expected to offer a reasonable fallback scenario, such as manual entry.

When you get rejected, the policy violation notice in Play Console usually states which item was triggered; before appealing, check your Play Console notifications and your email to find out which policy your app violated; then submit your appeal through the "File an appeal" form (you may submit one appeal per removal, suspension, or other enforcement action) and present an explanation consistent with the justification you stated in the Declaration form.

Compliance checklist

Rather than handling the four policy items one by one, managing the October-January window as a single sequenced flow leads to fewer mistakes: first verify your current state, then make the code changes, then close out the Play Console processes — order matters because you need clarity on which flows actually require justification before filling out the Declaration form.

Things to check in order during the October-January preparation window:

Step
When
What to do
Play Console registration status
Now
Verify on Play Console Home whether developer registration completed automatically
Move to Contact Picker
Before October 2026
Replace flows using READ_CONTACTS with the ACTION_PICK_CONTACTS picker
Try the location button
Before October 2026
Test the onlyForLocationButton flag in a test build, review the UX
SMS/Call Log alternatives
Before October 2026
Move the phone verification flow to SMS Retriever API or Digital Credentials API
Foreground service review
Before October 2026
Replace foreground service used for geofencing with Geofence API
Declaration form
As soon as the form opens
Write and submit your justification if you need broad contacts/continuous location
Play policy insights
By October 2026
Add the new warning panel in Android Studio to your pipeline
Pre-review tracking
From October 27, 2026
Read and resolve the new policy warnings in Play Console on every submission

GOLDEN TIP

The most valuable insight in this article

This tip holds the article's most important takeaway.

Easter Egg

You found a hidden gem!

There's a hidden detail in this section. Want to uncover it?

Reader Reward

You can copy the items below to turn the compliance checklist in this article into a one-page copy; check off each item as you complete it and track your progress through the October-January window.

FAQ

When is the Play Console registration deadline?

September 30, 2026 is the global deadline for Play Console registration: you need to keep the apps you distribute on Play registered in Play Console, otherwise the risk of "global removal from Google Play" arises, in the policy page's wording. Play says 99% of apps are registered automatically; verify from the Play Console Home page whether you fall into the remaining exception. A second, separate layer starts on the same date: in Brazil, Indonesia, Singapore, and Thailand, on certified devices, apps from unregistered developers can't be installed through the normal install flow; installation via adb is independent of this requirement, and a separate "advanced flow" sideload path for unregistered apps remains open. The global expansion of device-side protection is planned for 2027.

Which permissions are being narrowed in 2027?

On January 27, 2027, four changes take effect together: mandatory Contact Picker instead of broad READ_CONTACTS in apps targeting Android 17+, location button (onlyForLocationButton) becoming the recommended minimum scope for sensitive location, removal of phone verification via READ_CALL_LOG, and geofencing no longer being an approved use case in foreground service.

Which picker APIs should be used instead of broad permission?

For contact data, Android's built-in Contact Picker (ContactsPickerSessionContract.ACTION_PICK_CONTACTS) or privacy-oriented alternatives like Sharesheet; for sensitive location, the location button rendered with USE_LOCATION_BUTTON and scoped down with the onlyForLocationButton flag; and for phone verification, the Digital Credentials API or SMS Retriever API should be used.

What happens if I don't fill out the Declaration form?

Apps that don't meet policy requirements or lack the required Permissions Declaration Form can be removed from Google Play. If you have needs like broad contact access or continuous sensitive location, you shouldn't enter the enforcement date without filling out this form and presenting your justification.

When do pre-review warnings start?

Pre-review checks in Play Console kick in from October 27, 2026 — three months before the January 27, 2027 enforcement date. The announcement defines the scope of these checks as "potential contacts or location permissions policy issues" — meaning the warnings come for contacts and location permissions; the SMS/call log and foreground service items aren't covered by pre-review.

Are these changes the same thing as Android Developer Verification?

No. Android Developer Verification is about verifying the identity of the developer signing the apps; it kicks in on September 30, 2026 as both a global Play Console registration requirement and a device-side install restriction in four countries. The permission policy changes in this article (contacts, location, SMS/call log, foreground service) are a separate policy set and take effect on January 27, 2027.

Conclusion

The transition to 2027 isn't one big change, it's four separate policy items converging on the same date (January 27, 2027). The biggest code-side work is moving contact access to Contact Picker and migrating phone verification to SMS Retriever or Digital Credentials API; the most critical process step is filling out the Declaration form months before enforcement. You can check out our guide to other changes that will break your app on Android 17 (API 37), or read our article for those who missed the Google Play API 36 deadline. If you're curious about developer verification's impact on sideloading, we covered that in detail in a separate article; for Android 15-era Privacy Sandbox and foreground service changes, our previous guide is still a solid foundation. For a subscription-side topic that's independent of permission policy but relevant in the same period, check out our Google Play Billing v7 guide.

Sources

Tags

#Google Play#Android permissions#Contact Picker#READ_CONTACTS#location button#Play Console#SMS Retriever#2027
Muhittin Çamdalı

Muhittin Çamdalı

Lead Mobile Engineer

Lead Mobile Engineer with 12+ years of experience. Expert in iOS, Android and cross-platform architectures with Swift, SwiftUI, Kotlin and Flutter. I build performant, user-friendly mobile apps.

iOS Development News

Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.

We respect your privacy. You can unsubscribe at any time.

Share