Environment.getExternalStorageDirectory() deprecated in API level 29 java
android, android-api-levels, deprecated
Solution
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).
Problem
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?