[如何使用MediaStore api播放和播放歌曲?另外,获取其封面,并在可能的情况下阅读其输入流?

问题描述 投票:0回答:1
package com.devrj.helium.data_model

import android.content.ContentUris.withAppendedId
import android.content.Context
import android.net.Uri
import android.os.CancellationSignal
import android.provider.MediaStore.Audio.Media.*
import com.devrj.helium.model.entity.TrackEntity

class MediaStoreDataStream(streamInfo: () -> Context) :
    DataStream<Context, TrackEntity>(streamInfo) {

    private var cancellationSignal: CancellationSignal? = null

    companion object {
        private const val COL_ID = 0
        private const val COL_TITLE = 1
        private const val COL_SIZE = 2
        private const val COL_ARTIST = 3
        private const val COL_ALBUM = 4
        private const val COL_YEAR = 5
        private const val COL_TRACK = 6
        private const val COL_DATE_MODIFIED = 7
        private const val COL_DATE_ADDED = 8
        private const val COL_DISPLAY_NAME = 9
        private const val COL_DATA = 10

        val projection = arrayOf(
            _ID,
            TITLE,
            SIZE,
            ARTIST,
            ALBUM,
            YEAR,
            TRACK,
            DATE_MODIFIED,
            DATE_ADDED,
            DISPLAY_NAME,
            DATA
        )
    }

    override fun stopStream() {
        super.stopStream()
        cancellationSignal?.cancel()
    }


    override fun onStreamStarted() {
        val context = streamInfo()


        val contentResolver = context.contentResolver

        cancellationSignal = CancellationSignal()

        val trackQuery = contentResolver.query(
            EXTERNAL_CONTENT_URI,
            projection,
            null,
            null,
            null,
            cancellationSignal
        )
        trackQuery?.use { cursor ->
            /*
            Cache column indices
             */
            val columns = Array(projection.size) { i ->
                cursor.getColumnIndex(projection[i])
            }
            /*
            Per entity
             */
            while (cursor.moveToNext()) {

                val columnId = cursor.getLong(columns[COL_ID])

                val locationURI: Uri = withAppendedId(INTERNAL_CONTENT_URI, columnId)


                ////////////////////////////////////////////////////
                //////////////////CREATE NEW ENTITY/////////////////
                ////////////////////////////////////////////////////

                val newTrack = TrackEntity(columnId)

                newTrack.apply {
                    uri = locationURI.path.toString()
                    size = cursor.getLong(columns[COL_SIZE])
                    title = cursor.getString(columns[COL_TITLE])
                    artist = cursor.getString(columns[COL_ARTIST])
                    album = cursor.getString(columns[COL_ALBUM])
                    track = cursor.getInt(columns[COL_TRACK])
                    dateModified = cursor.getLong(columns[COL_DATE_MODIFIED])
                    dateAdded = cursor.getLong(columns[COL_DATE_ADDED])
                    dateAccessed = cursor.getLong(columns[COL_DATE_ADDED])
                    year = cursor.getLong(columns[COL_YEAR])
                    displayName = cursor.getString(columns[COL_DISPLAY_NAME])
                    filePath = cursor.getString(columns[COL_DATA])
                }

                send(newTrack)

                newTrack.deb()

            }
        }

    }


}

我最近开始学习MediaStore API,并且由于我正在构建音乐播放器应用程序,因此我认为由于其所有性能优势而迁移到该应用程序将是有益的。但是,我似乎无法播放一首歌曲或检索其封面。我该如何实现?

这是我尝试播放歌曲的方式

            val resolver: ContentResolver = onContextRequest!!.onRequest().contentResolver
            val mode = "rw"

            try {

                val uri = Uri.parse(Stem.get().loadedTrack.data!!.uri)

                uri.toast(onContextRequest!!.onRequest())

                resolver.openFileDescriptor(uri, mode).use {

                    player!!.setDataSource(it!!.fileDescriptor)
                }

            } catch (e: IOException) {
                e.printStackTrace()
                "ERROR $e".longToast(onContextRequest!!.onRequest())
            }

而且我得到了异常FileNotFoundException

ERROR java.io.FileNotFoundException: No content provider: /internal/audio/<some_id>

在我可以将数据源设置为文件的路径之前,它可以正常工作,但是这种方法不是最有效的。

在官方的android文档中,说明了如何执行此操作。这是我在做什么。

https://developer.android.com/training/data-storage/shared/media#open-file

这些都是我已经声明的所有权限(是的,它们在运行时被授予)

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
android kotlin filenotfoundexception mediastore
1个回答
0
投票

我看不到EXTERNAL_CONTENT_URI是什么。如果您使用的是Android Q,请使用

Uri mediaUri = MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);

然后生成文件的类似于ContentUri的文件

contentUri = ContentUris.withAppendedId(                            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, _id);

使用此uri启动MediaMetaRetriever以获取相册

MediaMetadataRetriever mmr = new MediaMetadataRetriever();
byte[] img = mmr.getEmbeddedPicture();

您可以像玩这个uri一样>>

mMediaplayer.setDataSource(mContext, uri);

希望有帮助。不要忘记设置运行权限。

GGK

© www.soinside.com 2019 - 2024. All rights reserved.