Reputation: 863
My device is an Android 11 (API level 29).
I am trying to get album arts (for queried songs) from the contentResolver
, and if they do not exist, I want to insert one.
This is my code so far:
val folders = mutableSetOf<File>()
if (relPath.path.isNotEmpty())
folders.add(File(relPath.path, ".."))
val audioFiles = mutableListOf<AudioFile>()
val currentDir = File("")
val projection = arrayOf(
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.RELATIVE_PATH,
MediaStore.Audio.Media.DISPLAY_NAME
)
val sortOrder = MediaStore.Audio.Media.TITLE
contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, null, null, sortOrder)?.use {
val idIdx = it.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)
val titleIdx = it.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)
val albumIdx = it.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)
val albumIdIdx = it.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID)
val artistIdx = it.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)
val durationIdx = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)
val fileRelPathIdx = it.getColumnIndexOrThrow(MediaStore.Audio.Media.RELATIVE_PATH)
val displayNameIdx = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)
while (it.moveToNext()) {
val fileRelPath = File(it.getString(fileRelPathIdx).let { if (it == "/") "" else it })
if (currentDir == fileRelPath) { // only fetch songs if they are in this directory
val id = it.getLong(idIdx) // TODO getColumnIndexOrThrow
val title = it.getString(titleIdx)
val album = it.getString(albumIdx)
val albumId = it.getLong(albumIdIdx)
val artist = it.getString(artistIdx)
val duration = it.getLong(durationIdx)
val displayName = it.getString(displayNameIdx)
//////////////////////// fetch cover art
val albumArtUri = ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), albumId)
var coverArt: Bitmap? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {try {
contentResolver.loadThumbnail(albumArtUri, android.util.Size(100, 100), null)
} catch (e: IOException) {
null
}} else {
var albumArtPath: String? = null
contentResolver.query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, arrayOf(MediaStore.Audio.Albums.ALBUM_ART), "${MediaStore.Audio.Albums._ID} = ?", arrayOf(albumId.toString()), null)?.use {
if (it.moveToFirst())
albumArtPath = it.getString(it.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM_ART))
}
BitmapFactory.decodeFile(albumArtPath)
}
////////////////////// end fetch cover art
audioFiles.add(AudioFile(id, title, album, artist, coverArt, duration))
}
//
fileRelPath.toRelativeString(relPath).substringBefore('/').takeIf(String::isNotEmpty)?.let { folders.add(if (relPath.path.isEmpty()) File(it) else File(relPath.path, it)) }
}
}
In the end, to my surprise, none of my songs have an album art (using contentResolver
).
$ adb shell content query --uri "content://media/external/audio/albumart"
No result found.
$ adb shell content query --uri "content://media/external/audio/albums" | grep -vc album_art=NULL
0
So currently I am using MediaMetadataRetriever()
to fetch the album art:
val retriever = MediaMetadataRetriever()
retriever.setDataSource(File(File("/sdcard", fileRelPath.path), displayName).path)
val data = retriever.embeddedPicture
retriever.release()
if (data != null) {
coverArt = BitmapFactory.decodeByteArray(data, 0, data.size)
}
Apparently I should insert album arts myself in MediaStore: How can I update the album art path using contentResolver? This is my attempt for a single album art:
val albumArtUri = Uri.parse("content://media/external/audio/albumart")
val values = ContentValues().apply {
put("album_id", albumId)
put("_data", "/sdcard/cover.jpg") // this image does exist
}
contentResolver.insert(albumArtUri, values)
But I get the Error:
android.database.sqlite.SQLiteException: table album_art has no column named _id (code 1 SQLITE_ERROR): , while compiling: INSERT INTO album_art (_data,_id) VALUES (?,_GET_ID( '/storage/emulated/0/Music/_.thumbnails/1730630794351.jpg' ))
I have 3 questions:
/storage/emulated/0/Music/_.thumbnails/1730630794351.jpg
does not exist (the folder was created at the same time as the error though)I have these in my Manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
So it should be fine(?)
Upvotes: 0
Views: 31