이전 글(notification 구현)에서 추가로 해 볼려고 한 것들 + a로 정리
이 글에서 할 것.
_ notificationManager의 notiy() 호출 시 id값을 그때그때 다르게 주면 여러개가 쌓일 것이다.
-> 알아본 결과 : id 값을 다르게 주는게 맞음.
많이 보이는 방법은 System.currentTimeMills()를 이용, 현재 시간을 받아와 대입하여 그때그때 id값을 다르게 지정해주는 방법.
notificationManager.notify((System.currentTimeMillis()).toInt(), notificationBuilder.build() )
noticiation이 갱신되지 않고, 여러개 쌓이는 것을 확인 할 수 있음.
위의 사진에서 제일 최근에 보낸 notification _ 쏼라3의 경우 클릭 시 PendingIntent가 잘 작동하여, 앱으로 이동하는 것을 확인할 수 있지만, 그 이전에 보낸 쏼라2나 1의 경우에는 클릭을 하더라도 아무 이벤트도 일어나지 않는 것을 확인.
문제해결 : pendingIntent의 request code도 개별적으로 설정해줘야, 각각의 notification이 제대로 일을 함.
즉, 다중 noticiation을 주어 클릭 시 데이터 전달 등 각각의 일을 처리하게하고 싶다면 pendingIntent의 request code도 다르게 주어야함.
val pendingIntent = PendingIntent.getActivity(
this, (System.currentTimeMillis()).toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT
)
pendingIntent란 intent를 가지곤 있으나, 당장 수행하지 않고, 특정 시점에 수행하도록하는 랩퍼 클래스이다. 보통 앱이 백그라운드 등에 있을 때, 현재 구동 중이지 않을 때 수행될 수 있도록 한다.
대표적인 사용처는 Notification이나, AlarmManger이다.
주요메서드
- 무엇을 실행할지에 따라서 아래와 같이 나뉜다.
notification _ 다중 알림을 받아 쌓고 싶다면, notificationManager의 notiy()의 id값과 pendingIntent의 request 코드 값을 각각 다르게 부여해야한다.
when(NotificationStyle.valueOf(data["type"]!!)){
NotificationStyle.NORMAL -> Unit
NotificationStyle.BIG_TEXT -> {
notificationBuilder.setStyle(
NotificationCompat.BigTextStyle()
.bigText(data["message"] + "\n"+ data["message"] + data["message"] + "\n"
+ data["message"] + data["message"] + data["message"])
)
}
NotificationStyle.CUSTOM -> {
notificationBuilder.setStyle(NotificationCompat.DecoratedCustomViewStyle())
.setCustomContentView(
RemoteViews(
packageName,
R.layout.custom_view_notification
).apply {
setTextViewText(R.id.tv_custion_title, data["title"])
setTextViewText(R.id.tv_custion_message, data["message"])
}
)
}
NotificationStyle.INBOX->{
val token = data["message"]?.split(' ');
if(token != null && token.size >= 3){
notificationBuilder.setStyle(
NotificationCompat.InboxStyle()
.addLine(token[0])
.addLine(token[1])
.addLine(token[2])
.setBigContentTitle(data["title"] + "!!!")
.setSummaryText("단어가 ${token.size - 3}만큼 더 왔습니다.")
)
}
}
기존에 보냈던 request body에 type이라는 키값을 추가로 주어, type 값에 따라 스타일을 적용시키도록 구현함.
: 안드로이드 7.0부터는 관련 알림을 그룹으로 표시 가능 -> 이메일 앱 등에서 알림 표시 시 동일한 그룹으로 알림을 포함하여 축소할 수 있도록 만들 수 있다. 아래 사진과 같은 스타일 알림이 좋은 예시.
(참고) 알림 그룹 != 알림 채널 그룹
val NOTI_GROUP_ID = "com.study.aos.noti_group"
notificationBuilder.setContentTitle(data["title"])
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setSubText("SubText 줄")
.setContentText(data["message"])
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setGroup(NOTI_GROUP_ID)
val notiSummaryBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Summary Noti Title")
.setContentText("new message")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setGroup(NOTI_GROUP_ID)
.setGroupSummary(true)
NotificationManagerCompat.from(this).apply{
notify((System.currentTimeMillis()/1000).toInt(), notificationBuilder.build())
notify(123, notiSummaryBuilder.build())
}
맨 아래 notification을 보면 알다시피, 맨 처음에 보낸 notification은 그룹에 들어가지않고 홀로 있게 된다.... 두번째 보낸 애들부터는 잘 그룹으로 만들어지는 것을 확인할 수 있음.
참고한 android developer 사이트에서 나온 것 처럼 summary 외에 한번에 2개 이상의 메세지를 보낼 경우에는 잘 작동된다. 내가 잘못한건지, 원래이런지 이유 알아내자.
//아래 코드 = 잘 돌아가는 경우. << 아예 notification으로 푸시할 내용 리스트로 만들어서 for문 돌리면서 여러번 보내도 잘 동작하는 것 확인.
NotificationManagerCompat.from(this).apply{
notify((System.currentTimeMillis()).toInt(), notificationBuilder.build())
notify((System.currentTimeMillis()).toInt(), notificationBuilder.build())
notify((System.currentTimeMillis()).toInt(), notificationBuilder.build())
notify(123, notiSummaryBuilder.build())
}
Android 7.0 이상부터는 앱이 4개 이상의 알림을 보내면서 그룹을 지정하지 않으면 시스템에서 이러한 알림을 자동으로 그룹화를 해줌.
notification은 중요도에 따라 알림의 형태가 달라진다.
중요도는 android 8.0 이상에서는 채널에 설정하고, 7.1 이하는 notification 자차에 설정한다.
val channel = NotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT //중요도
)
notificationBuilder.setContentTitle(notification.title)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentText(notification.body)
.setPriority(NotificationCompat.PRIORITY_DEFAULT) //중요도
.setContentIntent(pendingIntent)
.setAutoCancel(true)
잠금화면상태(system ui가 신뢰할 수 없는)에서 알림의 존재와 내용을 표시하는 방법, 가시성을 설정 (setVisibility()를 이용해 notificaiton에서 설정)
1. VISIBILITY_PUBLIC : 잠금화면 위에서도 내용을 다 읽을 수 있음.
2. VISIBILITY_PRIVATE : 기본상태, icon이나 tickerText가 표시됨. (내용은 해제 후)
3. VISIBILITY_SECRET : 사용자가 잠금화면을 풀 때까지 icon과 ticker 등 알림 일체 표시X
setAutoCancel() : 알림 탭할 경우 시 알림이 지워짐.
setContentIntent() : 알림 탭할 시 작동할 pendingIntent가 담김.
setOnlyAlertOnce() : 처음 알림 올 경우에만 알림 발생, 업데이트나 중복 시에 알림 별도로 알리지 않음.
setTicker() : 알림이 상태바에 있을 때 나타날 텍스트
setOngoing() : 알림 리스트에서 사용자가 알림을 탭하거나 스와이프해도 알림이 사라지지 않음.
잘읽었습니다. 많이 도움 되었어요