본문 바로가기

안드로이드/코틀린

[Android] Notification Group을 이용한 푸시 ui 개선

반응형

'Notification Group'은 Android 7.0부터 도입돼 여러개의 노티를 그룹화 해서 보여줄수 있습니다. 예로 카카오톡의 새로운 메세지나 지메일 메일 알림이 Notification Group을 사용해 여러개의 알림들을 한가지 그룹으로 보여주고 아래로 당겼을때 개별 노티 리스트를 보여줍니다.

gmail app 

도입된 당시는 Bundle이라고 불렀지만 최신 문서에서는 Group으로 네이밍이 변경 됐습니다. 

※공식문서를 참고 했습니다.

>그룹지정

NotificationCompat.Builder를 생성할때  'setGroup(String groupKey)' 옵션으로 속할 그룹 명을 지정합니다.

설정된 키값 별로 묶여서 보여집니다.

KEY_WATER_GROUP : 저는 각 식물들의 물주는 노티들을 묶어서 보여주기 위한 키를 지정했습니다.

	private var KEY_WATER_GROUP = "waterGroup"
            
          var builder =
                NotificationCompat.Builder(context, channelId)
                    .setSmallIcon(R.drawable.ic_launcher_background)
                    .setContentTitle(title)
                    .setContentText(content)
                    .setAutoCancel(true)
                    .setShowWhen(true)
                    .setGroup(KEY_WATER_GROUP)
                    .setContentIntent(contentIntent)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)

그룹 노티 생성   

그룹별로 묶어줄 노티를 생성합니다. 그룹 노티는 별도 타이틀이나 컨텐츠는 추가하지 않고 setGroup에 동일한 키값을 주고 추가적으로setGroupSummary값을 필수로 지정해야합니다.  

그리고 setOnlyAlertOnce(true)를 설정해 중복된 노티는 한번만 보여주도록 하는데, 이 옵션을 추가하지 않으면 노티가 생성될때 마다 뒷편으로 그룹 노티가 함께 띄워지게 됩니다.

        private var KEY_WATER_GROUP = "waterGroup"
        
        fun getSummaryNoti(context: Context): NotificationCompat.Builder {
            return NotificationCompat.Builder(context, channelId)
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setAutoCancel(true)
                .setOnlyAlertOnce(true)
                .setGroup(KEY_WATER_GROUP)
                .setGroupSummary(true)
        }

노티 생성

그룹 노티는 실제 보여줄 노티와 그룹 노티를 매번 함께 호출해야 합니다.

        private var summaryNoti = 1234


	NotificationManagerCompat.from(context).notify(id.toInt(), builder.build())

	NotificationManagerCompat.from(context)
                .notify(summaryNoti, getSummaryNoti(context).build())
     

notify 함수의 첫번째 인자는 노티를 구분하는 id 값으로 같은 아이디는 쌓이지 않고 업데이트 되니 리스트로 구분할 노티들의 아이디는 각기 다르게 해야하고 그룹 노티의 아이디는 동일한 키값을 사용합니다. 제 경우는 각 식물들 마다 한번씩 밖에 보여지지 않기 때문에 넘겨 받은 키값으로 진행했습니다. 

>PendingIntent

펜딩인텐트는 다른 컴포넌트에게 작업을 지시하는 인텐트로, 노티를 클릭했을때 특정 작업을 실행하도록 설정할수 있습니다.

크게 엑티비티 실행, 서비스 실행, 브로드캐스트 실행으로 3가지 입니다. ( 저는 엑티비티를 실행시키도록 했습니다. )

PendingIntent.getActivity( Context  context, int requestCode, Intent intent, int flags) 

함수를 사용할때 고려해야 할 사항은

requestCode : 노티를 구분하는 것과 같이 펜딩 인텐트를 구분하는 코드로 중복된 코드로 인텐트를 실행시키면 이전에 예약된 작업이 사라집니다. 

예로 각 노티를 클릭했을때 A라는 엑티비티로 각 노티의 아이디 값을 전달하기 위해선 requestCode를 고유한 값으로 구분해야 하며 그렇지 않으면 각 노티를 클릭했을때 모두 동일한 값을 엑티비티로 전달하게 됩니다.


            val intent = Intent(context, MainActivity::class.java)
            intent.putExtra(MainActivity.KEY_PLANT_ID, id)

            val contentIntent =
                PendingIntent.getActivity(
                    context,
                    id.toInt(),
                    intent,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )

flags

  • FLAG_CANCEL_CURRENT : 이전에 생성한 펜딩인텐트를 취소하고 새로 만든다
  • FLAG_IMMUTABLE : 생성된 펜딩인텐트를 수정 불가하게 한다.
  • FLAG_NO_CREATE : 생성된 펜딩인텐트를 반환한다 ( 재사용 가능 )
  • FLAG_ONE_SHOT : 일회용 펜딩인텐트를 생성한다.
  • FLAG_UPDATE_CURRENT : 이미 생성된 펜딩인텐트를 업데이트한다. ( intent의 extra data만 변경 ) 
반응형