본문 바로가기
Android/안드로이드 스터디(Kotlin)

Android] Pending Intent

by 김마리님 2024. 3. 13.

푸시 서비스에서 액티비티를 열어야 할때 PendingIntent를 이용한다. PendingIntent는 해당 애플리케이션이 종류되더라도 Intent를 보류하며 권한을 위임받아 다른 프로세스에서 살아남아있는 인텐트이다. 따라서, 앱이 종료되더라도 푸시를 받아 액티비티를 열 때 실질적으로는 Intent가 열리는 것이 아닌 해당 Intent의 역할을 위임받은 PendingIntent가 오픈된다.

이 때, 액티비티가 열리며 푸시의 페이로드를 전달해야하는 상황에서 activity intent 에 해당 값을 실어 보낼 수 있는데, 이 때의 주의사항이 있다.

 

이것이 PendingIntent의 getActivity()의 class이다.

PendingIntent.getActivity에 열고싶은 activity의 intent를 삽입함으로써 PendingIntent의 호출 시점에서 해당 액티비티를 열어주게 된다.

    public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags) {
        throw new RuntimeException("Stub!");
    }

 

페이로드를 담아보낼 때 주의할 점은 마지막의 Flag이다.

versionSDK가 31이 되면서,  해당 PendingIntent 내부에는 이 친구가 변경 가능한지, 변경 불가능한지를 플래그로써 명시해줘야 한다. 이 플래그가 

PendingIntent.FLAG_MUTABLE
PendingIntent.FLAG_IMMUTABLE

 

이다.

해당 플래그를 명시하지 않을 시 다음과 같은 오류가 발생한다.

java.lang.IllegalArgumentException: kr.co.softopia.push_example: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
    Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.

 

오류를 읽어보면 이렇게 말한다.

 S+(버전 31 이상)를 타겟팅하려면 PendingIntent를 생성할 때 FLAG_IMMUTABLE 또는 FLAG_MUTABLE 중 하나를 지정해야 합니다. FLAG_IMMUTABLE 사용을 적극 고려하세요. 일부 기능이 PendingIntent가 변경 가능해야 하는 경우에만 FLAG_MUTABLE을 사용하세요.

 

음넹. IMMUTABLE을 적극 권장한답니다. PendingIntent가 변경되지 않는 이상은.

 

페이로드가 늘 같은 값이 들어온다면 상관 없지만, 페이로드가 다른 값이 들어온다면 PendingIntent값을 변경하지 않되, extra 값을 갱신해줘야 한다. 그러나, 여기서 문제. IMMUTABLE을 선언해버리면 새로 데이터가 들어간 PendingIntent값이 들어와도 무시해버린다.

 

따라서, Flag를 하나 더 넣어줘야하는데..

PendingIntent.FLAG_UPDATE_CURRENT
PendingIntent.FLAG_CANCEL_CURRENT

 

여기서 cancel은 새로운 PendingIntent가 들어오면 기존걸 날려버리고 새 PendingIntent를 가져오는 것이고, update는 새로 선언된 PendingIntent가 가진 데이터만 업데이트 하고 기존의 PendingIntent는 남긴다. 따라서, 우리가 원하는 동작을 사용하려면 PendingIntent를 다음과 같이 선언해야한다.

var pendingIntent = PendingIntent.getAcitivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
반응형