Notification 은 단말 상단 위치에 사용자가 쉽게 확인 가능합니다.
대표적으로 현재 App 의 상태를 표시 해주거나,
특정 상황에 대한 정보를 사용자에게 알려 주는 역할을 합니다.
간단한 예제를 통해서 정리하려고 합니다.
1. 예제 목표
- App 실행 시 현재 App 상태를 표시 해주는 Notification 을 생성한다.
- App 상태 Notification 내용을 업데이트 할 수 있다. (중요도 낮음)
- 알림 역할을 하는 또 다른 Notification 을 표시한다. (중요도 높음)
1. Foreground Service
먼저 Foreground Service 를 구현하기 위해 FOREGROUND_SERVICE 권한 요청합니다.
(저는 MainService.kt 클래스 명으로 서비스를 만들어 주었습니다.)
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name=".MainApplication"
.................
<service
android:name=".MainService"
android:enabled="true" />
</application>
MainActivity 에서 아래와 같이 서비스를 실행 시켜줍니다.
private fun startMainService() {
val serviceIntent = Intent(this, MainService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent)
} else {
startService(serviceIntent)
}
}
2. (App Status) Notification 생성
서비스가 실행 될 때 startNotification 메소드를 호출해주고 Notification 을 생성 해주는 동작을 합니다.
이때, Android 8.0 (Oreo) 이후부터는 채널을 꼭 생성해주고 Notification 을 실행해줘야 합니다.
class MainService : Service() {
....................
override fun onCreate() {
super.onCreate()
startNotification()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_NOT_STICKY
}
override fun onBind(p0: Intent?): IBinder? = null
private fun startNotification() {
createNotificationChannel()
val pendingIntent = Intent(this, MainActivity::class.java).let { notificationIntent ->
PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
}
val notification = NotificationCompat.Builder(this, CHANNEL_ID_APP_STATUS)
.setContentTitle("App Status")
.setContentText("App is Started.")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setOngoing(true) // Notification 를 밀어도 사라지지 않음
.build()
startForeground(NOTIFICATION_ID_APP_STATUS, notification)
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val context = MainApplication.context()
val notificationManager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(
CHANNEL_ID_APP_STATUS,
CHANNEL_ID_APP_STATUS,
NotificationManager.IMPORTANCE_LOW // 알림음이 울리지 않음
)
notificationManager.createNotificationChannel(channel)
}
}
}
3. (App Status) Notification 업데이트
MainService 클래스에서 updateNotification 을 전역함수로 사용할 수 있도록 코드를 작성하였습니다.
해당 메소드를 통해 Notification 업데이트를 원할때 호출해서 표시해줄 수 있습니다.
class MainService : Service() {
companion object {
const val NOTIFICATION_ID_APP_STATUS = 111
const val CHANNEL_ID_APP_STATUS = "AppStatus"
......
fun updateNotification(content: String) {
val context = MainApplication.context()
val pendingIntent = Intent(context, MainActivity::class.java).let { notificationIntent ->
PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
}
val notificationManager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val notification = NotificationCompat.Builder(context, CHANNEL_ID_APP_STATUS)
.setContentTitle("AppStatus")
.setContentText(content)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setOngoing(true)
.build()
notificationManager.notify(NOTIFICATION_ID_APP_STATUS, notification)
}
}
override fun onCreate() {
super.onCreate()
startNotification()
}
......
}
4. (App Status) Notification 결과
App 상태를 표시해주는 Notification 을 생성하고 업데이트 해줬을 때의 결과입니다.
5. (Alarm) Notification 업데이트
추가로 또 다른 채널의 알림 Notification 을 띄워주는 함수를 아래와 같이 작성하였습니다.
이전 Notification 과 다른 점은 채널의 중요도 설정을 IMPORTANCE_HIGH 로 설정해줘서
알림음과 상단 헤드업이 표시되도록 하였습니다.
class MainService : Service() {
companion object {
const val NOTIFICATION_ID_ALARM = 222
const val CHANNEL_ID_ALARM = "Alarm"
fun alarmNotification(content: String) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val context = MainApplication.context()
val notificationManager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(
CHANNEL_ID_ALARM,
CHANNEL_ID_ALARM,
NotificationManager.IMPORTANCE_HIGH // 알림음이 울리며 상단 헤드업으로 표시
)
notificationManager.createNotificationChannel(channel)
}
val context = MainApplication.context()
val notificationManager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val pendingIntent = Intent(context, MainActivity::class.java).let { notificationIntent ->
PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
}
val notification = NotificationCompat.Builder(context, CHANNEL_ID_ALARM)
.setContentTitle("Alarm")
.setContentText(content)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.build()
notificationManager.notify(NOTIFICATION_ID_ALARM, notification)
}
}
override fun onCreate() {
super.onCreate()
startNotification()
}
......
}
6. (Alarm) Notification 결과
알림 Notification 을 업데이트 해줬을 때의 결과입니다.
0 comments: