API
Notification / NotificationCompat
알림이 사용자에게 어떻게 표시될지를 나타내는 클래스다.
API 레벨 11(Honeycomb)에 알림을 생성하는 Notification.Builder
가 추가되었다. 생성자는 다음과 같다.
Builder(context: Context!)
API 레벨 11 ~ 25 (deprecated)Builder(context: Context!, channelId: String!)
API 레벨 26 ~
API 레벨 4(Donut) 정도로 낮은 버전까지 호환되도록 하려면 AndroidX의 NotificationCompat
클래스를 사용한다.
NotificationChannel / NotificationChannelCompat
유사한 알림이 속하는 집합인 채널을 나타내는 클래스다.
알림 채널 기능은 API 레벨 26(O)에 추가되었기 때문에 NotificationChannelCompat
은 그 미만 버전에서는 아무런 동작도 하지 않는다.
NotificationChannel
은 생성자를, NotificationChannelCompat
은 Builder
클래스를 통해 생성된다.
NotificationChannel(id: String!, name: CharSequence!, importance: Int)
API 레벨 26 ~
채널 ID 문자열, 사용자에게 표시되는 채널 이름 문자열, 채널의 중요도를 전달한다.
중요도에 따라 사용자에게 보이는 다음 상수를 사용할 수 있다.NotificationManager.IMPORTANCE_DEFAULT
NotificationManager.IMPORTANCE_HIGH
NotificationManager.IMPORTANCE_LOW
NotificationManager.IMPORTANCE_MAX
NotificationManager.IMPORTANCE_MIN
NotificationManager.IMPORTANCE_NONE
NotificationManager.IMPORTANCE_UNSPECIFIED
NotificationChannelCompat.Builder(id: String, importance: Int)
NotificationManager / NotificationManagerCompat
생성된 알림을 표시할 때 사용하는 클래스다.
NotificationManager
는 Context.getSystemService(Context.NOTIFICATION_SERVICE)
를 호출하여 가져올 수 있다.
NotificationManagerCompat
은 생성자의 접근 제한자가 private
이기 때문에 from(Context)
를 호출하여 생성해야 한다.
소스 코드 중 이에 해당하는 부분은 다음과 같다.
@NonNull
public static NotificationManagerCompat from(@NonNull Context context) {
return new NotificationManagerCompat(context);
}
private NotificationManagerCompat(Context context) {
mContext = context;
mNotificationManager = (NotificationManager) mContext.getSystemService(
Context.NOTIFICATION_SERVICE);
}
Context
파라미터의 getSystemService()
를 호출하는 것을 알 수 있다.
알림 표시하기
알림 관리자 가져오기
getSystemService(Context.NOTIFICATION_SERVICE)
가 반환한 객체를 NotificationManager
로 캐스팅한다.
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
채널 만들기
API 레벨 26 이상 버전인 경우 알림 채널을 사용해야 하므로 NotificationChannel
을 생성한다.
생성자에 채널 ID, 채널 이름, 중요도를 전달한 뒤 여러 메서드로 채널에 대한 설정을 할 수 있다.
사용할 수 있는 메서드 중 일부는 다음과 같다.
setDescription(description: String!)
사용자에게 표시되는 채널 설명문을 지정한다.setShowBadge(showBadge: Boolean)
앱 런처 아이콘 상단에 숫자 배지를 표시할지 여부를 지정한다.setSound(sound: Uri!, audioAttributes: AudioAttributes!)
알림음 URI와 오디오 속성을 지정한다.enableLights(lights: Boolean)
(디바이스에 해당 기능이 있을 경우) 해당 채널에 포함되는 알림에 대한 표시등 점등 여부를 지정한다.setLightColor(argb: Int)
알림 표시등의 색상을 지정한다.enableVibration(vibration: Boolean)
해당 채널에 포함되는 알림의 진동 여부를 지정한다.setVibrationPattern(vibrationPattern: LongArray!)
해당 채널에 포함되는 알림에 대한 진동 패턴을 지정한다.
설정을 마치고 이 객체를 NotificationManager.createNotificationChannel()
에 전달해야 채널이 생성된다.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
"channel_id",
"Channel Name",
NotificationManager.IMPORTANCE_DEFAULT
)
channel.run {
val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val audioAttributes = AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build()
setSound(uri, audioAttributes)
description = "Description of the channel"
setShowBadge(true)
enableLights(true)
lightColor = Color.CYAN
enableVibration(true)
vibrationPattern = longArrayOf(250, 250, 250, 250)
}
manager.createNotificationChannel(channel)
}
알림 생성하기
기본 설정
NotificationCompat.Builder
를 생성한다.
빌드 버전이 API 레벨 26 미만이면 컨텍스트만 전달하는 생성자를 호출하고, 그 이상이면 채널 ID도 전달하는 생성자를 호출한다.
val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationCompat.Builder(this, "channel_id")
} else {
NotificationCompat.Builder(this)
}
Builder
의 여러 메서드로 알림에 대한 설정을 한다.
사용할 수 있는 메서드 중 일부는 다음과 같다.
setSmallIcon(icon: Int): NotificationCompat.Builder
알림에 표시될 작은 아이콘을 지정한다.setLargeIcon(icon: Bitmap?): NotificationCompat.Builder
알림에 표시될 큰 아이콘을 지정한다. 보통 메시지 앱 등에서 사용자 아이콘을 표시하는 데 사용한다.setShowWhen(show: Boolean): NotificationCompat.Builder
타임스탬프 표시 여부를 지정한다.setWhen(when: Long): NotificationCompat.Builder
타임스탬프에 표시되는 시각을 지정한다. 현재 시각을 지정하려면System.currentTimeMillis()
를 사용한다.setContentTitle(title: CharSequence?): NotificationCompat.Builder
알림의 제목을 지정한다.setContentText(text: CharSequence?): NotificationCompat.Builder
알림의 본문을 지정한다.
builder
.setSmallIcon(android.R.drawable.ic_notification_overlay)
.setWhen(System.currentTimeMillis())
.setContentTitle("Notification Title")
.setContentText("Content text of the notification")
터치 이벤트 설정
알림을 터치할 시 동작을 설정하려면 다음의 메서드를 사용할 수 있다.
setAutoCancel(autoCancel: Boolean): NotificationCompat.Builder
알림을 터치하면 자동으로 취소되는지 여부를 설정한다.
단독으로 사용하면 작동하지 않고 터치 시 실행될 수 있는PendingIntent
가 있어야 한다.setContentIntent(intent: PendingIntent?): NotificationCompat.Builder
알림을 터치하면 실행되는PendingIntent
를 지정한다.setOngoing(ongoing: Boolean): NotificationCompat.Builder
사용자가 알림을 해제하지 못하도록 하는지 여부를 설정한다.true
를 전달하면 스와이프해도 알림을 해제할 수 없다.
builder
.setContentIntent(PendingIntent.getActivity(
this, 100, Intent(), PendingIntent.FLAG_IMMUTABLE))
.setAutoCancel(true)
.setOngoing(false)
액션 추가하기
NotificationCompat.Builder.addAction()
에 NotificationCompat.Action
객체를 전달하여 액션을 추가할 수 있다.
최대 3개까지만 추가할 수 있다.
Action
의 생성자 또는 Action.Builder
클래스를 사용하여 Action
객체를 생성할 수 있다.
Action.Builder
는 build()
를 호출해야 한다.
Action(icon: Int, title: CharSequence?, intent: PendingIntent?)
액션 버튼에 표시할 아이콘의 리소스 ID, 액션 버튼 텍스트, 터치 시 실행되는 보류 인텐트를 전달한다.PendingIntent
부분에null
을 전달하면 알림에 액션을 추가해도 액션 버튼이 표시되지 않는다.Action(icon: IconCompat?, title: CharSequence?, intent: PendingIntent?)
아이콘 리소스 ID 대신IconCompat
객체를 전달한다.Action.Builder(icon: Int, title: CharSequence?, intent: PendingIntent?)
Action.Builder(icon: IconCompat?, title: CharSequence?, intent: PendingIntent?)
Action.Builder(action: Action)
Action
객체 자체를 전달한다.
builder.addAction(
android.R.drawable.ic_notification_overlay,
"Action Title",
PendingIntent.getActivity(
this, 100, Intent(this, MyActivity::class.java), PendingIntent.FLAG_IMMUTABLE)
)
알림 표시하기
NotificationCompat.Builder
의 설정을 마치고 마지막으로 build()
를 호출하면 Notification
객체가 반환된다.
알림 ID와 함께 NotificationManager.notify()
에 전달하면 사용자에게 알림이 표시된다.
반대로 알림을 취소하려면 NotificationManager.cancel()
에 취소하려는 알림의 ID를 전달하면 된다.
manager.notify(11, builder.build())
위 과정을 정리하면 다음과 같다.
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
"channel_id",
"Channel Name",
NotificationManager.IMPORTANCE_DEFAULT
)
channel.run {
val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val audioAttributes = AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build()
setSound(uri, audioAttributes)
description = "Description of the channel"
setShowBadge(true)
enableLights(true)
lightColor = Color.CYAN
enableVibration(true)
vibrationPattern = longArrayOf(250, 250, 250, 250)
}
manager.createNotificationChannel(channel)
}
val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationCompat.Builder(this, "channel_id")
} else {
NotificationCompat.Builder(this)
}
val notification = builder
.setSmallIcon(android.R.drawable.ic_notification_overlay)
.setWhen(System.currentTimeMillis())
.setContentTitle("Notification Title")
.setContentText("Content text of the notification")
.setContentIntent(
PendingIntent.getActivity(
this, 100, Intent(), PendingIntent.FLAG_IMMUTABLE
)
)
.setAutoCancel(true)
.setOngoing(false)
.addAction(
android.R.drawable.ic_notification_overlay,
"Action Title",
PendingIntent.getActivity(
this, 100, Intent(this, MyActivity::class.java), PendingIntent.FLAG_IMMUTABLE
)
)
.build()
manager.notify(11, notification)
다음과 같이 Compat 클래스를 사용하면 위와 같은 내용이지만 코드가 한결 깔끔해 보인다.
NotificationChannel
과는 다르게 NotificationChannelCompat.Builder
의 생성자에는 채널 이름을 전달하지 않는다.
하지만 세터로 이름을 설정하지 않으면 채널을 생성할 때 IllegalArgumentException
이 발생하니 주의하자.
val manager = NotificationManagerCompat.from(this)
val channel = NotificationChannelCompat.Builder(
"channel_id", NotificationManagerCompat.IMPORTANCE_DEFAULT
)
.setName("Channel Name")
.setDescription("Description of the channel")
.setLightsEnabled(true)
.setLightColor(Color.CYAN)
.setVibrationEnabled(true)
.setVibrationPattern(longArrayOf(250, 250, 250, 250))
.setSound(
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build()
)
.build()
val notification = NotificationCompat.Builder(this, "channel_id")
.setSmallIcon(android.R.drawable.ic_notification_overlay)
.setWhen(System.currentTimeMillis())
.setContentTitle("Notification Title")
.setContentText("Content text of the notification")
.setContentIntent(
PendingIntent.getActivity(
this, 100, Intent(), PendingIntent.FLAG_IMMUTABLE
)
)
.setAutoCancel(true)
.setOngoing(false)
.addAction(
android.R.drawable.ic_notification_overlay,
"Action Title",
PendingIntent.getActivity(
this, 100, Intent(this, MyActivity::class.java), PendingIntent.FLAG_IMMUTABLE
)
)
.build()
manager.createNotificationChannel(channel)
manager.notify(11, notification)
'Android' 카테고리의 다른 글
서비스 (1) : 포그라운드 및 백그라운드 서비스 (0) | 2022.08.27 |
---|---|
액션 바 사용하기 (0) | 2022.08.09 |
진동 울리기 (0) | 2022.07.21 |
벨소리 재생하기 (0) | 2022.07.19 |
Chronometer와 RecyclerView로 스톱워치 만들기 (0) | 2022.07.09 |