READ_MEDIA_IMAGES rejected: Google Play's Photo and Video Permissions policy and the declaration form
Google has decided your app does not need permanent access to every photo on the device. READ_MEDIA_IMAGES and READ_MEDIA_VIDEO are access to personal and sensitive data, and Play expects most apps to use the Android photo picker instead. If you keep the permissions, you must declare why the picker is not enough.
How it is worded
Usually a policy email or a warning on the Policy status page rather than a plain rejection, and it names the permission:
"Your app requests the READ_MEDIA_IMAGES permission but does not appear to have a core use case requiring persistent or frequent access to photos and videos."
Check whether you have a warning with a deadline or an outright rejection of the release. They behave differently, and the Policy status page in Play Console is where that is stated.
What it means
The policy is unusually clear. Its summary:
"To protect user privacy and security, Google Play requires apps that request READ_MEDIA_IMAGES or READ_MEDIA_VIDEO permissions to show strong, legitimate core use cases for persistent or frequent access to photos and videos. If your app does not qualify for this access, you should remove the permissions. Instead, use a system picker like the more privacy-preserving Android Photo Picker for one-time or infrequent needs."
And the rule:
"Apps that target Android 13 or later (API level 33+) may only request the READ_MEDIA_IMAGES and READ_MEDIA_VIDEO permissions if system pickers (like the Android Photo Picker) are not sufficient for your app to provide core functionality. Apps that still request the READ_MEDIA_IMAGES and READ_MEDIA_VIDEO permissions must submit a Play Console declaration to demonstrate access needs for Photos and why Android Photo Picker (or alternatives) would not suffice."
Photos also sit inside the user data policy: "All user photos are personal and sensitive data subject to the user data policy."
So there are three positions, and only three:
- You use the photo picker and hold neither permission. Nothing to declare.
- You hold the permissions and your core functionality genuinely requires persistent or frequent library access. You must declare it and be able to defend it.
- You hold the permissions and cannot justify them. This is the rejection.
What decides the bucket is one-time or infrequent access versus persistent or frequent access. Picking an avatar, attaching an image to a message, choosing a photo to edit: one-time. A gallery app indexing the whole library, a backup client syncing it, a manager finding duplicates: plausibly persistent.
Why it happens
- You need one image and asked for the library. By far the most common case. An avatar picker, a document upload, an "add a photo to this entry" flow.
- You still use
READ_EXTERNAL_STORAGEwith amaxSdkVersionand the media permissions above it, as a Stack Overflow answer from 2023 said to. The storage permission is not the problem; the media ones are. - A dependency declares them. Image pickers, cropping libraries, camera wrappers and chat SDKs all add permissions through manifest merging. You did not write it and it is still yours.
- You declared them "just in case" during a migration to targetSdk 33 and never removed them.
- The declaration was never completed, or was completed with a generic answer. "Users need to select photos" describes a picker use case and will be read as one.
- You use
MediaStorequeries to build your own picker UI. A gallery grid of your own is not a core use case for full access if the platform picker serves the same need.
How to fix it
- Find out what actually declares the permission. Build the release variant and read the merged manifest at
app/build/outputs/logs/manifest-merger-release-report.txt, or open the APK in Android Studio's APK Analyzer. This tells you whether the permission is yours or a library's. - Decide honestly which bucket you are in. Write one sentence describing the user need. If it contains "select", "choose", "attach" or "upload", you are a picker case.
- If you are a picker case, migrate. Use
PickVisualMediaorPickMultipleVisualMediafrom AndroidX Activity 1.7.0 or later. It falls back toACTION_OPEN_DOCUMENTon devices without picker support, back to API 19, so you need no second code path. - Then delete both permissions from your manifest, and add
tools:node="remove"entries for any that a dependency reintroduces:<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" tools:node="remove" /> - Handle persistence if you keep a URI. The picker grants temporary access; call
takePersistableUriPermissionwithFLAG_GRANT_READ_URI_PERMISSIONif the reference must survive a restart. Copying the bytes into your own storage is usually simpler. - Remove the runtime permission prompt and its rationale UI. A dialog explaining why you need photo access, in an app that no longer needs it, will confuse the reviewer.
- If you are a genuine persistent-access case, complete the declaration. It asks what the access is for and why the picker will not serve it. Answer with the specific feature: "the app scans the full library on a schedule to detect duplicates, which requires enumerating items the user has not individually selected" is defensible. Then make sure that feature is visible in your store listing, because the policy also requires permissions to map to features "promoted in your Google Play listing".
- Update the Data safety form, then rebuild and check the merged manifest again before uploading. A mismatch between manifest and Data safety is its own violation, and manifest merging surprises are why this gets rejected twice.
Appeal, or change the app?
For a picker case, do not appeal. Migrate. The photo picker is a smaller change than most developers expect, often under a day, and it removes the permission prompt entirely, which usually improves completion of the flow it sits in.
Appeal when the declaration was rejected but the use case is real. Give the reviewer the mechanism, not the benefit. Say what your code does that the picker cannot express: enumerate items the user has not selected, watch for new items, read metadata across the library, operate without a foreground interaction. Point at the screen where the feature lives, and at the line in your listing that promotes it.
Do not appeal because the picker's design does not fit your interface. A preference for your own gallery grid is a design choice, and the policy is explicit that system pickers are the expected path where they can do the job.
One caveat: pages here have been revised repeatedly since Android 13 shipped, and the article that once held this text has moved. Read the live Photo and Video Permissions section on Google's Permissions and APIs that Access Sensitive Information page before relying on any deadline you saw elsewhere.
AppSubmit reads the merged manifest from the build you are about to upload and lists the permissions Play treats as restricted, with any declaration outstanding. Removing the permission is still a code change in your project.