Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent 해결방법 총정리
Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent 해결방법을 소개한다.
SI업체에서 일하는 안드로이드 개발자로서 무수히 많은 프로젝트들의 SDK 업데이트 작업을 하다보면 수없이 보는 에러로그다.
찬찬히 해석해보면 해결방법은 너무나 간단하지만 경우에 따라 다른 해결방법이 존재하기때문에 이 글에 총 정리를 해본다.
1. PendingIntent의 Flag 수정
에러로그를 해석해보면 targetSDK 버전이 31 이상일 때는 PendingIntent의 Flag를 FLAG_IMMUTABLE 또는 FLAG_MUTABLE을 사용해야한다는 뜻이다.
PendingIntent pending;
Intent intent = new Intent(this, MainActivity.class);
pending = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
👇위와 같은 코드를 아래처럼 바꿔주면 된다.👇
PendingIntent pending;
Intent intent = new Intent(this, MainActivity.class);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
pending = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
} else {
pending = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
앱이 실행되고있는 기기의 SDK 버전이 S(31)이상이면 PendingIntent의 flag를FLAG_IMMUTABLE 또는 FLAG_MUTABLE로 바꿔주면된다.
나같은 경우에는 Push 메시지 수신시 내요을 바꿔주기위해 FLAG_MUTABLE과 FLAG_UPDATE_CURRENT를 or 연산해주었다.
2. dependency 추가
현재 프로젝트 소스를 자바로하느냐 코틀린으로 하는지에 따라서 아래 dependency를 선택해서 추가해준다.
implementation "androidx.work:work-runtime:2.7.1" // java
implementation "androidx.work:work-runtime-ktx:2.7.1" // kotlin
3. Firebase-Messaging 라이브러리 버전 올리기
1번과 2번 같은 경우에는 다른 개발 블로그에도 왕왕 많이 나오는데 이번에 소개할 내용은 찾을 수가 없어서 삽질을 좀 했다;; (1시간 정도?)
처음에는 firebase-messaging 라이브러리 버전이 11점대를 쓰고 있었는데 이것을 23.1.1로 바꿔주니까 에러가 사라졌다!!
근데 좀 짜증나는게 이럴 경우에 파이어베이스 푸시 메시지와 관련해서 토큰값을 받는 코드를 수정해야한다.
아마 원래 아래와 같은 코드가 존재했을 것이다.
public class FcmService extends FirebaseInstanceIdService { //이 클래스와 관련된 코드는 싹 다 지워버리자
@Override
public void onCreate() {
super.onCreate();
updateToken(FirebaseInstanceId.getInstance().getToken());
}
@Override
public void onTokenRefresh() {
super.onTokenRefresh();
updateToken(FirebaseInstanceId.getInstance().getToken());
}
private void updateToken(String token) {
if (isEmpty(token)) {
Log.d("FcmService", "token is not exist.");
return;
}
Log.d("FcmService", "token is refreshed : " + token);
PreferencesRepositoryImpl repository = PreferencesRepositoryImpl.getInstance();
repository.setToken(token);
}
}
FirebaseInstanceIdService 클래스가 deprecated 되었기 때문에 Firebase token 값을 받는 부분을 FirebaseMessagingService에서 onNewToken() 메서드를 override해서 처리한다,.
아래 코드를 참고하길 바란다.
@Override
public void onNewToken(@NonNull String token) {
super.onNewToken(token);
updateToken(token);
}
private void updateToken(String token) {
if (isEmpty(token)) {
Log.d("FcmService", "token is not exist.");
return;
}
Log.d("FcmService", "token is refreshed : " + token);
PreferencesRepositoryImpl repository = PreferencesRepositoryImpl.getInstance();
repository.setToken(token);
}