Google Play Contacts Permission Policy: READ_CONTACTS
Apps targeting API 37 may only request READ_CONTACTS if the Contact Picker falls short. Why an open declaration stalls your closed test before day one.
On this page9 sections
- 01What Google's contacts permission policy requires
- 02Who is in scope, and when the rule catches you
- 03Why a contacts declaration can stop a closed test before day one
- 04The two declaration questions, and the answers that fail
- 05Migrating to the Contact Picker
- 06MANAGE_CONTACTS: the second policy, announced October 29, 2026
- 07What to do in your closed test this week
- 08Frequently asked questions
- 09Sources
From January 27, 2027, an app that targets Android 17 (API level 37) or higher may only request READ_CONTACTS if the Android Contact Picker cannot deliver its core functionality, and it must file a Play Console declaration explaining why the picker is not enough. That part is written plainly on Google's policy pages. The part that costs developers two weeks is elsewhere: the declaration sits in App content, and an unresolved App content item on an active bundle blocks every publishing change, closed testing included. So a contacts-permission problem rarely arrives as a rejection email. It arrives as a closed test where your testers have nothing new to install.
What Google's contacts permission policy requires
Google announced the Contacts Permission policy on April 15, 2026 and began prompting affected developers in Play Console from September 2026. Compliance became mandatory on January 27, 2027 for apps that target API 37 or higher, with a 30-day automatic self-extension available in Console. The operative rule, in Google's own words:
"Apps that target Android 17 or higher (API level 37+) may only request the READ_CONTACTS permission if the Android Contact Picker is not sufficient for your app to provide core functionality. Apps that still request the READ_CONTACTS permission must submit a Play Console declaration to demonstrate access needs for Contacts and why Contact Picker would not suffice."
Read that as a two-branch decision, not a ban. If a picker covers your feature, you drop the permission and ship. If it genuinely cannot, you keep the permission and take on a review obligation. There is no third branch where you keep the permission and skip the declaration.
Two supporting rules on the same page get overlooked. Access must be necessary for features you actually promote in your store listing, not for capability the code happens to contain, and minimum scope is the standard Google applies: system pickers and Sharesheet are the default, with the restricted permission as the exception you have to justify. Google also states that apps may not disclose or publish non-public contacts data unless the individual contacts authorise it, which is a separate obligation from the declaration and survives an approval.
The 30-day automatic self-extension is worth understanding before you lean on it. It is an option in Play Console that buys time against the deadline; it does not remove the declaration requirement, and it does not shorten the review that follows submission. A developer who plans around the extension and not around the review queue ends up blocked in February with a test that cannot ship.
Who is in scope, and when the rule catches you
Two conditions must both be true: the build's targetSdkVersion is 37 or higher, and the manifest still requests READ_CONTACTS. Apps that target API 36 and below are outside this policy regardless of what they request. Google's target-API requirement currently sits at API 36 for new apps and updates since August 31, 2026, so an untouched project is not in scope on paper today.
That is a temporary shelter, not an exemption. Every time you bump targetSdk for the next Play requirement, or rebuild a template project against the latest SDK, the app moves into scope with no other change. Our reading of the two documents together is that the in-scope population grows on the same schedule as the target-API rule, so a project that ignores this now inherits the problem at the worst possible moment, which is mid-test.
Device coverage is a separate axis from policy scope. The Contact Picker exists only on devices running Android 17 or higher and is not backported, so a user on Android 16 sees no picker no matter what your app targets. Plan the old-device path before you write the migration, not after.
Check the number instead of the intention. It sits in the app module's build.gradle as targetSdk, and Play Console records the target SDK against each uploaded bundle, which is the version that counts because the policy is applied to what you shipped rather than to a build file someone edited after the fact.
There is one genuine scope limit for indie developers: this is a Google Play policy, so an APK you hand out yourself or ship through another store is not covered by it. Publish the same code on Play at the same target SDK and it is. If you are mid-test with a build that targets 36, you have room to finish that run before dealing with the contacts question, which is the one advantage of starting now rather than in January.
Why a contacts declaration can stop a closed test before day one
Google ties permission declarations to publishing itself, not just to review:
"If you have an active app bundle that requires a Permissions Declaration, including releases on the Open, Closed, or Internal test tracks, an alert is displayed on the left menu under App Content. You cannot publish any changes to your app, including changes to your Store Presence ... until you address this alert."
Pre-review checks reinforce it. Play Console now runs automated checks when you queue a change, and Google states those checks "verify that updates contain all mandatory declarations on your app's App content page", with missing declarations listed among the issues you must resolve before publication rather than ones you can wave through.
The tail is the expensive part. Once you do submit a sensitive-permission declaration, Google says the request "may require up to several weeks to process", and during that time the app or update "will be in a pending publication status". Overriding a pending publication with another release can add further delay.
For a closed test, that chain has a specific shape. The bundle you uploaded to the closed track cannot roll out. Testers who already opted in keep the previous build. Testers you are still recruiting have no new version to install. The 14-day clock is measured on opted-in testers, so nothing resets, but your test coverage stalls at exactly the point where you were trying to prove engagement.
| What you see in Console | What it means | What to do |
|---|---|---|
| Alert under App content, Permissions | An active bundle on a test track requests a permission with no declaration on file | Complete the declaration, or remove the permission, before uploading the next build |
| Pre-review check blocks submission | Mandatory App content declaration is missing and cannot be deferred | Finish App content, then use Publishing overview to send changes for review |
| Release stuck in pending publication | Google is reviewing the permission request, which can take several weeks | Do not override with another release; move your test dates and tell testers |
| Testers report no opt-in link or an old version | The new version never rolled out to the track | Check the track's release history before blaming the invite list |
If testers report they cannot see the app at all rather than an old build, work through the opt-in link diagnostics first, because that has separate causes from a held release.
The two declaration questions, and the answers that fail
The contacts declaration is short. Google lists two required questions: which user-facing features need READ_CONTACTS, and why the Contact Picker is not sufficient for them. Both are judged on core functionality as promoted in your store listing, not on what the code technically could do.
The first question offers a fixed set of use cases: contact management, dialer and in-call screens, call history, business contact tools, spam and call blocking, assistive technology, AI agents that need deep contact access, social discovery and friend matching, backup and restore, keyboard autocorrect and autocomplete, and user-initiated contact selection. That last option is a trap worth naming, because Google's own FAQ on the same page says apps that request the permission only for "sharing files, collaborating, inviting/referring someone to join a service, choosing a contact to transact with" should not request it at all. The option exists in the form; the FAQ says it does not justify the permission. Pick "user-initiated selection" and you have effectively answered question two against yourself.
| Feature in your app | Declaration defensible? | What Google points you to |
|---|---|---|
| Invite a friend, share a file, pay a contact | No | Contact Picker or Sharesheet, permission removed |
| Custom in-app contact list you built yourself | No | Google states a custom picker does not qualify; rebuild on the system picker |
| Friend matching against your own user base | Possibly | Declaration, with the social discovery use case selected |
| Dedicated contacts app, dialer, backup tool | Yes | Declaration, with the matching use case and an explanation of the gap |
| Keyboard autocomplete of names and emails | Yes, as listed | Declaration, autocorrect and autocomplete use case |
| AI agent that answers contact questions on command | Listed, but scrutinised | Declaration, AI agent use case, with the specific commands it must serve |
Question two is where most declarations fail, because "it is easier for us" is not a technical insufficiency. Google's FAQ says a custom picking experience "does not qualify as a reason to retain Contacts access". What does stand up is a described gap: the picker returns only user-selected contacts once per session, so a feature that must rank or match every saved contact without the user choosing them cannot be built on it.
Budget for the review package as well. Google's declaration flow for sensitive permissions asks for reviewer instructions and a video demonstration of the core functionality the permission supports. A screen recording of the friend-matching flow doing something the picker cannot do is worth more than any amount of prose in the justification field.
Migrating to the Contact Picker
The picker is an intent that returns a session URI, and it requires no contacts permission at all. You declare which data fields you need, the user picks contacts, and you query the session URI for read access that does not outlive the session.
val requestedFields = arrayListOf(
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
)
val intent = Intent(ContactsPickerSessionContract.ACTION_PICK_CONTACTS).apply {
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
putExtra(ContactsPickerSessionContract.EXTRA_PICK_CONTACTS_SELECTION_LIMIT, 5)
putStringArrayListExtra(
ContactsPickerSessionContract.EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS,
requestedFields
)
}
launcher.launch(intent)
// In the result callback: one session URI for the whole selection
val sessionUri = result.data?.data ?: return
contentResolver.query(sessionUri, null, null, null, null)?.use { cursor ->
// read only the fields you asked for
}
Three details from the API reference that change behaviour if you miss them. The requested data fields extra is required, and contacts without at least one of those field types are filtered out of the list. The selection limit defaults to 50 and throws an IllegalArgumentException above 100. And the result is a single session URI rather than one URI per contact, so query it once off the main thread instead of looping over individual contacts.
Then clean up the other side: remove the uses-permission line for READ_CONTACTS, delete the runtime request and its rationale dialog, and update the Data safety form so the declaration matches reality. An app that no longer holds the permission should not still be telling users it reads contacts, and mismatched declarations are their own review problem, as covered in what to declare on the Data safety form.
What about devices on Android 16 and older
The picker is not backported, so the old path stays in the code for a while. There is a bridge: on devices running Android 17 or higher, the system automatically upgrades the legacy Intent.ACTION_PICK to the new picker interface for apps that target API 37, so existing code gets the new UI without changes. What it does not get is the new capabilities, meaning multi-select, multiple data fields and the single session URI all still require ACTION_PICK_CONTACTS.
For devices below Android 17, ACTION_PICK with a contact content type remains the only system picker, and it returns one contact per launch. Test that path on a pre-17 device with contacts present, because OEM contacts apps vary in what they return for a pick intent, and the difference shows up as a null URI in production rather than in your emulator.
MANAGE_CONTACTS: the second policy, announced October 29, 2026
Five days before this article, Google announced a companion policy for MANAGE_CONTACTS, the single permission behind both reading and writing contacts. It is narrower in intent and later in timing: apps may request it only where the platform's own ACTION_INSERT and ACTION_EDIT intents cannot do the job, declarations open in summer 2027, and compliance is mandatory in August 2027. Google's policy preview lists August 25, 2027 for the API 38+ form of the rule.
The practical reading for a small app is that adding a contact from a chat thread does not need the permission at all, because the platform intent already prompts the user to create one. Only bulk or programmatic contact management, such as a contact manager or an enterprise sync adapter, has a case to make.
It is a separate policy rather than an extension of the read rule because the risk is different. READ_CONTACTS governs reading the address book; MANAGE_CONTACTS governs writing to it, and writing has a much smaller set of legitimate uses. The declaration you file mirrors the read side: you show why the platform intents for adding and editing one contact are not sufficient for your core functionality. Google's own examples of a justified need are narrow, which tells you how small the approved population is meant to be.
The advice for anyone shipping this year is not to add the permission speculatively. A manage-contacts permission left in the manifest becomes a second declaration, a second review window and a second deadline in 2027, and Google's wording is explicit that apps which can use the narrowly scoped intents must use them.
What to do in your closed test this week
- Read
targetSdkVersionin your build file, not the one in your notes. If it is 37 or higher and the manifest still carriesREAD_CONTACTS, you are in scope now. - Name the feature that needs contacts and decide honestly which branch it is on. Invite, share and pick-a-contact features belong on the picker.
- If the picker covers it, migrate before the build that your testers will opt into. Doing it after 12 testers are installed means shipping a second build mid-run, which is time you do not get back if the review queue is busy.
- If it does not, submit the declaration first and treat the response time as a schedule item. Google's wording is several weeks, so a plan that assumes days is not a plan.
- Change the test script, not just the code. Ask testers to exercise the picking flow specifically, including cancelling the picker and selecting zero contacts, because those two paths are where migrated code usually breaks.
- Check the track's release history before you message testers about a missing update, and read the release notes on the other common approval delays if you are already blocked on something else.
We run closed tests as a service, and the campaigns we handle treat declarations as a scheduling item rather than a compliance checkbox. The reason is mechanical: testers test the build sitting on the track, so a release held after upload does not pause the test politely, it quietly moves the test onto older code while the day count keeps running. That is also why we check App content before a build goes out rather than after testers report a problem.
Two adjacent items on the same App content list are worth checking while you are there: account-level identity verification failures and the 16 KB page size requirement, both of which block or delay publishing in the same queue. The target API requirement that eventually pushes you into scope is covered in the target API 36 rules and dates.
Frequently asked questions
Do I need READ_CONTACTS to let a user pick a contact?
No. The Android Contact Picker returns user-selected contacts to your app through ACTION_PICK_CONTACTS without the permission, and the API reference states the calling app gains one-time read access to that selection. For apps whose only contacts feature is inviting or sharing with a chosen person, this is the intended path.
Does the policy apply if my app targets API 36?
Not yet. The rule explicitly covers apps targeting Android 17 (API level 37) or higher. You move into scope when you raise targetSdk, which the Play target-API requirements will eventually force, so the delay is a scheduling choice rather than a permanent exemption.
Will Google reject my app, or just hold it?
It holds it first. An undeclared sensitive permission on an active bundle blocks publishing changes, and a submitted declaration puts the release into pending publication while it is reviewed, which Google says can take several weeks. A rejection can follow if the declaration or the app's behaviour does not support the use case you claimed.
Does a contacts declaration reset my 14-day clock?
No. The clock runs on testers who are opted in continuously, and a held release does not opt anyone out. The damage is different: testers who already opted in keep an older build, and testers you are still recruiting cannot install anything new. New testers have to start their own 14 days from the moment they opt in to a live build.
My app has a custom contact picker screen. Does that count as a reason to keep the permission?
No. Google's FAQ answers this directly: a custom contact picking experience "does not qualify as a reason to retain Contacts access". The comparison Google makes is between the system picker and your genuine core functionality, not between the system picker and the UI you built.
Can testers on older Android versions use the Contact Picker during my closed test?
Not on devices below Android 17, because the picker is not backported. If your 12 testers include devices on Android 11 to 16, which is normal for a mixed panel, they will hit the legacy path, so put both flows in the test script and record which one each tester used.
What if I just remove contacts access entirely?
Then the policy does not apply to you, and that is often the right answer. Removing the permission also removes the declaration, the extended review and the pending publication window. The cost is a feature change, so decide before the build that testers opt into rather than after.
Sources
- Google Play Console Help: Understanding restricted permissions with minimum scope alternatives - the contacts timeline (April 15 2026 announcement, September 2026 prompts, January 27 2027 enforcement), the declaration questions, the use cases Google lists, and the answers Google says do not qualify.
- Google Play Console Help: Preview of Permissions and APIs that Access Sensitive Information - the dated effective-date table for the contacts, MANAGE_CONTACTS, local network and AppFunctions policies.
- Google Play Console Help: Declare permissions for your app - the statement that an undeclared permission blocks all publishing changes on open, closed and internal tracks, the several-week review, pending publication status, and the reviewer instructions and video demonstration the form asks for.
- Google Play Console Help: Detect app issues early with pre-review checks - checks verify that updates contain all mandatory App content declarations, and missing declarations are listed among the issues that cannot be deferred.
- Google Play Console Help: App testing requirements for new personal developer accounts - 12 testers opted in continuously for the preceding 14 days, measured when you apply for production access.
- Google Play Console Help: Target API level requirements for Google Play apps - API 36 mandatory for new apps and updates from August 31 2026, with an extension available to November 1 2026.
- Android Developers: Contact picker - the intent action, requested data fields, MIME types, and the automatic upgrade of legacy ACTION_PICK for apps targeting API 37.
- Android API reference: ContactsPickerSessionContract - permission-free access to user-selected contacts, the default selection limit of 50 and maximum of 100, and the single session URI returned to the caller.
- Android Developers Blog: Boosting user privacy and business protection with updated Play policies - Google's own framing of the Contact Picker as the new standard for accessing contacts, and the pre-review checks introduced for contacts and location permissions.
Need testers who stay opted in for the full 14 days?
OnTesters provides 12 real testers on physical Android devices, with replacements for dropouts and free retesting if Google asks for more testing. From $14.99.
We do not sell or guarantee production access
Afrin Asha
Founder, OnTesters
Android developer and QA specialist. Built OnTesters after working through Google Play’s 12-tester closed testing requirement on real devices. Read the full story