加载 MediaStore.Audio.Media.DATA 不适用于 android 10 及以上?
Loading MediaStore.Audio.Media.DATA not working for android 10 and above?
所以我正在制作这个应用程序,我正在其中获取设备的所有音频文件。
private fun getAudioFiles() {
val songs = mutableListOf<SongEntity>()
val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
// IS_MUSIC : Non-zero if the audio file is music
val selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0"
// Sort the musics
val sortOrder = MediaStore.Audio.Media.TITLE + " ASC"
//val sortOrder = MediaStore.Audio.Media.TITLE + " DESC
val contentResolver1 = ContextWrapper(applicationContext).contentResolver
val cursor = contentResolver1!!.query(
uri,
null,
selection,
null,
sortOrder
)
//looping through all rows and adding to list
if (cursor != null && cursor.moveToFirst()) {
do {
val songName = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE))
val artistName =
cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST))
val duration =
cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION))
val url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))//.replace("\","\\"")
//val url = File(resolver.openFileDescriptor(uri, "r"))
val songEntity =
SongEntity(songs.size + 1, songName, artistName, parseLong(duration), url, -1)
Log.i("FetchCheck", songEntity.toString())
songs.add(songEntity)
//insert song one by one
//WORKING!!!
//mAllSongsViewModel.insertSong(songEntity)
} while (cursor.moveToNext())
}
//TODO - To send songs list to DB
//TODO set shared preferences for isLoaded
//fetch and initialize db with all songs at once
//WORKING!!! TO INSERT MULTIPLE SONGS AT ONCE
mAllSongsViewModel.insertSongs(songs)
//finally set shared pref
sharedPreferences.edit().putBoolean("songLoaded", true).apply()
}
接下来我必须在任何片段中加载歌曲的所有细节,这很好。但是我无法加载歌曲的封面照片。
这是一个适配器的代码,需要通过封面照片显示最近的曲目。
override fun onBindViewHolder(holder: RecentTrackViewHolder, position: Int) {
if (songs != null) {
val image=getAlbumCover(songs!![position].albumCover)
if (image != null) {
holder.imgSingleRecentTrack.setImageBitmap(BitmapFactory.decodeByteArray(image,0,image.size))
}
else{
holder.imgSingleRecentTrack.setImageResource(R.drawable.drawable_cover)
}
}
这是 getAlbumCover 方法的代码。
private fun getAlbumCover(url:String?): ByteArray? {
if(url==null)
return null
val mmr = MediaMetadataRetriever()
try {
mmr.setDataSource(url);
Log.e("IMAGE","path OBTAINED for this song")
return mmr.getEmbeddedPicture();
}
catch(e:Exception) {
Log.e("IMAGE", e.message+e.stackTrace.toString()+"for path "+url)
return null
}
现在我可以确定的是,所有音频文件都已正确提取并存储在数据库中。
但是当我尝试从音频文件的 url 加载图像时,我抛出了这个异常。我附上了各个日志消息的屏幕截图。
根据日志消息,我假设是 setDataSource(url) 抛出 illegalArgumentException(如其文档中所述)here.
现在我不知道如何解决这个问题。我试过这个:
url.replace("\","\\"")
没有成功。请建议我该怎么办?
还有别的办法吗?或者这个错误是可以解决的?
编辑:问题标题已更新,问题已得到解答。请参考已接受的答案。
问题是使用了已弃用的方法来获取 url。它现在可以正常工作到 android 9。
val url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))
要定位更高版本,请使用:
val albumArtColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)
val durationColumn = cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)
val artistColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)
val titleColumn = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)
val idColumn = cursor.getColumnIndex(MediaStore.Audio.Media._ID)
所以我正在制作这个应用程序,我正在其中获取设备的所有音频文件。
private fun getAudioFiles() {
val songs = mutableListOf<SongEntity>()
val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
// IS_MUSIC : Non-zero if the audio file is music
val selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0"
// Sort the musics
val sortOrder = MediaStore.Audio.Media.TITLE + " ASC"
//val sortOrder = MediaStore.Audio.Media.TITLE + " DESC
val contentResolver1 = ContextWrapper(applicationContext).contentResolver
val cursor = contentResolver1!!.query(
uri,
null,
selection,
null,
sortOrder
)
//looping through all rows and adding to list
if (cursor != null && cursor.moveToFirst()) {
do {
val songName = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE))
val artistName =
cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST))
val duration =
cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION))
val url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))//.replace("\","\\"")
//val url = File(resolver.openFileDescriptor(uri, "r"))
val songEntity =
SongEntity(songs.size + 1, songName, artistName, parseLong(duration), url, -1)
Log.i("FetchCheck", songEntity.toString())
songs.add(songEntity)
//insert song one by one
//WORKING!!!
//mAllSongsViewModel.insertSong(songEntity)
} while (cursor.moveToNext())
}
//TODO - To send songs list to DB
//TODO set shared preferences for isLoaded
//fetch and initialize db with all songs at once
//WORKING!!! TO INSERT MULTIPLE SONGS AT ONCE
mAllSongsViewModel.insertSongs(songs)
//finally set shared pref
sharedPreferences.edit().putBoolean("songLoaded", true).apply()
}
接下来我必须在任何片段中加载歌曲的所有细节,这很好。但是我无法加载歌曲的封面照片。
这是一个适配器的代码,需要通过封面照片显示最近的曲目。
override fun onBindViewHolder(holder: RecentTrackViewHolder, position: Int) {
if (songs != null) {
val image=getAlbumCover(songs!![position].albumCover)
if (image != null) {
holder.imgSingleRecentTrack.setImageBitmap(BitmapFactory.decodeByteArray(image,0,image.size))
}
else{
holder.imgSingleRecentTrack.setImageResource(R.drawable.drawable_cover)
}
}
这是 getAlbumCover 方法的代码。
private fun getAlbumCover(url:String?): ByteArray? {
if(url==null)
return null
val mmr = MediaMetadataRetriever()
try {
mmr.setDataSource(url);
Log.e("IMAGE","path OBTAINED for this song")
return mmr.getEmbeddedPicture();
}
catch(e:Exception) {
Log.e("IMAGE", e.message+e.stackTrace.toString()+"for path "+url)
return null
}
现在我可以确定的是,所有音频文件都已正确提取并存储在数据库中。 但是当我尝试从音频文件的 url 加载图像时,我抛出了这个异常。我附上了各个日志消息的屏幕截图。
根据日志消息,我假设是 setDataSource(url) 抛出 illegalArgumentException(如其文档中所述)here.
现在我不知道如何解决这个问题。我试过这个:
url.replace("\","\\"")
没有成功。请建议我该怎么办? 还有别的办法吗?或者这个错误是可以解决的?
编辑:问题标题已更新,问题已得到解答。请参考已接受的答案。
问题是使用了已弃用的方法来获取 url。它现在可以正常工作到 android 9。
val url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))
要定位更高版本,请使用:
val albumArtColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)
val durationColumn = cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)
val artistColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)
val titleColumn = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)
val idColumn = cursor.getColumnIndex(MediaStore.Audio.Media._ID)