Answer
The core mechanism of temporary URI permissions (FLAG_GRANT_URI_PERMISSION and takePersistableUriPermission()) does not change between API level 32 (Android 12L) and API level 33 (Android 13). What does change is the prerequisite permission set required to actually read the media referenced by that URI.
Confirmed facts
- On Android 13, apps that target
targetSdkVersion >= 33 no longer receive broad READ_EXTERNAL_STORAGE access. Instead they must declare one or more of the granular media permissions: READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, or READ_MEDIA_AUDIO.
- When a user selects a file via the system picker (
ACTION_OPEN_DOCUMENT, ACTION_GET_CONTENT, or the photo picker), the system grants a temporary URI permission to the app regardless of the app’s target SDK, as long as the URI is returned through those APIs.
- If the app does not call
contentResolver.takePersistableUriPermission(uri, mode), the permission is lost when the process is killed or the device is rebooted.
- The temporary URI permission itself is not affected by the new granular media permissions; however, attempting to open the URI for reading will fail with a
SecurityException if the app lacks the required media permission for that file type.
Likely explanation
Access failures after moving to API 33 usually stem from missing the new READ_MEDIA_* permission, not from a change in how the URI grant works. The system still grants the URI, but the subsequent read operation is blocked unless the appropriate media permission is held at runtime.
Steps needed for this case
- Declare the needed granular media permission(s) in the manifest, e.g.:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
- Request the permission at runtime on devices running Android 13 (API 33) before attempting to read the URI.
- After obtaining the URI from the picker, immediately call:
final int mode = Intent.FLAG_GRANT_READ_URI_PERMISSION;
getContentResolver().takePersistableUriPermission(uri, mode);
Use ContentResolver.openInputStream(uri) (or similar) to read the file; this will succeed only if the media permission is granted.
One missing diagnostic detail
If you are already calling takePersistableUriPermission() but still losing access after a process restart, confirm whether you are persisting the URI permission across reboots (the flag above does that) or if you are relying solely on the transient grant. Let me know if you need guidance on checking the persisted permission state.