###問題
MediaStoreに登録されている音楽の情報を変更する機能を実装したいのですが、以下のようなコードを実行しても情報が変更されません。API21~29までは以下のコードで変更できていることが確認できました。Android11(API30)でContentResolver.updateを実行すると1が返却され、情報を更新できているように見えるのですが、実際は更新されていませんでした。
###気になっていること
問題のコードを以下に掲載しますが、pendingItem()でIS_PENDINGを1にし、updateItem()で情報を更新するようになっています。pendingItem()のContentResolver.updateを実行しようとするとRecoverableSecurityExceptionが発生するので、それを拾い許可を得てから再度実行します。このときのLogCatが以下です。
LogCat
1D/MediaProvider: User allowed grant for [content://media/external/audio/media/3619] 2I/MediaProvider: Granted permission to 1 items on external to caios.android.kanade 3W/MediaProvider: Ignoring mutation of date_expires from caios.android.kanade 4D/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 5D/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でした。しかし、実際は更新されていません。
Kotlin
1private fun tagEdit(musicData: MusicData): Int { 2 val contentResolver = requireContext().contentResolver 3 val uri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, musicData.id) 4 5 return try { 6 pendingItem(contentResolver, uri) 7 updateItem(contentResolver, uri) 8 musicLibrary.buildLibrary() 9 SUCCESS 10 } catch (e: Throwable) { 11 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && e is RecoverableSecurityException) { 12 startIntentSenderForResult(e.userAction.actionIntent.intentSender, REQUEST_CODE, null, 0, 0, 0, null) 13 NEED_PERMISSION 14 } else { 15 e.printStackTrace() 16 FAILED 17 } 18 } 19 } 20 21 private fun pendingItem(contentResolver: ContentResolver, uri: Uri) { 22 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return 23 24 val contentValues = ContentValues().apply { 25 put(MediaStore.Audio.Media.IS_PENDING, 1) 26 } 27 28 val line = contentResolver.update(uri, contentValues, null, null) 29 30 Log.d(TAG, "pendingItem: update line:$line") 31 } 32 33 private fun updateItem(contentResolver: ContentResolver, uri: Uri) { 34 val title = binding.titleEditText.text.toString() 35 val artist = binding.artistEditText.text.toString() 36 val album = binding.albumEditText.text.toString() 37 val track = binding.trackEditText.text.toString().toLong() 38 val disc = binding.discEditText.text.toString().toLong() 39 val year = binding.yearEditText.text.toString().toLong() 40 41 val contentValues = ContentValues().apply { 42 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { 43 put(MediaStore.Audio.Media.IS_PENDING, 0) 44 } 45 put(MediaStore.Audio.Media.TITLE, title) 46 put(MediaStore.Audio.Media.ARTIST, artist) 47 put(MediaStore.Audio.Media.ALBUM, album) 48 put(MediaStore.Audio.Media.TRACK, addTrackAndDisc(track, disc)) 49 put(MediaStore.Audio.Media.YEAR, year) 50 } 51 52 val line = contentResolver.update(uri, contentValues, null, null) 53 54 Log.d(TAG, "updateItem: update line:$line") 55 }
あなたの回答
tips
プレビュー