I am writing code for downloading and storing in MediaStore files of different types. For devices running Android 10 and above I store all of them to Downloads
collection, and it works fine. Those running Android below 10 don't have this collection. At the beginning I tried to store them to the Files
collection, but it turned out that it's not possible to store for example image to the Files
collection. So I came to this code:
fun createDownloadsFile(context: Context, fileName: String, mimeType: String): Uri? {
val values = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
}
val collection = if (hasAndroid10()) {
values.put(MediaStore.MediaColumns.IS_PENDING, 1)
MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
} else getMediaStoreCollectionBelowAndroid10(mimeType)
return context.contentResolver.insert(collection, values)
}
private fun getMediaStoreCollectionBelowAndroid10(mimeType: String): Uri = when {
mimeType.startsWith("image/") -> MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
mimeType.startsWith("audio/") -> MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
mimeType.startsWith("video/") -> MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
else -> MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL)
}
Images and videos now get stored fine on Android below 10. But attempts to store audio crash on the line contentResolver.insert(collection, values)
with:
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.lastIndexOf(int)' on a null object reference
Attempts to store files of type different from image, video and audio crash on the same row with: java.lang.IllegalArgumentException: no path was provided when inserting new file
I will be grateful for any help!