Google Play Rejected Your Flutter App for Photo Permissions? Fix READ_MEDIA_IMAGES in 4 Steps (2026)
Why did Google Play reject my Flutter app for photo and video permissions?
Because the release you uploaded, or an older one still active on a testing track, requests READ_MEDIA_IMAGES or READ_MEDIA_VIDEO, and Google Play only allows those permissions for apps whose core purpose needs broad, ongoing access to the photo library. An app that lets users pick a profile picture or attach a receipt is expected to use the system photo picker instead. In Flutter apps the permission often comes from a plugin rather than your own code. The fix is to find who adds it, remove it from the merged manifest, check the built app, and replace every active version code on every track before resubmitting.
What the policy actually says
Google’s Photo and Video Permissions policy has two parts. Apps that need broad access must pass a review and show a core use case with persistent or frequent access to photos or videos. Apps with “one-time or infrequent” use, which Google illustrates with uploading a profile picture or a photo of a cheque, should use a system picker such as the Android photo picker. The timeline on the policy page:
| Date | What changed |
|---|---|
| August 31, 2024 | Apps with one-time or infrequent use asked to remove the permissions and move to a picker |
| January 2025 | End of the optional extension for apps that needed more time |
| May 28, 2025 | Full compliance mandatory for all developers, including those with an extension |
The same Play Console help page now also covers a Contacts Permission policy: from September 2026 apps with READ_CONTACTS are prompted to declare core use or switch to a contact picker, and compliance becomes mandatory on January 27, 2027 for apps targeting Android 17 (API level 37) or later. If you are already fixing media permissions, check contacts in the same pass.
Step 1: find who adds the permission
Your own AndroidManifest.xml is only one input. Gradle merges it with the manifest of every plugin, so a permission you never typed can still ship. Three ways to see the final list:
- Android Studio’s Merged Manifest tab. Open
android/app/src/main/AndroidManifest.xmlin Android Studio and click Merged Manifest at the bottom of the editor. Selecting a permission shows which library manifest it came from. - apkanalyzer on a release build. Build an APK with
flutter build apk --releaseand runapkanalyzer manifest permissions build/app/outputs/flutter-apk/app-release.apkto print the permissions that actually ship. - Your plugin list. File pickers, file openers, gallery savers and camera plugins are the usual sources. A Stack Overflow answer about open_filex shows exactly this pattern: the app never used the permission, a dependency declared it.
Step 2: switch one-time picks to the photo picker
If your app picks an image now and then, you do not need a media permission at all. The image_picker package’s documentation says that on Android 13 and above it uses the Android Photo Picker, and a Flutter triager pointed out in issue 171494 that the package needs no extra permission declarations for it. Google’s Android Developers Blog adds that the photo picker has been backported to older devices, down to Android 4.4, through Google Play services. For most indie apps, a plain call is enough:
final picked = await ImagePicker().pickImage(source: ImageSource.gallery);
Test the picker on an Android 13 or newer device after removing the permission, and on one older device if you support it.
Step 3: remove the permission from the merged manifest
When a plugin declares the permission and you do not need it, override it in your app’s manifest. Android’s manifest-merge documentation describes tools:node="remove" as the way to drop an element contributed by a lower-priority manifest that is out of your control:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" tools:node="remove" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" tools:node="remove" />
</manifest>
Only remove what your app does not use. If a plugin genuinely needs broad access for a feature, either replace that feature with a picker or decide whether your app’s core purpose qualifies for the declaration.
Step 4: verify, rebuild and replace every track
The rejection notice quoted in Flutter issue 173536 asks developers to remove the permissions “from all version codes within the submission. This includes both production and testing tracks.” That line catches many indie developers: the new build is clean, but an old internal or closed testing build still requests the permission.
- Run apkanalyzer again and confirm neither permission appears.
- Bump the version code and build a new app bundle.
- Upload it to every track that still has an older active release with the permission, including internal and closed testing.
- Send the changes for review from Publishing overview.
If you are in the middle of a phased release, the replacement build follows the same rules as any update; our guide to staged rollout rules for indie Flutter apps covers halting and replacing a rollout. A new closed test may also be needed if your account is still under the tester requirement described in our 12 testers for 14 days closed-testing guide.
A worked example
Illustrative case. An indie habit-tracker app lets users set a profile photo and attach an image to a journal entry. Play rejects version 23. The Merged Manifest tab shows READ_MEDIA_IMAGES and READ_MEDIA_VIDEO coming from a file-opening plugin used to preview exported PDFs, not from the image code. The developer keeps image_picker for both photo features, adds two tools:node="remove" lines, confirms with apkanalyzer that the release APK no longer lists either permission, ships version 24 to production and to the closed testing track that still held version 21, and resubmits. The update is approved on the next review.
Make it part of your release routine
Permissions drift every time you add or update a plugin. Add one line to your release checklist: print the release build’s permissions with apkanalyzer and compare them with the last approved build. The same check keeps your Data safety form honest, as our guide to refreshing the Play Console Data safety form after SDK changes explains, and pairs well with the yearly target API level deadline. More of these release notes from a one-person studio are on GSPTeck’s apps and projects page.
FAQ
Does image_picker need READ_MEDIA_IMAGES on Android 13?
No. On Android 13 and above image_picker uses the Android Photo Picker, which needs no media permission. If your merged manifest still lists the permission, another plugin or an old manifest entry is adding it.
Why was my app rejected when my code never asks for photo permissions?
Google Play checks the merged manifest, which includes every plugin’s declarations, and every active version code on every track. A dependency or an older testing build can carry the permission even if your current code never requests it.
Can I keep READ_MEDIA_IMAGES if my app is a gallery or photo editor?
Possibly. Apps whose core purpose needs persistent or frequent access to photos can complete the declaration in Play Console and pass a review. One-time uses such as profile pictures do not qualify.
Do I need to remove the permission from old testing builds?
Yes. The rejection notice asks for the permission to be removed from all version codes in the submission, including testing tracks, so upload a clean build to every track that still holds an affected release.
Sources
- Play Console Help: details on Google Play’s Photo and Video Permissions policy (checked 2026-10-21)
- Android Developers Blog: photo picker everywhere, backported to Android 4.4 (checked 2026-10-21)
- Android Developers: merge manifest files and tools:node="remove" (checked 2026-10-21)
- Android Developers: apkanalyzer (checked 2026-10-21)
- pub.dev: image_picker and the Android Photo Picker (checked 2026-10-21)
- flutter/flutter issue 171494: READ_MEDIA_IMAGES and image_picker (checked 2026-10-21)
- flutter/flutter issue 173536: Photo and Video Permissions rejection notice (checked 2026-10-21)
- Stack Overflow: open_filex adding READ_MEDIA permissions (checked 2026-10-21)