알림 채널 API 이해
상태 바는 화면 상단의 배터리, 네트워크, 시간 등 시스템의 상태 정보가 출력됩니다. 이 상태 바에 앱의 정보를 출력하는 것을 알림(notification)이라고 합니다.
원래 상태 바는 시스템에서 관리하는 곳이며 앱이 직접 제어할 수 없습니다. 그런데 앱에서 시스템에 의뢰하면 시스템에서 관리하는 상태 바에 앱의 알림을 출력할 수 있습니다. 따라서 앱의 화면을 구성하거나 사용자 이벤트를 처리하는 프로그래밍과는 구조가 다르며 알림을 위해 제공하는 API를 이용해야 합니다.
알림은 NotificationManager의 notify() 함수로 발생합니다. notify() 함수에는 NotifiicationCompat.Builder가 만들어 주는 Notification 객체를 대입하며 이 객체에 알림 정보가 저장됩니다. 그런데 NotificationCompat.Builder를 만들 때 NotificationChannel 정보를 대입해 줘야 합니다.
정리하자면 NotificationChannel로 알림 채널을 만들고 NotificationManager에 등록합니다. 만들어진 채널 정보를 대입해 NoificationCompat.Builder를 만든 후, 이 빌더로 Notification 객체를 만듭니다. 최종적으로 이 Notification 객체를 NotificationManager의 notify() 함수에 대입하면 알림이 표시됩니다.
알림 빌더
Notification을 만들기 위해서는 NotificationCompat.Builer가 필요한데 빌더를 만드는 방법이 API 레벨 26(Android 8 오레오) 버전부터 변경됐습니다. 26 버전 이전까지는 다음 생성자를 이용합니다.
- Builder(context: Context!)
하지만 26 버전 이상부터는 빌더를 만들 때 NotificationChannel을 만들고 이 채널의 식별값(채널 아이디)을 빌더의 생성자 매개변수에 지정해 줘야 합니다.
- Builder(context: Context!, channelId: String!)
알림 채널 생성자는 다음과 같습니다.
- NotificationChannel(id: String!, name: CharSequence!, importance: Int)
채널의 식별값과 설정 화면에 표시할 채널 이름을 문자열로 지정합니다. 세 번째 매개변수는 이 채널에서 발생하는 알림의 중요도이며 다음의 상수로 지정합니다.
중요도 상수 | 설명 |
NotificationManager.IMPORTANCE_HIGH | 긴급 상황으로 알림음이 울리며 헤드업으로 표시 |
NotificationManager.IMPORTANCE_DEFAULT | 높은 중요도이며 알림음이 울림 |
NotificationManager.IMPORTANCE_LOW | 중간 중요도이며 알림음이 울리지 않음 |
NotificationManager.IMPORTANCE_MIN | 낮은 중요도이며 알림음도 없고 상태 바에도 표시되지 않음 |
채널의 각종 정보는 함수나 프로퍼티로 설정할 수 있습니다.
- fun setDescription(description: String!): Unit → 채널의 설명 문자열
- fun setShowBadge(showBadge: Boolean): Unit → 홈 화면의 아이콘에 배지 아이콘 출력 여부
- fun setSound(sound: Uri!, audioAttributes: AudioAttributes!): Unit → 알림음 재생
- fun enableLights(lights: Boolean): Unit → 불빛 표시 여부
- fun setLightColor(argb: Int): Unit → 불빛이 표시된다면 불빛의 색상
- fun enableVibration(vibration: Boolean): Unit → 진동을 울릴지 여부
- fun setVibrationPattern(vibrationPattern: LongArray!): Unit → 진동을 울린다면 진동의 패턴 설정
이러한 내용을 반영하여 알림 빌더(NotificationCompat.Builder)를 다음처럼 작성할 수 있습니다.
// 알림 빌더 작성 코드
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val builder: NotificationCompat.Builder
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "first-channel"
val channelName = "My first channel"
val channel = NotificationChannel(
channelId,
channelName,
NotificationManager.IMPORTANCE_HIGH
).apply {
description = "My first channel description"
}
// 채널에 다양한 정보 설정 (작성하지 않아도 알림 표시에 지장은 없음)
channel.showBadge(true)
channel.enableLights(true)
channel.lightColor = Color.RED
channel.enableVibration(true)
channel.vibrationPattern = longArrayOf(100, 200, 100, 200)
// 채널을 NotificationManager에 등록
manager.createNotificationChannel(channel)
// 채널을 이용해 빌더 생성 (API 레벨 26 오레오 버전 이상부터)
builder = NotificationCompat.Builder(this, channelId)
} else { // 26 이전 버전에서의 빌더 생성
builder = NotificationCompat.Builder(this)
}
알림 객체
알림 빌더(NotificationCompat.Builder)를 만들었으면 이 빌더를 이용해 Notification 객체를 만듭니다. 알림은 스몰 아이콘과 발생 시각, 제목, 내용 등으로 구성됩니다. 이러한 알림 정보를 빌더의 세터 함수를 이용해 설정해야 합니다.
// 알림 객체 설정
builder.setSmallIcon(android.R.drawble.ic_notification_overlay)
builder.setWhen(System.currentTimeMillis())
builder.setContentTitle("Test title")
builder.setContentText("Test text")
여기까지 작성했다면 이제 NotificationManager 클래스의 notify() 함수를 이용해 알림을 띄웁니다.
// 알림 발생
manager.notify(12, builder.build())
builder.build() 함수가 Notification 객체를 만들어 반환하고, 이로써 알림이 발생합니다. notify() 함수의 첫 번째 매개변숫값은 알림을 식별하는 데 사용하는 숫자이며 개발자가 임의로 지정합니다. 이 식별값은 사용자 폰에 발생한 알림을 코드에서 취소할 때 사용합니다. 이때 cancel() 함수를 이용하며 매개변수로 취소할 알림의 식별값을 전달합니다.
// 알림 취소
manager.cancel(12)
사용자가 알림을 터치하면 이벤트가 발생할 수 있으며 알림은 화면에서 자동으로 사라집니다. 또한 사용자가 알림을 손가락으로 밀어서(스와이프) 취소할 수 있습니다. 터치나 스와이프를 하더라도 알림이 사라지지 않게 하려면 빌더의 세터 함수로 지정해야 합니다.
// 알림 취소 막기
builder.setAutoCancel(false)
builder.setOngoing(true)
setAutoCancel(false)로 지정하면 알림을 터치할 때 이벤트는 발생하지만 알림이 사라지지는 않습니다. 또한 setOngoing(true)로 지정하면 사용자가 알림을 스와이프해도 사라지지 않습니다. 따라서 2가지를 모두 설정했다면 사용자가 알림을 취소할 수 없으며 결국 코드에서 특정 순간에 cancel() 함수로 취소해야 합니다.
지금까지 알림 채널을 이용한 알림 빌더 생성과 알림 객체 생성, 마지막으로 기본적인 알림을 띄우는 방법까지 알아봤습니다. 알림을 터치할 때 발생하는 이벤트는 대부분 앱의 액티비티 화면을 실행하는 것입니다. 그런데 알림은 앱이 관할하는 화면이 아니며 시스템에서 관리하는 상태 바에 출력하는 정보입니다. 그러므로 이 알림에서 발생한 터치 이벤트는 앱의 터치 이벤트로 처리할 수 없고, 이벤트가 발생하는 시점을 앱에서 정할 수 없으므로 인텐트(intent)를 이용해야 합니다. 인텐트를 이용한 알림 터치 이벤트 처리는 이어지는 글에서 알아보겠습니다.
'📱 Android' 카테고리의 다른 글
[Android] ViewPager2(뷰페이저2) - 스와이프로 넘기는 화면 구성 (0) | 2022.02.20 |
---|---|
[Android] ImageView(이미지뷰)를 보여주는 3가지 방법 (Kotlin) (0) | 2022.02.19 |
[Android] 에뮬레이터 무한 로딩 오류 (0) | 2022.02.10 |
[Android] Custom Dialog 띄우기 (Kotlin) (0) | 2022.02.10 |