AndroidRでMediaStoreのアイテムの情報を更新できない
teratailとのマルチポストになります。ご迷惑おかけして申し訳ありません。
問題
MediaStoreに登録されている音楽の情報を変更する機能を実装したいのですが、以下のようなコードを実行しても情報が変更されません。API21~29までは以下のコードで変更できていることが確認できました。Android11(API30)でContentResolver.updateを実行すると1が返却され、情報を更新できているように見えるのですが、実際は更新されていませんでした。
気になっていること
問題のコードを以下に掲載しますが、pendingItem()でIS_PENDINGを1にし、updateItem()で情報を更新するようになっています。pendingItem()のContentResolver.updateを実行しようとするとRecoverableSecurityExceptionが発生するので、それを拾い許可を得てから再度実行します。このときのLogCatが以下です。
D/MediaProvider: User allowed grant for [content://media/external/audio/media/3619]
I/MediaProvider: Granted permission to 1 items on external to caios.android.kanade
W/MediaProvider: Ignoring mutation of date_expires from caios.android.kanade
D/MediaProvider: Moving /storage/emulated/0/Music/Bang Dream!/Poppin'on!/B.O.F.mp3 to /storage/emulated/0/Music/Bang Dream!/Poppin'on!/.pending-1619280218-B.O.F.mp3
D/MediaProvider: Moving /storage/emulated/0/Music/Bang Dream!/Poppin'on!/.pending-1619280218-B.O.F.mp3 to /storage/emulated/0/Music/Bang Dream!/Poppin'on!/B.O.F.mp3
2行目まででRecoverableSecurityExceptionを拾い、変更権限を得ているのですが、3行目で「変更を無視する」?といった内容のLogが出ているのが気になっています。data_expiresカラムの情報は変更していないはずなのですが...。Android Q以下のデバイスではこういったLogCatが出ていないため、このLogCatになにか鍵があるのではないかと考えているのですが、依然として解決できていません。
コード
情報を変更したいときにtagEdit()を呼び出します。MusicData.idはMediaStore.Audio.Media._IDから得られた値です。RecoverableSecurityExceptionが発生した際もユーザーに許可が得られ次第、再度tagEdit()を呼び出します。pendingItem()でIS_PENDINGを1に変更し、updateItem()で変更する情報を取得(EditTextにユーザーが入力)してMediaStoreに更新を依頼します。ContentResolver.updateの結果はいずれも1でした。しかし、実際は更新されていません。
private fun tagEdit(musicData: MusicData): Int {
val contentResolver = requireContext().contentResolver
val uri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, musicData.id)
return try {
pendingItem(contentResolver, uri)
updateItem(contentResolver, uri)
musicLibrary.buildLibrary()
SUCCESS
} catch (e: Throwable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && e is RecoverableSecurityException) {
startIntentSenderForResult(e.userAction.actionIntent.intentSender, REQUEST_CODE, null, 0, 0, 0, null)
NEED_PERMISSION
} else {
e.printStackTrace()
FAILED
}
}
}
private fun pendingItem(contentResolver: ContentResolver, uri: Uri) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return
val contentValues = ContentValues().apply {
put(MediaStore.Audio.Media.IS_PENDING, 1)
}
val line = contentResolver.update(uri, contentValues, null, null)
Log.d(TAG, "pendingItem: update line:$line")
}
private fun updateItem(contentResolver: ContentResolver, uri: Uri) {
val title = binding.titleEditText.text.toString()
val artist = binding.artistEditText.text.toString()
val album = binding.albumEditText.text.toString()
val track = binding.trackEditText.text.toString().toLong()
val disc = binding.discEditText.text.toString().toLong()
val year = binding.yearEditText.text.toString().toLong()
val contentValues = ContentValues().apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
put(MediaStore.Audio.Media.IS_PENDING, 0)
}
put(MediaStore.Audio.Media.TITLE, title)
put(MediaStore.Audio.Media.ARTIST, artist)
put(MediaStore.Audio.Media.ALBUM, album)
put(MediaStore.Audio.Media.TRACK, addTrackAndDisc(track, disc))
put(MediaStore.Audio.Media.YEAR, year)
}
val line = contentResolver.update(uri, contentValues, null, null)
Log.d(TAG, "updateItem: update line:$line")
}