[Cursor : 커서] java.lang.IllegalArgumentException: Invalid token LOCALIZED 오류 해결하기
2020-11-20 19:47:30.300 23340-23340/sample.test.musicplayer E/TAG: HI
2020-11-20 19:47:30.311 23340-23340/sample.test.musicplayer E/AndroidRuntime: FATAL EXCEPTION: main
Process: sample.test.musicplayer, PID: 23340
java.lang.RuntimeException: Unable to start activity ComponentInfo{sample.test.musicplayer/sample.test.musicplayer.MainActivity}: java.lang.IllegalArgumentException: Invalid token LOCALIZED
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.IllegalArgumentException: Invalid token LOCALIZED
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:172)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:472)
at android.content.ContentResolver.query(ContentResolver.java:1183)
at android.content.ContentResolver.query(ContentResolver.java:1115)
at android.content.ContentResolver.query(ContentResolver.java:1071)
at sample.test.musicplayer.common.SongLib$Companion.getMediaSongList(SongLib.kt:147)
at sample.test.musicplayer.common.SongLib.<init>(SongLib.kt:17)
at sample.test.musicplayer.MainActivity.onCreate(MainActivity.kt:124)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
[오류가 발생한 코드 스니펫] 오류 원인은 COLLATE LOCALIZED ASC가 문제이다.
val selection = MediaStore.Audio.Media.IS_MUSIC + " = 1"
val sortOrder = MediaStore.Audio.Media.TITLE + " COLLATE LOCALIZED ASC"
var cur = context.contentResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
mCursorCols,
selection,
null,
sortOrder
)
fun getMediaSongList(context: Context) : ArrayList<MusicViewModel> {
val mCursorCols = arrayOf(
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.TRACK
)
val selection = MediaStore.Audio.Media.IS_MUSIC + " = 1"
val sortOrder = MediaStore.Audio.Media.TITLE + " COLLATE LOCALIZED ASC"
var cur = context.contentResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
mCursorCols,
selection,
null,
sortOrder
)
//cursor = context.contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, "title")
if (cur != null && cur.moveToFirst()) {
lateinit var title: String
lateinit var artist: String
lateinit var album: String
var idTruck: Int
// - MediaStore.Audio.Albums
// - MediaStore.Audio.Artists
// - MediaStore.Audio.Genres
// - MediaStore.Audio.Playlists
// - MediaStore.Audio.Media
//
// * Nested Inteface
// - MediaStore.Audio.AlbumColumns : 앨범을 나타내는 컬럼
// - MediaStore.Audio.ArtistColumns : 연주자를 나타내는 컬럼
// - MediaStore.Audio.GenresColumns : 쟝르를 나타내는 컬럼
// - MediaStore.Audio.PlaylistsColumns : 곡목록을 나타내는 컬럼
// - MediaStore.Audio.AudioColumns : 여러개의 테이블에서 나타나는 audio file을 위한 컬럼
idTruck = cur.getColumnIndex(MediaStore.Audio.Media.TRACK)
// val yearColumn = cursor.getColumnIndex(MediaStore.Audio.Media.YEAR)
try {
do {
title = cur.getString(cur.getColumnIndex(MediaStore.Audio.AudioColumns.TITLE))
artist = cur.getString(cur.getColumnIndex(MediaStore.Audio.AudioColumns.ARTIST))
album = cur.getString(cur.getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM));
val albumIds = cur.getLong(cur.getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM_ID))
//Log.e("TAG", "title = $title albumIds=$albumIds] duration: $duration")
val audioId = cur.getLong( cur.getColumnIndex(MediaStore.Audio.AudioColumns._ID) )
val sArtworkUri = Uri.parse("content://media/external/audio/albumart")
val sAlbumArtUri = ContentUris.withAppendedId(sArtworkUri, albumIds)
//android.util.Log.i("TAG", "sAlbumArtUri = " + sAlbumArtUri + "]");
val externalUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
val contentUri = ContentUris.withAppendedId(externalUri, audioId)
val duration = cur.getLong(cur.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION))
val musicVo = MusicViewModel(
audioId,
title,
"서브타이틀",
artist,
sAlbumArtUri,
contentUri,
album,
duration
)
musicList.add(musicVo)
} while (cur.moveToNext())
} catch (ee: IllegalStateException) {
ee.printStackTrace()
} catch (se: SecurityException) {
se.printStackTrace()
//songsList = java.util.ArrayList<MusicVo>()
} catch (e: Exception) {
e.printStackTrace()
} finally {
cur?.close()
}
}
return musicList
}
[해결방법] 안드로이드 11이 설치된 휴대폰에서 발생하는 오류이다. 안드로이드 10에서는 발생하지 않았다. ” COLLATE LOCALIZED”를 제거하거나 SDK버전를 체크하는 분기문을 작성하면 된다.
val selection = MediaStore.Audio.Media.IS_MUSIC + " = 1"
val sortOrder = MediaStore.Audio.Media.TITLE + " ASC"
var cur = context.contentResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
mCursorCols,
selection,
null,
sortOrder
)
var sortOrder: String? = null
sortOrder = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
MediaStore.Audio.Media.TITLE + " ASC"
}else{
MediaStore.Audio.Media.TITLE + " COLLATE LOCALIZED ASC"
}