안드로이드

[Android/Kotlin] 알림 - Notification (1) Basic - Notification (Manager, Builder, Channel), NotificationManager.cancel()

란서 2022. 6. 20. 21:47

알림 (Notification) Overview


앱이 어떠한 액션을 취했을 때, background 또는 foreground 어느 상황에서든지 해당 내용을 담은 알림창을 status bar에 보여주는 서비스이다. 알림에 설정된 중요도 "Importance" 에 따라 알림에 사운드가 나오거나 화면 상단에 pop up message를 띄울 수 있다.

 

알림의 기본적인 형태

 

  1. 작은 아이콘: 필수 구성요소이며 setSmallIcon()을 통해 설정됩니다.
  2. 앱 이름: 시스템에서 제공합니다.
  3. 타임스탬프: 시스템에서 제공하지만 setWhen()을 사용하여 재정의하거나 setShowWhen(false)로 숨길 수 있습니다.
  4. 큰 아이콘: 선택사항이며(일반적으로 연락처 사진에만 사용되며 앱 아이콘에 사용하지 않음) setLargeIcon()을 통해 설정됩니다.
  5. 제목: 선택사항이며 setContentTitle()을 통해 설정됩니다.
  6. 텍스트: 선택사항이며 setContentText()를 통해 설정됩니다.

 



알림을 생성하기 위해서는 보통 다음과 같은 과정을 거친다.

 

  1. NotificationManager의 extend function을 이용, 함수 내에서 Notification Builder를 만들고 알림을 생성한다.
  2. Notification BuilderNotificationCompat.Builder() 를 호출하며 해당 인자로는

    ApplicationContext
    channel's Id  : String (채널은 뒤에 설명)

    를 넘겨주어야 한다.

  3. Notification Builder를 통해 기본적으로  title, content, icon 을 설정해주어야 한다.

    builder.
    setContentTitle()
    setContentText()
    setSmallIcon()

    와 같은 메소드가 있다.

  4.  NotificationManger가 제공하는 notify() 메서드를 통해 "알림"을 알릴 수 있다.

    notify()메서드에는 다음과 같은 인자를 전달한다.

    Notification's Id : Int (해당 인자는 '알림'의 고유한 ID로써 알림을 update 또는 cancel 하는 데에 사용될 수 있다.)
    Notification Builder


※ 주의 
모든 알림(Notificaiton)은 반드시 알림 채널(NotificationChannel)에 할당되어야 한다.

 

알림 매니저 및 확장함수 (NotificationManager & extend Function)


'알림 매니저'는 시스템이 제공하는 "시스템 서비스" 이다. 
따라서 다음과 같이 contextCompat.getSystemService() 메서드를 통해 NotificationManager를 생성한다.

 

*NotifiicationManager는 알림이 사용될 UI 또는 클래스에서 구현하는 것이 좋다.

val notificationManager = 
contextCompat.getSystemService(context, NotificationManager::class.java) 
as NotificationManager

 


'알림 매니저'확장 함수를 만들어 알림을 생성할 수 있다.

fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context ) {
	...
}

-sendNotification() 확장 함수의 인자는 

1. setContextText()에 들어갈 messageBody
2. Notfication Builder를 만들 때 사용될 applicationContext (이외에도 다양하게 사용)

전달받는다.

 

private val NOTIFICATION_ID = 0

fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context ) {
	val notifyBuilder = NotificationCompat.Builder(
    	applicationContext,
        applicationContext.getString(R.string.egg_notificattion_channel_id)
    )
    
    .setSmallIcon(R.drawable.cooked_egg)
    .setContentTitle(applicationContext.getString(R.string.notification_title))
    .setContentText(messageBody)
    
    notify(NOTIFICATION_ID, builder.build())
}

 

-> NotificationCompat.Builder() 를 이용하여 알림을 생성한 뒤, notify() 메서드 호출하여 알림을 전송할 수 있다.

 


//In ViewModel.kt

val notificationManager = 
contextCompat.getSystemService(context, NotificationManager::class.java) 
as NotificationManager

notificationManager.sendNotification("Time is Running...", applicationContext)

 

이 후 NotificationManager를 호출하는 UI 또는 viewModel에서 sendNotificaion() 메서드 호출.

 

 

알림 채널 (NotificationChannel)


알림이 생성되어 display 되려면 반드시 특정 알림 채널에 속해야만 한다. (API 26이상 부터 모든 Notification은 반드시 채널에 할당되어야만 한다.)

알림 채널은 알림의 '유형 type' 을 나타낸다. 

예를 들어 요리와 관련된 서비스를 제공하는 어플리케이션이 있다고 가정하자.

 

그렇다면 해당 어플리케이션은 다음과 같은 알림을 제공할 것이다.

 

"곧 오븐에서 요리를 꺼낼 시간 입니다!"

 

해당 알림의 목적은 어플리케이션의 사용자에게 요리 시간이 완료 되었음을 알리는 것이다.

그런데 똑같은 어플리케이션에서 다음과 같은 알림도 보여준다고 한다.

 

"신선한 고기가 20% 할인된 가격으로 입고 되었습니다!"

이번 알림의 목적은 사용자에게 요리에 필요한 재료들을 알리는 것이다.

이번 알람은 위의 알림의 목적과는 상이하다. 

따라서 두 알림은 다른 '카테고리'에 묶여야 한다.
이 '카테고리'를 의미하는 것이 '알림 채널'이다

다른 알림 채널에 속한 알림들은 사용자에게 display될 때 겹쳐서 나타나지 않는다.
또한 사용자가 알림을 끄고 싶을 때 불필요한 알림 채널만을 비활성화할 수 있다.


알림 채널을 생성하여 해당 채널을 사용하기 위해서는 마찬가지로 NotificationManager 을 사용한다.
NotificationManager.createNotificationChannel() 메서드를 사용하여 인자로

NotificationChannel 인스턴스를 넘겨준다


NotificationChannel 인스턴스는 NotificationChannel.Builder()를 통해 생성한다.

//In Fragment

...
createNotificationChannel("cook_channel", "Cook")
...

}

fun createNotificationChannel(channelId:String, ChannelName:String) {
	val notificationChannel = NotificationChannel.Builder(
    	channelId,
        channelName,
        NotificationManager.IMPORTANCE_HIGH
    )
}
  • channel_Id : String = 채널의 고유한 아이디를 인자로 넘긴다. 앞으로 Notification 객체가 만들어질 때 그 Notification이 어느 채널에 할당될 지 선택할 때 채널 아이디를 사용한다.

  • channel_name : String = 채널의 이름을 인자로 넘긴다. 쉽게 말해 카테고리 제목을 정하는 것이다. 

  • Notification Importance = 해당 채널의 중요도를 인자로 넘긴다. 채널의 중요도를 설정하는데 뒤에서 설명.

notificationChannel.enableLights(true)
notificationChannel.lifgtColor = Color.RED
notificationChannel.enableVibration(true)
notificationChannel.description = "Breakfast reminder"

 

NotificationChannel 내부 메서드를 통해 채널의 디테일한 부분을 설정해 줄 수 있다.

val notificationManager = requireActivity().getSystemService(
	NotificationManager::class.java
) as NotificationManager

notificationManager.createNotificationChannel(notificationChannel)

위에 언급한 대로 notificationManager을 사용하여 알림 채널을 사용할 수 있도록 생성.

 

 

 

NotificationManager.cancel()


앱에서 사용자에게 알림을 나타낸 뒤, 알람을 확인하기도 전에 앱은 다시 알람을 display 해야되는 상황이 생길 수 있다.
만약 사용자에게 새로운 알람을 갱신해야 되는 경우에는 기존의 알람을 제거해야 할 필요가 있다.


두 알람의 채널이 같은 알림 채널이라고 가정했을 때 기존의 알람이 이미 status bar에 존재하는 경우,
새 알람이 나타난다면 두 알람 간에 충돌이 생겨 알람의 갱신이 제대로 이루어지지 않는 경우를 볼 수 있다.

따라서 알람을 notify() 하기 전 (위의 예시에서는 NotficationManager.sendNotification() 을 통해 notify)
먼저 기존의 알람을 cancel() 하는 것이 권장된다.

NotificationManager의 cancel 메서드는 다음과 같다.

  • NotificationManager.cacnel( id : Int) = 채널의 고유 id를 인자로 하여 해당 채널의 알람을 삭제할 수 있다.
  • NotificationManager.cancelAll() = NotificationManager의 모든 Channel의 알림을 제거한다.

 

//NotificationManager Extension Function
fun NotificationManager.cancelNotification() {
	cancelAll()
}


//viewModel
val notificationManager = (requireActivity() or contextCompat).getSystemService(
	context, //contextCompat인 경우
    NotificationManager::class.java
) as NotificationManager

notification.cancelNotification()
notification.sendNotification(messageBody, applicationContext)

 

 

 

참고


https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=ko 

 

알림 개요  |  Android 개발자  |  Android Developers

알림 개요 알림은 사용자에게 미리 알림을 주고 다른 사람과의 소통을 가능하게 하며 앱에서 보내는 기타 정보를 적시에 제공하기 위해 Android가 앱의 UI 외부에 표시하는 메시지입니다. 사용자

developer.android.com