简体   繁体   中英

How to save file to external storage from link using Mediastore

I have an audio class with filePath (which is a link to audio file to AWS S3 file). Here's my function

fun download(audio: Audio) {
        val audioOutStream: OutputStream

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val values = ContentValues()
            values.put(MediaStore.Audio.Media.DISPLAY_NAME, "${audio.title}.mp3")
            values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mpeg")
            values.put(
                MediaStore.Audio.Media.RELATIVE_PATH,
                "${Environment.DIRECTORY_MUSIC}/Soundy/"
            )
            val uri = context.contentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values)
            audioOutStream = context.contentResolver.openOutputStream(uri!!)!!
        } else {
            val audioPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).toString() + "/Soundy/"
            val audio = File(audioPath, audio.title!!)
            audioOutStream = FileOutputStream(audio)
        }

        audioOutStream.close()
    }

It saves audio, but this file contains nothing (It's 0 bytes). How can I save file from Url using Mediastore? My android version is 11.

EDIT Changed my code to:

 fun download(audio: Audio) {
       val values = ContentValues()
        values.put(MediaStore.Audio.Media.DISPLAY_NAME, "${audio.title}.mp3")
        values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mpeg")
        values.put(
            MediaStore.Audio.Media.RELATIVE_PATH,
            "${Environment.DIRECTORY_MUSIC}/Soundy/"
        )
        val uri = context.contentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values)
        val audioOutStream = context.contentResolver.openOutputStream(uri!!)!!
        val request = Request.Builder().url(audio.filePath).build()
        val response = OkHttpClient().newCall(request).execute()
        val sink = Okio.buffer(Okio.sink(audioOutStream))
        sink.writeAll(response.body()!!.source())
        sink.close()
        audioOutStream.close()
    }

Still isn't working.

That is because you do not do anything with audioOutStream , except to close it. If you want to write something, you need to write something. For example, you could use OkHttp to download the content and write it out . While that example shows writing to a File , Okio also offers a sink() extension function on OutputStream that you can use.

In other words, going back to your original code, you would have something like this:

fun download(audio: Audio) {
        val audioOutStream: OutputStream

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val values = ContentValues()
            values.put(MediaStore.Audio.Media.DISPLAY_NAME, "${audio.title}.mp3")
            values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mpeg")
            values.put(
                MediaStore.Audio.Media.RELATIVE_PATH,
                "${Environment.DIRECTORY_MUSIC}/Soundy/"
            )
            val uri = context.contentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values)
            audioOutStream = context.contentResolver.openOutputStream(uri!!)!!
        } else {
            val audioPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).toString() + "/Soundy/"
            val audio = File(audioPath, audio.title!!)
            audioOutStream = FileOutputStream(audio)
        }

        val request = Request.Builder().url(audio.filePath).build()
        val response = OkHttpClient().newCall(request).execute()
        val sink: BufferedSink = audioOutStream.sink().buffer()

        sink.writeAll(response.body()!!.source())
        sink.close()

        audioOutStream.close()
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM