본문 바로가기
깡샘 코틀린

10-5 알림 띄우기

by 농농씨 2023. 6. 27.

알림 채널

상태 바는 화면 상단의 한 줄을 의미하며 이곳에 배터리, 네트워크, 시간 등 시스템의 상태 정보가 출력된다. 이 상태 바에 앱의 정보를 출력하는 것을 알림(notification)이라 한다.

원래 상태 바는 시스템에서 관리하는 곳이며 앱이 직접 제어할 수 없다. 그런데 앱에서 시스템에 의뢰하면 시스템에서 관리하는 상태 바에 앱의 알림을 출력할 수 있다. 따라서 앱의 화면을 구성하거나 사용자 이벤트를 처리하는 프로그래밍과는 구조가 다르며 알림을 위해 제공하는 API를 이용해야 한다.

 

API Level 33 버전부터는 앱에서 알림을 띄우기 위해 사용자에게 퍼미션(허가)를 요청해야 한다.

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

 

알림은 NotificationManager의 notify() 함수로 발생한다. notify() 함수에는 NotificationCompat.Builder가 만들어주는 Notification 객체를 대입하며 이 객체에는 알림 정보가 저장된다. 그런데 NotificationCompat.Builder를 만들 떄 NotificationChannel 정보를 대입해 줘야 한다.

정리하자면 1️⃣NotificationChannel로 알림 채널을 만들고 2️⃣이 채널 정보를 대입해 NotificationCompat.Builder를 만든 다음, 3️⃣이 빌더로 Notification 객체를 만든다. 4️⃣이 Notification 객체를 NotificationManager의 notify() 함수에 대입하는 구조이다.

 

Notification을 만들려면 NotificationCompat.Builder가 필요한데 빌더를 만드는 방법이 API 레벨 26 (Android 8) 버전부터 변경됐다. 26 버전 이전까지는 다음 생성자를 이용했다.

  • Builder(context: Context!)

즉, 26 버전 이전까지는 빌더를 만들 때 NotificationChannel 정보가 필요 없었다. 하지만 26 버전에서 이 생성자는 deprecated 되었으며 빌더를 만들 때 다음 생성자를 사용해야 한다. 즉, NotificationChannel을 만들고 이 채널의 식별값을 빌더의 생성자 매개변수에 지정해 줘야 한다.

  • Builder(context: Context!, chennelId: String!)

API 레벨 26 버전에서 채널이라는 개념이 추가되었는데 이는 앱의 알림을 채널로 구분하겠다는 의도이다. 사용자가 환경 설정에서 어떤 앱의 알림을 받을지 말지 설정할 수 있다. 26이전 버전 이전까지는 채널이라는 개념이 없어서 사용자가 설정에서 알림을 안 받겠다고 하면 이 앱에서 띄우는 모든 알림은 발생하지 않았따.

하지만 26버전부터는 채널 개념을 도입하여 앱의 알림을 채널별로 구분할 수 있다. 받고 싶은 채널의 알림만 선택해서 받을 수 있다.

다음은 알림채널의 생성자이다.

// 알림 채널 생성자
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 : 진동을 울린다면 진동의 패턴

setDescription() 함수에 전달하는 문자열은 설정 화면에서 채널을 설명하는 곳에 보인다. 그리고 setShowBadge(true)로 설정하면 홈 화면의 앱 아이콘에 확인하지 않은 알림 개수가 표시된 배지 아이콘이 보인다.

배지 아이콘에 표시되는 숫자는 코드에서 알고리즘으로 지정하는 값이 아니라 사용자가 확인하지 않은 알림 개수가 자동으로 표시되는 것이다. 만약 사용자가 알림을 확인하면 배지 아이콘이 자동으로 사라진다. 물론 이 배지 아이콘은 코드에서 setShowBadge(true)로 지정했더라도 사용자가 폰 설정에서 앱의 배지 아이콘을 출력하지 않겠다고 설정하면 나오지 않는다.

또한 enableVibration() 함수를 이용해 알림이 발생할 때 진동이 울리게 할 수 있으며, 만약 특정 패턴으로 울려야 한다면 setVibrationPattern() 함수를 함께 이용해 진동 패턴을 설정한다.

이러한 내용을 반영하여 알림 빌더(Notification.Builder)를 다음처럼 작성할 수 있다.

// 알림 빌더 작성
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val builder: NotificationCompat.Builder

if (Build.VERSION.SDK_INT >= Build.VERISON_CODES.0) { // SDK 최소버전 설정
	val channelId = "one-channel" // 채널 ID 설정
    val channelName = "My Channel One" // 채널 이름 설정
    val chennel = NotificationChannel(
    	channelId,
        channelName,
        NotificationManager.IMPORTANCE_HIGH // 알림의 중요도(상수) 설정
    )
    
    // 채널에 다양한 정보 설정
    channel.description = "My Channel One Description" // 채널 설명(설정 화면)
    channel.setShowBadge(true) // 알림 개수 뱃지 달도록 함
    val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
    // ??
    val audioAttributes = AudioAttributes.Builder()
    	.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
        .setUsage(AudioAttributes.USAGE_ALARM)
        .build()
    channel.setsound(uri. audioAttributes) // 알림음 재생
    channel.enableLights(true) // 불빛 표시 여부
    channel.lightColor = Color.RED // 불빛이 붉은색이도록 함
    channel.enableVibration(true) // 진동 여부
    channel.vibrationPattern = longArryOf(100, 200, 100, 200) // 진동 패턴
    
    // 채널을 NotificatinoManager에 등록
    manager.createNotificationChannel(channel)
    
    // 채널을 이용해 빌더 생성
    builder = NotificationCompat.Builder(this. channelId) // 채널 아이디로 호출
} else {
	builder = NotificationCompat.Builder(this)
}

 

 

알림 객체

알림 빌더를 만들었으면 이 빌더를 이용해 Notification 객체를 만들어야 한다. 이 객체에 출력할 이미지, 문자열 등의 정보를 담는다. 앱에서 알림이 발생하면 상태 바에 이미지가 출력된다. 이를 스몰 아이콘(small icon)이라 부른다. 그리고 상태 바를 끌어내리면 알림 정보가 뜬다.

알림은 스몰 아이콘과 발생 시각, 제목, 내용 등으로 구성된다. 이러한 알림 정보를 Notification 객체에 설정해야 한다.

// 알림 객체 설정
builder.setSmallIcon(android.R.drawable.ic_notification_overlay) // 스몰 아이콘 정보 설정
builder.setWhen(System.currentTimeMillis()) // 발생 시각 정보 설정
builder.setContentTitle("Content Title") // 제목 설정
builder.setContentText("content Massage") // 내용 설정

빌더의 세터 함수를 이용해 알림의 구성 정보를 설정한다. 

 

이제 NotificationManager 클래스의 notify() 함수를 이용해 알림을 띄운다.

// 알림 발생
manager.notify(11, builder.build())

builder.build() 함수가 Notification 객체를 만들고 이로써 알림이 발생한다. 첫 번째 매개변숫값은 알림을 식별하는 데 사용하는 숫자이며 개발자가 임의로 지정한다. 이 식별값은 사용자 폰에 발생한 알림을 코드에서 취소할 때 사용한다. 이때 cancel() 함수를 이용하며 매개변수로 취소할 알림의 식별값을 전달한다.

// 알림 취소
manager.cancel(11) // 임의로 지정한 식별 코드 사용됨

 

사용자가 알림을 터치하면 이벤트가 발생할 수 있으며 이때 알림은 화면에서 자동으로 사라진다(취소). 또한 사용자가 알림을 손가락으로 밀어서(스와이프) 취소할 수도 있다. 그런데 터치나 스와이프를 하더라도 알림이 사라지지 않게 하려면 빌더의 세터 함수로 지정해야 한다.

// 알림 취소 막기(2가지 방법)
builder.setAutoCancel(false) // 터치하면 이벤트는 발생하지만 알림이 사라지지는 않음
builder.setOngoing(true) // 사용자가 스와이프해도 알림이 사라지지 않음

setAutoCancel(false)로 지정하면 알림을 터치할 때 이벤트는 발생하지만 알림이 사라지지는 않는다. 또한 setOngoing(true)로 지정하면 사용자가 알림을 스와이프해도 사라지지 않는다. 만약 2가지를 모두 설정했다면 사용자가 알림을 취소할 수 없으며 결국 코드에서 특정 순간에 cancel() 함수로 취소해야 한다.

 

 

알림 구성

지금까지 알림의 기본 구성을 살펴봤다. 알림은 그 밖에 다양한 형태로 구성할 수 있다. 지금부터 자주 사용하는 알림 구성을 살펴보자.

 

알림 터치 이벤트

알림은 사용자에게 앱의 상태를 간단하게 알려주는 기능을 하는데, 사용자가 더 많은 정보를 요구할 수 있다. 그래서 대부분 앱은 사용자가 알림을 터치했을 때 앱의 액티비티 화면을 실행한다. 이렇게 하려면 알림의 터치 이벤트를 구현해야 한다.

그런데 알림은 앱이 관할하는 화면이 아니시스템에서 관리하는 상태 바에 출력하는 정보이다. 그러므로 이 알림에서 발생한 터치 이벤트는 앱의 터치 이벤트로 처리할 수 없다. 즉, 이전에 살펴봤던 onTouchEvent() 함수로는 처리할 수 없다. 결국 앱에서는 사용자가 알림을 터치했을 때 실행해야 하는 정보를 Notifiction 객체에 담아두고, 실제 이벤트가 발생하면 Notification 객체에 등록된 이벤트 처리 내용을 시스템이 실행하는 구조로 처리한다.

 

사용자가 알림을 터치하면 앱의 액티비티 또는 브로드캐스트 리시버를 실행해야 하는데 이를 실행하려면 인텐트(Intent)를 이용해야 한다.(13장에서 자세히) 이곳에서는 간단하게 '앱의 컴포넌트를 실행하는 데 필요한 정보'정도로 생각하면 된다.

사용자가 알림 내용을 터치할 때 앱의 컴포넌트를 실행하려면 먼저 인텐트를 준비해야 한다. 이 인텐트가 있어야 알림에서 원하는 컴포넌트를 실행할 수 있다. 그런데 인텐트는 앱의 코드에서 준비하지만 이 인텐트로 실제 컴포넌트를 실행하는 시점은 앱에서 정할 수 없다. 따라서 1️⃣인텐트를 준비한 후 2️⃣Notification 객체에 담아서 3️⃣이벤트가 발생할 때 인텐트를 실행해 달라고 시스템에 의뢰해야 한다. 이러한 의뢰는 PendingIntent 클래스를 이용한다. PendingIntent 클래스는 컴포넌트별로 실행을 의뢰하는 함수를 제공한다. 각 함수의  세 번째 매개변수에 인텐트 정보를 등록한다.

  • static fun getActivity(context: Context!, requestCode: Int, intent: Intent!, flags: Int): PendingIntent!)
  • static fun getBroadcast(context: Context!, requestCode: Int, intent: Intent!, flags: Int): PendingIntent!)
  • static fun getService(context: Context!, requestCode: Int, intent: Intent!, flags: Int): PendingIntent!)

이 함수들의 네 번째 매개변수는 flag 값으로 똑같은 알림이 발생했을 때 어떻게 처리해야 하는지를 나타낸다. 여기에 입력할 상수 변수로는 FLAG_IMMUTABLE, FLAG_CANCEL,CURRENT, FLAG_MUTABLE, FLAGE_NOCREATE, FLAG_ONE_SHOW, FLAG_UPDATE_CURRENT 가운데 하나를 지정한다. 그런데 API 레벨 31을 대상으로 한다면 FLAT_MUTABLE과 FLAG_IMMUTABLE 중 하나를 지정해 주어야 한다.

 

다음은 알림을 터치했을 때 DetailActivity라는 액티비티의 실행 정보를 Notification 객체에 등록하는 코드이다. 그리고 터치 이벤트 등록은 빌더의 setContentIntent() 함수를 이용한다.

// 알림 객체에 액티비티 실행 정보 등록
val intent = Intent(this. DetailActivity::class.java)
val pendingIntent =
    PendingIntent.getActivity(this, 10, intent, // 세번째 매개변수로 인텐트 정보 등록
    	PendingIntent.FLAG_IMMUTABLE) // 네번째 매개변수로 똑같은 알림이 발생했을때 어떻게 처리할지 설정
builder.setContentIntent(pendingIntent) // 터치 이벤트 등록

 

액션

알림에는 터치 이벤트 이외에도 액션을 최대 3개까지 추가할 수 있다. 알림에서 간단한 이벤트는 액션을 처리한다. 알람 앱의 알람 취소, 전화 앱의 전화 수신이나 거부 등이 대표적인 예이다. 스크린샷 알람에서 공유, 편집, 삭제 등을 할 수 있는 것도 예시이다.

액션도 사용자 이벤트 처리가 목적이다. 따라서 알림 터치 이벤트와 마찬가지로 사용자가 액션을 터치할 때 실행할 인텐트(컴포넌트 실행 위해 필요한 정보) 정보를 PendingIntent(컴포넌트별로 실행을 의뢰하는 함수 제공)로 구성해서 등록해야 한다. 1️⃣실제 사용자가 액션을 터치하면 2️⃣등록된 인텐트가 시스템에서 실행되어 3️⃣이벤트가 처리되는 구조이다. 액션을 등록할 때는 addAction() 함수를 이용한다.

// 액션 등록 함수
open fun addAction(action: Notification.Action!): Notification.Builder

매개변수로 액션의 정보를 담는 Action 객체를 전달한다. Action 객체는 Action.Builder로 만든다

 

// 액션 빌더 생성자
Builder(icon: Int, title: CharSequence!, intent: PendingIntent!)

액션 빌더의 생성자에 아이콘 정보와 액션 문자열, 그리고 사용자가 액션을 클릭했을 때 이벤트를 위한 PendingIntent 객체를 전달한다.

// 액션 등록하기
val actionIntent = Intent(this, OneReceiver::class.java)
val actionPendingIntent = PendingIntent.getBroadcast(this, 20, actionIntent,
	PendingIntent.FLAG_IMMUTABLE)
builder.addAction( // 액션등록하는 함수
	NotificationCompat.Action.Builder( // 액션 빌더 생성자(?)
    	android.R.drawable.stat_notifymore, // 아이콘 정보
        "Action", // 문자열
        actionPendingIntent // 사용자가 액션을 클릭했을 때의 이벤트를 위한 
        			// PendingIntent(컴포넌트 실행시키는 함수를 담은 클래스)의 객체 전달
    ).build()
)

 

원격 입력

원격 입력(remoteInput)이란 알림에서 사용자 입력을 직접 받는 기법이다. 원래 사용자 입력을 받으려면 에디트 텍스트 같은 뷰가 있는 화면을 제공해야 하는데, 간단한 입력은 앱의 화면을 통하지 않고 원격으로 액션에서 직접 받아서 처리할 수 있다. 카톡알림에서 답장할 수 있는 것이 그 예시이다.

원격 입력도 액션의 한 종류이다. RemoteInput에 사용자 입력을 받는 정보를 설정한 후 액션에 추가하는 구조이다

// 원격 입력
val KEY_TEXT_REPLY = "key_text_reply" // 문자열 설정
var replyLabel: String = "답장"
var remoteInput: RemoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).run {
			// Builder에 사용자 입력 정보 설정하고 RemoteInput 객체 생성함
	setLabel(replyLabel)
    build()
}

RemoteInput.Builder에 정보를 설정한 후 RemoteInput 객체를 생성합니다. 빌더에 들어가는 정보는 이 RemoteInput의 입력을 식별하는 값입력란에 출력되는 힌트 문자열이다. 식별값은 개발자가 임의로 작성할 수 있으며 사용자가 입력한 글을 가져올 때 사용된다.

그런데 RemoteInput은 API 레벨 20에서 추가되었다. 따라서 앱의 minSdk를 20 아래로 설정했다면 API 레벨 호환성을 고려해서 작성해야 한다. 앱의 API 레벨로 if~else 문을 작성해서 처리해도 되지만 호환성을 돕는 라이브러리가 있다. RemoteInput이 정의된 라이브러리를 임포트할 때 android.app.RemoteInput이 아닌 androidx.core.app.RemoteInput을 이용하면 된다.

 

RemoteInput도 액션이므로 액션의 터치 이벤트를 처리하기 위한 PendingIntent를 준비한다.

// 인텐트 준비
val replyIntent = Intent(this, ReplyReceiver::class.jave)
val replyPendingIntent = PendingIntent.getBroadcast(this, 30, replyIntent,
	PendingIntent.FLAG_MUTABLE)

앞에서 살펴본 PendingIntent와 특별한 차이는 없다. 단지 RemoteInput은 알림에서 사용자의 입력을 받는 것이므로 이벤트로 액티비티를 실행해 앱의 화면이 출력되게 하지 않고 브로드캐스트 리시버를 실행해 백그라운드에서 사용자 입력을 처리하는 게 일반적이다.

 

이제 알림에 액션을 등록하면서 RemoteInput 정보를 함께 설정한다.

// 원격 입력 액션 등록하기
builder.addAction(
	NotificationCompat.Action.Builder(
    	R.drawable.send,
        "답장",
        replyPendingIntent
    ).addRemoteInput(remoteInput)j.build() // 알림에 액션 등록하면서 RemoteInput 정보도 함께 설정함
)

앞에서 살펴본 액션 등록 코드와 비교하면 builder에 addRemoteInput()이라는 함수를 하나 더 사용했다. 이 함수의 매개변수로 RemoteInput객체를 전달하면 된다.

 

알림에서 사용자 1️⃣입력은 앞의 코드로 처리하면 된다. 그런데 2️⃣전송할 때 실행되는 브로드캐스트 리시버에서 사용자가 입력한 글을 받을 때는 다음과 같은 코드를 사용한다.

// 브로드캐스트 리시버에서 사용자가 입력한 글을 받는 코드
val replyTxt = RemoteInput.getResultsFromIntent(intent)
	?.getCharSequence("key_text_reply") // 매개변수 문자열 주목

이 코드에서 중요한 부분은 getCharSequence() 함수의 매개변수로 지정한 문자열이다. 이 문자열이 RemoteInput을 만들 때 지정한 식별값과 같아야 한다. 또한 브로드캐스트 리시버에서 사용자의 입력 글을 받은 후 알림을 갱신해 줘야 한다. 이때 RemoteInput의 알림을 띄울 때 사용했던 알림 객체의 식별값을 지정한다.

// 알림 갱신
manager.notify(11, builder.build())

이 작업은 알림에 글을 잘 받았다는 신호를 보내는 것이다. 이렇게 신호를 보내야 알림에서 글을 입력하는 부분이 사라진다.

 

 

프로그레스

앱에서 어떤 작업이 이루어지는 데 시간이 걸린다면 보통 알림을 이용해 일의 진행 상황을 프로그레스에 바로 알려준다. 대표적인 예가 앱에서 서버로 파일을 올리거나 내려받는 경우이다.

알림의 프로그레스 바는 화면을 따로 준비하지 않고 빌더에 setProgress() 함수만 추가해 주면 자동으로 나온다.

// 프로그레스 바 함수
open fun setProgress(max: Int, progress: Int, indeterminate: Boolean): Notification.Builder

첫 번째 매개변수가 프로그레스 바의 최댓값이며 두 번째 매개변수가 진행값이다. 처음에 현잿값을 지정한 후 스레드(thread) 같은 프로그램을 사용해 진행값을 계속 바꾸면서 상황을 알려 주면 된다. 그리고 만약 세 번째 매개변숫값이 true이면 프로그레스 바는 왼쪽에서 오른쪽으로 계속 흘러가듯이 표현되다.

 

다음은 스레드를 이용해 10초 동안 프로그레스 바의 진행값을 증가시키는 예이다.

// 프로그레스 바의 진행값을 증가시키는 스레드
builder.setProgress(100, 0, false)
manager.notify(11, builder.build())

thread { // 스레드 사용
    for (1 in 1..100) {
    	builder.setprogress(100, i, false)
        manager.notify(11, builder.build())
        SystemClock.sleep(100)
    }
}

 

 

알림 스타일

알림에 보이는 정보는 기본으로 문자열이지만 그 밖에 여러 가지 스타일을 제공한다. 이 스타일을 이용하면 문자열 이외에 다양한 콘텐츠로 알림을 구성할 수 있다.

 

큰 이미지 스타일

알림에 큰 이미지를 출력할 때는 BigPictureStyle을 이용한다. 화면을 캡처했을 때 뜨는 알림을 예시로 들어보자.

알림에 문자열, 액션 외에 큰 그림도 있다. 이 이미지를 BigPictureStyle로 만든다.

// 큰 이미지 스타일
val bigPicture = BitmapFactory.decodeResource(resources, R.drawable.test)
// 출력할 이미지를 비트맵(bitmap) 형식으로 지정함
val bigStyle = NotificationCompat.BigPictureStyle()
// BigPictureStyle 객체 생성
bigStyle.bigPicture(bigPicture) // BicPictureStyle 객체의 bigPicture 프로퍼티에
					// 아까 비트맵으로 지정한 이미지를 출력함
builder.setStyle(bigStyle) // 이렇게 만든 BigPicture 객체를 setStyle() 함수에 지정함

BigPictureStyle 객체의 bigPicture 프로퍼티에 출력할 이미지를 비트맵(bitmap) 형식으로 지정하며, 이렇게 만든 BigPicture 객체를 빌더의 setStyle() 함수에 지정한다.

 

긴 텍스트 스타일

알림에 긴 문자열을 출력해 사용자가 앱을 실행하지 않아도 많은 정보를 알 수 있게 할 수 있따. 대표적으로 이메일 앱은 이메일을 수신했을 때 알림으로 제목과 발신자뿐만 아니라 일부 내용도 보여 준다. 긴 문자열 알림은 BigTextStyle을 이용한다.

// 긴 텍스트 스타일
val bigTextStyle = NotificationCompat.BigTextStyle() // BigtextStyle 객체 생성
bigTextStyle.bigText(resources.getString(R.string.long_text)) // 객체의 문자열 속성에 문자열 지정함
builder.setstyle(bigTextstyle) // 빌더의 세터 함수에 그 객체 지정

 

상자 스타일

상자 스타일 알림은 문자열목록으로 출력하는 InboxStyle을 이용한다. 하나의 알림에 문자열을 여러 개 나열할 때 유용하다.

// 상자 스타일
val style = NotificationCompat.InboxStyle()
style.addLine("1코스 - 수락.불암산코스")
style.addLine("2코스 - 용마.아차산코스")
style.addLine("3코스 - 고덕.일자산코스")
style.addLine("4코스 - 대모.우면산코스")
builder.setStyle(style)

 

메시지 스타일

메시지 스타일 알림은 여러 사람이 주고받은 메시지를 구분해서 출력할 때 사용한다. 메시지 스타일에 보일 메시지는 각각 Message 객체로 표현한다.

// 메시지 객체
Message(text: CharSequence, timestamp: Long, sender: Person?)

하나의 메시지는 3가지 정보로 표현된다. 첫 번째 매개변수는 메시지 내용이며 두 번째 매개변수는 메시지가 발생한 시각이다. 그런데 메시지 스타일은 어떤 사람이 보낸 메시지인지 설정해야 한다. 이를 세 번째 매개변수인 Person 객체로 표현한다. Person알림에 출력될 한 사람의 정보를 담는 클래스이다.

// Person 객체 생성
val sender1: Person = Person.Builder()
	.setName("kkang")
    .setIcon(IconCompat.createWithResource(this, R.drawable.person1))
    .build()
    
val sender2: person = Person.Builder()
	.setName("kim")
    .setIcon(Iconcompat.createWithResource(this, R.drawable.person2))
    .build()

앞의 코드는 Person 객체 2개를 생성한다. Person 객체는 Person.Builder로 만들며 빌더의 setName(), setIcon() 함수를 이용해 사람의 이름과 프로필 사진을 등록할 수 있다. Person은 API 레벨 28 버전에 추가된 클래스이므로 API 레벨 호환성을 위해 androidx.core.app.Person 라이브러리를 임포트해야 한다.

이렇게 만든 Person 객체를 Message에 대입해서 이용한다.

// 메시지 객체 생성
val message1 = NotificationCompat.MessagingStyle.Message(
	"hello",
    SystemcurrentTimeMillis(),
    sender1 // 메시지 객체에 Person 객체 대입함
)
val message2 = NotificationCompat.messagingStyle.Message(
	"world",
    SystemcurrentTimeMillis(),
    sender2
)

 

이제 Message 객체를 MessageStyle에 대입한다.

// 메시지 스타일 만들기
val messageStyle = NotificationCompat.MessagingStyle(sender1)
	.addMessage(message1)
    .addMessage(message2)
builder.setStyle(messageStyle)

 

 

 

 

 

 

 

 

 

 

 

 

공부일기

더보기

으음 알림파트 내용이 많고 호흡이 길어서 머가먼지 🫠 개발은 원래 이런거겟죠 그쵸 모르는 단어가 지금은 많아도 언젠간 알게 되겟죠 그쵸 아자아자 이번달안에 책 끝내야지!!!

'깡샘 코틀린' 카테고리의 다른 글

11-2 appcompat 라이브러리 - API 호환성 해결  (0) 2023.06.29
11-1 제트팩과 androidx 소개  (0) 2023.06.27
10-4 소리와 진동 알림  (0) 2023.06.25
10-3 다양한 다이얼로그  (0) 2023.06.24
10-2 퍼미션 설정하기  (0) 2023.06.24