As getExternalStoragePublicDirectory has been deprecated in Android Q
, and the recommendation is to use other means. then how can we specify that we want to store the generated photos from a camera app into the DCIM
folder, or a custom sub-folder within the DCIM
?
The documentation states that the next 3 options are the new preferred alternatives:
Option 1 is out of the questions as it would mean that the photos get deleted if the app gets uninstalled.
Option 3 is also not a choice, as it would require the user to pick the location through the SAF file explorer.
We are left with option 2, the MediaStore; but at the time of this question there is no documentation on how to use it as a replacement for getExternalStoragePublicDirectory in Android Q.
getExternalStoragePublicDirectory gives internal storage - Stack Overflow. Stack Overflow for Teams – Start collaborating and sharing organizational knowledge.
MEDIA_MOUNTED. Storage state if the media is present and mounted at its mount point with read/write access. String. MEDIA_MOUNTED_READ_ONLY. Storage state if the media is present and mounted at its mount point with read-only access.
It returns the path to files folder inside Android/data/data/your_package/ on your SD card. It is used to store any required files for your app (e.g. images downloaded from web or cache files).
Based on the docs, use DCIM/...
for the RELATIVE_PATH
, where ...
is whatever your custom subdirectory would be. So, you would wind up with something like this:
val resolver = context.contentResolver val contentValues = ContentValues().apply { put(MediaStore.MediaColumns.DISPLAY_NAME, "CuteKitten001") put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg") put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/PerracoLabs") } val uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) resolver.openOutputStream(uri).use { // TODO something with the stream }
Note that since RELATIVE_PATH
is new to API Level 29, you would need to use this approach on newer devices and use getExternalStoragePublicDirectory()
on older ones.
@CommonsWare answer is amazing. But for those who want it in Java, you need to try this:
ContentResolver resolver = context.getContentResolver(); ContentValues contentValues = new ContentValues(); contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name); contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType); contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS); Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
As per the suggestion of @SamChen the code should look like this for text files:
Uri uri = resolver.insert(MediaStore.Files.getContentUri("external"), contentValues);
Because we wouldn't want txt files lingering in the Images folder.
So, the place where I have mimeType
, you enter the mime type you want. For example if you wanted txt
(@Panache) you should replace mimeType
with this string: "text/plain"
. Here is a list of mime types: https://www.freeformatter.com/mime-types-list.html
Also, where I have the variable name
, you replace it with the name of the file in your case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With