What the rejection typically looks like
Issue found: Permission use is not directly related to your app's core purpose
We found that your app is not compliant with how the READ_MEDIA_IMAGES/READ_MEDIA_VIDEO permissions are allowed to be used. Only apps whose core functionality requires broad access to photo and video files may request these permissions. Apps with a one-time or infrequent need should use a system picker such as the Android photo picker.
Action required: Remove the permissions or submit a declaration in Play Console. Upload a compliant version across all tracks and deactivate any non-compliant app bundles.
Paraphrased example – the exact wording in your message may differ.
What the sensitive permissions policy actually says
Google's Permissions and APIs that Access Sensitive Information policy has one core rule. You may only request sensitive permissions that current features promoted in your store listing need. You may never use them for undisclosed, unimplemented or disallowed purposes, and you may never sell the data.
On top of that, restricted permissions have their own rules, including SMS and Call Log, photo and video, All files access, package visibility, exact alarms, full-screen intents, request install packages, the Accessibility API, VPN, body sensors and Health Connect, and location. Most need a declaration in Play Console, and for permissions such as SMS, Call Log, All files access or QUERY_ALL_PACKAGES the release stays pending until Google approves it. Apps targeting Android 14 (API level 34) or higher must also declare each foreground service type they use.
Google reviews the merged manifest of every bundle you upload, not your source manifest. If a permission is listed there, it counts as requested, even if your code never calls the API behind it.
A rejected update leaves your previously published version live. But until you replace the non-compliant bundles, new releases will keep failing review, and if the live version breaks the policy too, Google can remove the app. Repeated violations can lead to account-level enforcement.
More changes are coming. As of October 2026, Google's policy deadlines page lists these for January 27, 2027: a new Contacts Permissions policy for apps targeting Android 17 (use the Android Contact Picker unless you need broad access), the location button as the recommended minimum scope for precise location, an end to account verification via phone call as a valid READ_CALL_LOG use, and geofencing no longer being an approved foreground service use case.
Common reasons apps get rejected under this policy
- An SDK or plugin added the permission. Ad, attribution, support chat, file picker and "device info" libraries often merge
QUERY_ALL_PACKAGES,READ_MEDIA_IMAGESor exact alarm permissions into your manifest. You won't see them in your own manifest file. - Broad photo access for a one-time action, such as a profile picture, a receipt or a post image. That is picker territory.
- QUERY_ALL_PACKAGES to detect a few known apps, such as WhatsApp or a payment app. A
<queries>declaration covers that. - SMS permissions for one-time password auto-fill. Google lists account or device authentication through broad SMS or Call Log access as an invalid use.
- All files access to save or open a document. The Storage Access Framework and MediaStore handle that.
- USE_EXACT_ALARM in a to-do, habit or reminder app that isn't an alarm, timer or calendar app.
- Foreground service declarations that are missing, vague or have no video.
- Accessibility automation without a prominent disclosure, or
isAccessibilityTool="true"in an app not built for people with disabilities. - A declaration the reviewer can't verify: no test credentials, a video that doesn't show the feature, or a listing that never mentions it.
- Forgotten tracks: production is fixed, but a testing track still serves a bundle with the permission.
Rejected or stuck? Talk to an App Specialist – for free.
Book a free consultation call: we look at your rejection or setup, explain the fastest way forward and tell you honestly whether you need us. Prefer to hand it off? Book our AI-powered + human-powered service and we take care of it.
Permission by permission: what is allowed and what to use instead
| Permission | Allowed for (summary) | Minimum-scope alternative |
|---|---|---|
SMS and Call Log (READ_SMS, RECEIVE_SMS, READ_CALL_LOG and others) | The default SMS, Phone or Assistant handler. Narrow exceptions include backup and restore, caller ID and spam blocking, cross-device sync, SMS-based financial transactions, device automation and companion apps. | SMS Retriever or SMS User Consent API for one-time passwords; ACTION_SENDTO/ACTION_DIAL intents |
QUERY_ALL_PACKAGES (apps targeting API level 30+) | Apps that must discover any and all installed apps for awareness or interoperability: device search, antivirus, file managers, browsers. Temporary exceptions are possible for apps that facilitate financial transactions, such as banking and digital wallets (security purposes only), and real-money gambling apps that need it for geofencing compliance. | <queries> with <package>, <intent> or <provider> |
READ_MEDIA_IMAGES, READ_MEDIA_VIDEO | Apps whose core function needs persistent, broad access, such as gallery apps that manage all of a user's photos | Android photo picker (no permission needed) |
MANAGE_EXTERNAL_STORAGE | File managers, backup and restore, antivirus, document management, on-device file search, file encryption, device migration | Storage Access Framework, MediaStore, app-specific storage |
USE_EXACT_ALARM | Alarm or timer apps and calendar apps that show event notifications, with a Play Console declaration | SCHEDULE_EXACT_ALARM (granted by the user, and denied by default for most new installs on Android 14+), inexact alarms, WorkManager |
| Accessibility API | Tools designed for people with disabilities (isAccessibilityTool="true"); other apps only with prominent disclosure and consent | A purpose-built API, such as the Autofill framework for password managers |
Photo and video: the rule most apps trip over
Apps targeting Android 13+ may only request READ_MEDIA_IMAGES/READ_MEDIA_VIDEO if system pickers aren't sufficient for core functionality. Google made full compliance mandatory on May 28, 2025, including for apps that had an extension. The Android photo picker is built in on Android 11+ devices that get Google System Updates. Google Play services provides a backport for Android 4.4–10, which you trigger with the ModuleDependencies service entry shown in the photo picker docs. With androidx.activity 1.7.0+, use the PickVisualMedia or PickMultipleVisualMedia contract.
Android 14's READ_MEDIA_VISUAL_USER_SELECTED doesn't get you around the policy, because its documented setup still declares READ_MEDIA_IMAGES and READ_MEDIA_VIDEO. If a legacy flow needs READ_EXTERNAL_STORAGE, cap it with android:maxSdkVersion="32".
Foreground service types (Android 14+)
When you target Android 14, every foreground <service> needs an android:foregroundServiceType (for example mediaPlayback, location or dataSync). Every type except shortService also needs its matching FOREGROUND_SERVICE_<TYPE> permission. The specialUse type also needs an android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE property that explains the use case. In Play Console, you describe each type, explain the user impact if the system defers or interrupts the task, and add a video link. Short or deferrable work belongs in WorkManager.
Accessibility API
Apps that aren't accessibility tools need a prominent in-app disclosure (a privacy policy isn't enough), affirmative consent and a Play Console declaration. The video has to show the disclosure, both accepting and declining consent, and the feature that uses the API. Google prohibits changing settings without permission, remote call audio recording and any use that lets an app "autonomously initiate, plan, and execute actions or decisions". That last rule matters for AI agent apps.
Background location has its own requirements. See our background location guide.
Removing permissions merged in by SDKs and plugins
First find out where the permission comes from. In Android Studio, open AndroidManifest.xml and switch to the Merged Manifest tab, which shows which library added each element. To inspect the exact artifact you upload, run bundletool dump manifest --bundle=app-release.aab.
Then remove the permission in your app module's manifest, which overrides library manifests:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:node="remove" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" tools:node="remove" />
</manifest>
Removing a permission doesn't remove the code that uses it. Test the SDK feature afterwards, because it may now get empty results or a SecurityException.
- Flutter: add the removals to
android/app/src/main/AndroidManifest.xml. - React Native: in bare projects, use the same file. In Expo, list them under
android.blockedPermissionsinapp.jsonand rebuild. - Capacitor:
android/app/src/main/AndroidManifest.xml. .NET MAUI:Platforms/Android/AndroidManifest.xml. Unity: enable Custom Main Manifest under Player Settings > Publishing Settings and add the removals there.
How to fix a sensitive permissions rejection step by step
- Read the issue details. In Play Console, open Policy status and the rejection email. Note the permission, the version codes and the tracks.
- Decide for each permission: remove or justify. Is it the core feature, promoted in the listing, and does it need persistent access? If not, remove it.
- Build the alternative: photo picker,
<queries>, Storage Access Framework, SMS Retriever or WorkManager. Make sure the app still works when a permission is denied, or you'll get a broken functionality rejection next. - Strip SDK-merged permissions and confirm with
bundletool dump manifestthat the release bundle no longer contains them. - Declare what you keep on the App content page in Play Console, with instructions, a video and test credentials. Play Console also asks for the declaration when you add a bundle with a restricted permission to a release. The menu labels around App content have changed over time, so use the search bar if you can't find it.
- Align your listing and Data safety form. The store description should name the feature, and your Data safety answers must cover the data the permission accesses.
- Replace every non-compliant bundle. Increase
versionCodeand create a release on every track that still serves the old bundle: production, open, closed and internal testing. Check paused tracks too. Don't retain the old bundles in the new releases. - Send the changes for review from Publishing overview, then check Policy status again.
Just raised targetSdkVersion for the target API level requirement? That's often when foreground service types and photo rules first apply.
Writing a declaration and video that reviewers can approve
Reviewers compare your declaration with your listing, your video and the app itself. To get a legitimate use approved:
- Name the core feature in user terms, using the same wording as your listing. "Gallery that organizes and backs up all photos on the device" beats "we need storage access".
- Explain technically why the alternative fails. For example: "The photo picker only returns selected items, so we can't scan the library to detect duplicates."
- Give reproducible steps and test credentials if anything is behind a login.
- Record a short video on a real device: launch the app, show the disclosure and permission prompt, then the feature using the data. Share a YouTube link or an MP4 link that opens without signing in.
- Keep it plain and submit early. Google's help center says declaration requests can take up to several weeks to process, and the release stays pending until then.
Resubmit or appeal?
In most cases, fix and resubmit. If you removed the permission, the new bundle and the deactivated old ones are your answer, and no message is needed.
Appeal only if you're confident your use is permitted, for example a default SMS app or a file manager rejected for All files access. Use Appeal on the Policy status page or the link in the email. Google accepts one appeal per enforcement action, so include your core purpose, why the alternative isn't enough, steps, video and test access. Don't resubmit an unchanged bundle hoping for a different reviewer. Repeated policy violations can lead to account-level enforcement.
How to prevent sensitive permission rejections
- Keep a permission allowlist in your repository. In CI, run
bundletool dump manifest --bundle=app-release.aab --xpath /manifest/uses-permission/@android:nameand fail the build when a new restricted permission appears. - Review the merged manifest after every dependency update, for example as part of your Renovate or Dependabot pull request checks.
- Map each restricted permission to a feature, a listing sentence, a Data safety answer and a declaration. If one link is missing, you have a rejection risk.
- Test denial paths: tap "Don't allow" on Android 13 and newer, and "Select photos and videos" (partial access) on Android 14 and newer.
- Use AI-assisted checks as a first pass to flag restricted permissions in manifests and SDK changelogs and draft declarations. A human should still verify them against the current policy.
Want a second pair of eyes on your manifest, declarations and release tracks before you submit? The appsubmitter.io Android submission service combines AI-assisted checks with human review. Start with a free consultation call.
Template: how to reply to the Google Play review team
Adapt this template to your situation. Keep it factual, short and specific – and only claim what you have actually changed.
Checklist before you resubmit
- The merged manifest of the new release bundle contains only the permissions you intend to request.
- Unneeded SDK permissions are removed with tools:node="remove" (or Expo blockedPermissions), and the affected SDK features still work.
- One-time photo or video selection uses the Android photo picker, without READ_MEDIA_IMAGES or READ_MEDIA_VIDEO.
- Checks for specific installed apps use queries elements instead of QUERY_ALL_PACKAGES.
- One-time password auto-fill uses the SMS Retriever or SMS User Consent API.
- Each foreground service declares the correct type and permission and is described in Play Console with a video.
- USE_EXACT_ALARM is only declared if the app is an alarm, timer or calendar app. Otherwise the app uses SCHEDULE_EXACT_ALARM, inexact alarms or WorkManager.
- Every restricted permission you keep has a declaration with steps, a working video link and valid test credentials.
- The store listing and Data safety answers match each restricted permission.
- The new version code is rolled out to every affected track, and the old bundles are deactivated.
Frequently asked questions
Why was my app rejected for a permission I never added?
tools:node="remove" and confirm it is gone with bundletool dump manifest.Do I need READ_MEDIA_IMAGES to let users upload a profile picture?
PickVisualMedia contract from androidx.activity 1.7.0+. On Android 4.4–10, Google Play services provides a backported version.How do I check if a specific app is installed without QUERY_ALL_PACKAGES?
queries element in your manifest, by package name or by an intent filter. If your app targets Android 11 (API level 30) or higher, calls like getPackageInfo() then return results for the declared apps. That covers almost every "is app X installed" case.I removed the permission. Why is my app still rejected?
Can I use SMS permissions to read one-time passwords?
Does the new contacts permission policy affect my app?
READ_CONTACTS, very likely. Play Console has been prompting for a declaration since September 2026, and compliance is mandatory from January 27, 2027 for apps that target Android 17 (API level 37) or higher. You may only keep READ_CONTACTS if the Android Contact Picker isn't enough for your core functionality. Check the Contacts Permissions policy page for the current timeline.How long does a Google Play permissions declaration review take?
Do I need to declare foreground service types in Play Console?
android:foregroundServiceType values in your merged manifest.Official source: Google Play Policy Center – Permissions and APIs that Access Sensitive Information. Store policies change regularly – always check the current version. This guide is independent advice and not affiliated with Apple or Google.