Environment.Getexternalstoragedirectory() Deprecated in API Level 29 Java

Environment.getExternalStorageDirectory() deprecated in API level 29 java

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).

How to read or write file as getExternalStorageDirectory is deprecated in API 29?

From the docs you can see:

getExternalStoragePublicDirectory(String type)

This method was deprecated in API level 29. To improve user privacy, direct access to shared/external storage devices is deprecated. When
an app targets Build.VERSION_CODES.Q, the path returned from this
method is no longer directly accessible to apps. Apps can continue to
access content stored on shared/external storage by migrating to
alternatives such as Context#getExternalFilesDir(String),
MediaStore, or Intent#ACTION_OPEN_DOCUMENT.

Pass nothing as parameter to this function to get your directory as a File object :

context.getExternalFilesDir();

Here "Context" is an object which is obtained by this.getContext();

this is the current object of the Activity. Do check the scope carefully while using it.

Important

To access the Internal storage, Manifest.permission.WRITE_EXTERNAL_STORAGE and/or Manifest.permission.READ_EXTERNAL_STORAGE are required in the file AndroidManifest.xml.

Optional information:

  1. Usually the internal storage has the path
    /sdcard/ on Android devices. It's not a real path but a symlink.

  2. It's confusing but "external sdcard" in Android acutally means the Internal device storage and not the external ejectable out-of-the-device memory card storage.
    Also note that the real external sdcard cannot be fully access

  3. Activity class extends the Context class That's why we can get the context from it.

Method getExternalStorageDirectory() deprecated

Android Studio version is irrelevant. Depreciation is at the SDK level. Docs say:

This method was deprecated in API level 29. To improve user privacy, direct access to shared/external storage devices is deprecated. When an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible to apps. Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.

If you are not targeting Q you can ignore this for a while as depreciation means you should stop using the method, not that it stopped working as of sudden.

and I didn´t indicated my API level)

That's not true.

Environment.getExternalStorageDirectory() deprecated in API level 29 java

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).

Environment.getExternalStorageDirectory() deprecated. So how to access custom folders in internal storage in android API 29?

As of API 29 Environment.getExternalStorageDirectory() is deprecated.

More importantly, it does not work. You cannot write to arbitrary locations on external storage on Android 10 and higher using filesystem APIs.

What I want is to save all files related to my app in this custom folder

That will not be possible, sorry.

What you can do is use the Storage Access Framework's ACTION_OPEN_DOCUMENT_TREE to allow the user to choose where on the user's device you should be storing the user's content.

Is it advisable to use this way :

No, because you cannot write to that location.

Or can I use like this :

No, because you cannot write to that location.

Temporarily, you can use android:requestLegacyExternalStorage="true" to disable the "scoped storage" change in Android 10 and allow your app to continue using Environment.getExternalStorageDirectory(). That will stop working on Android 10 devices as soon as your targetSdkVersion hits 29, which you will need to do later this year to ship your app on the Play Store and certain other distribution channels.



Related Topics



Leave a reply



Submit