4

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!

Oleh Liskovych
  • 991
  • 3
  • 13
  • 31
  • Use the .DATA column to indicate where the file should be stored. But for below Android 10 it makes no sense to use the media store. – blackapps Dec 24 '20 at 20:44
  • @blackapps use .DATA like described here: https://stackoverflow.com/a/60496366/3400881 for audio/* mimeType and all mimeTypes excepto of image/* and video/* ? – Oleh Liskovych Dec 24 '20 at 20:53
  • You cannot use the media store for external files dir. That is an app specific directory where the media store keeps its hands off. – blackapps Dec 24 '20 at 21:07
  • Could you show or link some code sample demonstrating your solution? – Oleh Liskovych Dec 24 '20 at 21:11
  • @blackapps "But for below Android 10 it makes no sense to use the media store" - I need these files to be opened with other apps. As I understand If my app targets API level 30, than other apps won't be able to access `file://` Uri even though device is running Android below 10. Right? – Oleh Liskovych Dec 24 '20 at 21:23
  • You can use, no you have to use, FileProvider to serve your files to other apps with ACTION_VIEW. – blackapps Dec 24 '20 at 21:52
  • 1
    Any solid solution for this issue? – Nadimuddin Jul 23 '21 at 10:49
  • @blackapps why you not try in detail solution, related to media store. as I saw you have commented my question related to this topic. – Mohd Qasim Dec 31 '21 at 06:16

0 Answers0