WRITE_EXTERNAL_STORAGE is deprecated (and is not granted)

How can I fix this?

WRITE_EXTERNAL_STORAGE is deprecated (and is not granted) when targeting Android 13+. If you need to write to shared storage, use the MediaStore.creat

Asked on November 21, 2023 in uncategorized.
Add Comment
1 Answer(s)
WRITE_EXTERNAL_STORAGE permission has indeed been deprecated starting from Android 11 (API level 30), and the situation is even more restrictive with Android 13 (API level 33), where it's no longer available. If you need to save files that should be accessible by other apps or after your app is uninstalled, you must use the MediaStore API or the Storage Access Framework (SAF). Here's how you can use the MediaStore to save images, for example: 1. **Request permission to write** - On Android 10 (API level 29) and lower, you still need to request `WRITE_EXTERNAL_STORAGE` permission for access to shared storage. However, starting from Android 11 (API level 30), you should use `MANAGE_EXTERNAL_STORAGE` permission to request broader access to external storage if your use case necessitates it. Be cautious with this permission as it gives you access to the entire external storage and can only be used if your app requires such access and cannot function properly without it. Google Play restricts the apps that can request this permission, so you should check if your use case is compliant with their policy. 2. **Use MediaStore API** - for images, videos, and audio files across all Android versions. Here's an example of how to insert an image into the `MediaStore.Images` collection: ```java ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DISPLAY_NAME, "myImage.jpg"); // The name of the file values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); // The MIME type of the file values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/MyApp"); // The relative path // For API level 29 and above if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { values.put(MediaStore.Images.Media.IS_PENDING, 1); } Uri collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); Uri fileUri = context.getContentResolver().insert(collection, values); try (OutputStream stream = context.getContentResolver().openOutputStream(fileUri)) { // Write data into the pending image file } catch (IOException e) { context.getContentResolver().delete(fileUri, null, null); } // After writing, if you're using API level 29 and above: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { values.clear(); values.put(MediaStore.Images.Media.IS_PENDING, 0); context.getContentResolver().update(fileUri, values, null, null); } ``` 3. **Use the Storage Access Framework (SAF)** - when you want to allow the user to select files or directories through a system file picker. This doesn't require any permissions to be declared in your app's manifest. Keep these in mind when altering your app's storage behavior to support Android 13+: - **Understand Scoped Storage**: With Android 10 and upward, Scoped Storage is the norm. This means your app gets a 'private' directory where you can read/write without any permissions. No external app can access data located in another app's scoped area. - **Legacy Flag**: For apps that target Android 9 (API level 28) or lower, adding `android:requestLegacyExternalStorage="true"` to the manifest's `` tag allows the app to temporarily opt-out of scoped storage and use the old storage model. However, this is not a long-term solution, as this flag is ignored starting from Android 11. - **Testing**: Make sure you test your changes on different Android versions especially if your app supports a wide range of devices. This will help ensure compatibility and a smooth user experience. Remember, accessing shared or external storage is a sensitive topic due to privacy concerns, and many changes have been introduced in recent Android versions to ensure user data security. Always consult the official Android documentation when implementing these features.
Answered on November 21, 2023.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.