알람 기능을 테스트하기 위해 API 레벨 31 에뮬레이터를 사용하고 있었는데, PendingIntent를 생성하는 코드에서 다음과 같은 오류가 발생했다.
API 레벨 30 이전까지, FLAG_IMMUTABLE이 설정되지 않는 한 PendingIntent는 기본적으로 변경 가능했다. 하지만 API 레벨 31 부터는 PendingIntent를 사용하면 FLAG 변수로 FLAG_IMMUTABLE 또는 FLAG_MUTABLE을 사용하여 PendingIntent 사용시 변경 가능성을 명시적으로 지정해야한다(꼭 필요한 경우가 아니라면 FLAG_IMMUTABLE을 사용하도록 개발자 문서에 명시되어있다).
실제로 앱을 플레이스토어에 출시하게되면 여러 버전들에 대해 정상적으로 작동해야하므로, 다음과 같이 조건문을 작성해야한다.
// Java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
intent = PendingIntent.getBroadcast(context, code, intent, PendingIntent.FLAG_IMMUTABLE);
}else {
intent = PendingIntent.getBroadcast(context, code, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
// Kotlin
val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.getBroadcast(context, code, intent, PendingIntent.FLAG_IMMUTABLE)
}else {
PendingIntent.getBroadcast(context, code, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
FLAG_IMMUTABLE : 생성된 펜딩 인텐트가 변경되지 않음
FLAG_MUTABLE : 생성된 펜딩 인텐트가 변경될 수 있음
위 코드를 그대로 코틀린 프로젝트에서 작성한 후 실행했는데 동일한 오류가 발생했다. 분명 if문으로 조건문을 추가해주었는데도 말이다. 🤔 StackOverFlow에서 검색해보니 오류가 계속 발생한다면 내가 dependencies에 추가한 라이브러리들 중 하나가 내부적으로 WorkManager를 사용하거나 이전 버전의 WorkManager를 사용하기 때문이라고 한다. 따라서 dependencies에 다음의 종속 항목을 추가함으로써 최종적으로 문제가 해결되었다.
implementation 'androidx.work:work-runtime-ktx:2.7.0'
또는 필요하지 않다면, WorkManager를 사용하는 라이브러리를 삭제한 후 다시 싱크해도 해결된다. 나는 해당 프로젝트에서 Koin을 사용해 WorkManager를 사용할 필요가 없었기 때문에 해당 종속성을 삭제해주었다.
implementation "io.insert-koin:koin-androidx-workmanager:$koin_version"
https://developer.android.com/reference/android/app/PendingIntent#summary