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 aUri
to a location of the user's choosing, orUse
MediaStore
,ContentResolver
, andinsert()
to get aUri
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:
Usually the internal storage has the path
/sdcard/ on Android devices. It's not a real path but a symlink.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 accessActivity 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 aUri
to a location of the user's choosing, orUse
MediaStore
,ContentResolver
, andinsert()
to get aUri
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
How to Call Android Contacts List
Android - Dynamically Add Views into View
How to Connect to My Http://Localhost Web Server from Android Emulator
How to Add Dividers and Spaces Between Items in Recyclerview
Android: How to Get String from Resources Using Its Name
Android Action_Image_Capture Intent
Java Finished With Non-Zero Exit Value 2 - Android Gradle
What Is the Main Purpose of Settag() Gettag() Methods of View
Difference Between "@Id/" and "@+Id/" in Android
Android: Check Whether the Phone Is Dual Sim
How to Display an Alert Dialog on Android
Can the Android Layout Folder Contain Subfolders
Google Maps Android API V2 - Interactive Infowindow (Like in Original Android Google Maps)
Notification Not Showing in Oreo
Height of Status Bar in Android