Working on android Java, recently updated SDK to API level 29 now there is a warning shown which states that
Environment.getExternalStorageDirectory()
is deprecated in API level 29
My code is
private void saveImage() {
if (requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
final String folderPath = Environment.getExternalStorageDirectory() + "/PhotoEditors";
File folder = new File(folderPath);
if (!folder.exists()) {
File wallpaperDirectory = new File(folderPath);
wallpaperDirectory.mkdirs();
}
showLoading("Saving...");
final String filepath=folderPath
+ File.separator + ""
+ System.currentTimeMillis() + ".png";
File file = new File(filepath);
try {
file.createNewFile();
SaveSettings saveSettings = new SaveSettings.Builder()
.setClearViewsEnabled(true)
.setTransparencyEnabled(true)
.build();
if(isStoragePermissionGranted() ) {
mPhotoEditor.saveAsFile(file.getAbsolutePath(), saveSettings, new PhotoEditor.OnSaveListener() {
@Override
public void onSuccess(@NonNull String imagePath) {
hideLoading();
showSnackbar("Image Saved Successfully");
mPhotoEditorView.getSource().setImageURI(Uri.fromFile(new File(imagePath)));
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,Uri.fromFile(new File(filepath))));
Intent intent = new Intent(EditImageActivity.this, StartActivity.class);
startActivity(intent);
finish();
}
@Override
public void onFailure(@NonNull Exception exception) {
hideLoading();
showSnackbar("Failed to save Image");
}
});
}
What will be the alternative for this?
Use getExternalFilesDir()
, getExternalCacheDir()
, or getExternalMediaDirs()
(methods on Context
) instead of Environment.getExternalStorageDirectory()
.
Or, modify mPhotoEditor
to be able to work with a Uri
, then:
Use ACTION_CREATE_DOCUMENT
to get a Uri
to a location of the user's choosing, or
Use MediaStore
, ContentResolver
, and insert()
to get a Uri
for a particular type of media (e.g., an image) — see this sample app that demonstrates doing this for downloading MP4 videos from a Web site
Also, note that your Uri.fromFile
with ACTION_MEDIA_SCANNER_SCAN_FILE
should be crashing on Android 7.0+ with a FileUriExposedException
. On Android Q, only the MediaStore
/insert()
option will get your content indexed by the MediaStore
quickly.
Note that you can opt out of these "scoped storage" changes on Android 10 and 11, if your targetSdkVersion
is below 30, using android:requestLegacyExternalStorage="true"
in the <application>
element of the manifest. This is not a long-term solution, as your targetSdkVersion
will need to be 30 or higher sometime in 2021 if you are distributing your app through the Play Store (and perhaps elsewhere).