Saving files to MediaStore on devices running Android below 10

Viewed 1069

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!

0 Answers
Related