调用这个方法前记得判断文件读取权限
记得在子线程调用
缺少android30的设备,如果哪位朋友测试在高版本可用的话,麻烦留言,谢谢
import android.content.Context
import android.media.MediaMetadataRetriever
import android.media.MediaPlayer
import android.os.Environment
import android.provider.MediaStore
import java.io.File
/**
* @Description: 把对于音频文件的文件获取方式单独当做一个类提取出来
* @Author: dk
* @Date: 2021/7/9 11:04 AM
* @Email: 1658585060@qq.com
*/
data class Song(
//歌曲名
var song: String = "",
//歌手
var singer: String = "",
//歌曲所占空间大小 单位 byte
var size: Long = 0,
//歌曲时间长度 单位 ms
var duration: Int = 0,
//歌曲地址 /storage/emulated/0/package/name.mp3
var path: String = ""
)
private val songSuffix = arrayListOf("MP3", "AAC", "M4A", "MP4", "WAV", "3GP")
//调用这个方法前记得判断文件读取权限
//记得在子线程调用
fun Context.getMusics(): MutableList<Song> {
val list = ArrayList<Song>()
//优先调用系统的音频路径
val cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.AudioColumns.IS_MUSIC)
if (cursor != null) {
while (cursor.moveToNext()) {
val song = Song()
song.song = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME))
song.singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST))
song.path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA))
song.duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))
song.size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE))
if (song.song.contains("-")) {
val str: Array<String> = song.song.split("-").toTypedArray()
song.singer = str[0]
song.song = str[1]
}
logD("MusicFileExt->" + song.toJson())
list.add(song)
}
cursor?.close()
}
if (list.isEmpty()) { //在部分机型或者高版本上下面的方法可能无法调用,优先使用上面的方法
val hasSDCard = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
val firstPath = if (hasSDCard) Environment.getExternalStorageDirectory() else filesDir.absoluteFile
val secondPath = getExternalFilesDir(null)?.absoluteFile
var songFileList = findSong(firstPath)
if (songFileList.isEmpty() && secondPath != null) {
songFileList = findSong(secondPath)
}
list.addAll(getSongInfoWithFile(songFileList))
}
return list
}
private fun findSong(file: File): ArrayList<File> {
val arrayList = ArrayList<File>()
file.listFiles()?.forEach { singleFile ->
val suffix = singleFile.name.split(".").last()
if (singleFile.isDirectory && !singleFile.isHidden) {
arrayList.addAll(findSong(singleFile))
} else if (songSuffix.find { it.equals(suffix, true) } != null) {
arrayList.add(singleFile)
}
}
return arrayList
}
private fun getSongInfoWithFile(files: MutableList<File>): MutableList<Song> {
val mediaPlayer = MediaPlayer()
val mmr = MediaMetadataRetriever()
val songs = ArrayList<Song>()
files.forEach { file ->
val song = Song()
song.path = file.absolutePath
song.size = file.length()
if (file.name.contains("-")) {
val split = file.name.split("-")
song.singer = split[0].trim()
song.song = split[1].trim()
} else {
song.song = file.name
}
try {
mmr.setDataSource(file.absolutePath)
song.duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION).number()
if (song.duration == 0) {
song.duration = readDurationWithMediaPlayer(mediaPlayer, file)
}
} catch (e: Exception) {
song.duration = readDurationWithMediaPlayer(mediaPlayer, file)
}
songs.add(song)
}
if (mediaPlayer != null) {
mediaPlayer.stop()
mediaPlayer.reset()
mediaPlayer.release()
}
return songs
}
private fun readDurationWithMediaPlayer(mediaPlayer: MediaPlayer, file: File): Int {
var duration = 0
try {
mediaPlayer.setDataSource(file.absolutePath)
mediaPlayer.prepare()
duration = mediaPlayer.getDuration()
} catch (e: Exception) {
logE("file->${file.absolutePath} read media duration failed, message-> ${e.message}")
}
return duration
}
|