java—如何使用mediastore将文件从链接保存到外部存储

chy5wohz  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(413)

我有一个带有filepath的音频类(它是指向awss3文件的音频文件的链接)。这是我的职责

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()
    }

它保存音频,但此文件不包含任何内容(0字节)。如何使用mediastore从url保存文件?我的android版本是11。
编辑将我的代码更改为:

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()
    }

还是不行。

fd3cxomn

fd3cxomn1#

那是因为你什么都不做 audioOutStream ,除了关闭它。如果你想写点什么,你需要写点什么。例如,您可以使用okhttp下载内容并将其写出。而这个例子显示的是向 File ,okio还提供 sink() 扩展功能开启 OutputStream 你可以用的。
回到你原来的代码,你会得到这样的东西:

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()
    }

相关问题