(kotlin) notification

박용석·2023년 8월 28일
2

알림(notification)

  • 앱의 UI와 별도로 사용자에게 앱과 관련한 정보를 보여주는 기능
  • 알림을 터치하여 해당 앱을 열 수 있다.
    • 바로 간단한 작업(예 : 문자 답하기)을 할 수 있음(Android 7.0부터)
  • 보통 단말기 상단 부분에 표시되고, 앱 아이콘의 배지로도 표시(Android 8.0부터)

알림 채널(Android 8.0이상)

  • Android 8.0이상의 경우는 알림을 만들기 전에 알림 채널을 먼저 만들어야함.
  • 알림 채널은 알림을 그룹하여 알림 활성화나 방식을 변경 할 수 있음.
  • 현재 앱이 실행 중인 안드로이드 버전을 확인하여 8.0이상인 경우만 채널 생성
private val myNotificationID = 1
private val channelID = "default"

private fun createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Android 8.0
        val channel = NotificationChannel(channelID, "default channel",
            NotificationManager.IMPORTANCE_DEFAULT)
        channel.description = "description text of this channel."
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

알림 생성

  • 1). NotificationCompat.Builder 객체에서 알림에 대한 UI정보와 작업을 지정
    • setSmallIcon() : 작은 아이콘
    • setContentTitle() : 제목
    • setContentText() : 세부텍스
  • 2). NotificationCompat.Builder.build()호출
    • Notification객체를 반환
  • 3). NotificationManagerCompat.notify()를 호출해서 시스템에 Notification객체를 전달
private val myNotificationID = 1

private fun showNotification() {
    val builder = NotificationCompat.Builder(this, channelID)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle("title")
        .setContentText("notification text")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    NotificationManagerCompat.from(this).notify(myNotificationID, builder.build())
}

간단한 알림 예제를 만들어 보자

MainActivity.kt

package com.example.test123

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Intent
import android.graphics.BitmapFactory
import android.media.AudioAttributes
import android.media.RingtoneManager
import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.app.NotificationCompat
import com.example.test123.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.mainPageIvNotification.setOnClickListener {
            notification()
        }
    }

    fun notification() {
        val notificationId = 11

        val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager

        val builder: NotificationCompat.Builder
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // 26 버전 이상
            val channelId = "one-channel"
            val channelName = "My Channel One"
            val channel = NotificationChannel(
                channelId,
                channelName,
                NotificationManager.IMPORTANCE_DEFAULT
            ).apply {
                // 채널에 다양한 정보 설정
                description = "My Channel One Description"
                setShowBadge(true)
                val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
                val audioAttributes = AudioAttributes.Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .setUsage(AudioAttributes.USAGE_ALARM)
                    .build()
                setSound(uri, audioAttributes)
                enableVibration(true)
            }
            // 채널을 NotificationManager에 등록
            manager.createNotificationChannel(channel)
            // 채널을 이용하여 builder 생성
            builder = NotificationCompat.Builder(this, channelId)
        } else {
            // 26 버전 이하
            builder = NotificationCompat.Builder(this)
        }
        val bitmap = BitmapFactory.decodeResource(resources, R.drawable.flower)
        val intent = Intent(this, MainActivity::class.java)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
        // 알림의 기본 정보
        builder.run {
            setSmallIcon(R.mipmap.ic_launcher)
            setWhen(System.currentTimeMillis())
            setContentTitle("키워드 알림")
            setContentText("설정한 키워드에 대한 알림이 도착했습니다.")
            setStyle(
                NotificationCompat.BigTextStyle()
                    .bigText("설정한 키워드에 대한 알림이 도착했습니다!!")
            )

//            setStyle(NotificationCompat.BigPictureStyle()
//                    .bigPicture(bitmap)
//                    .bigLargeIcon(null))  // hide largeIcon while expanding
                        addAction(R.mipmap.ic_launcher, "Action", pendingIntent)
        }
        manager.notify(notificationId, builder.build())
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/main_page_iv_notification"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/emoticon"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

결과물

단순한 결과물에 비해서 코드가 어려운 것 같다. 다음 실습에서는 알림 확장뷰에서 긴 텍스트, 이미지, 버튼추가, 프로그레스바 추가 중 한가지를 더 구현해 보아야겠다.

profile
슬기로운 개발 활동

3개의 댓글

comment-user-thumbnail
2023년 8월 29일

흐아ㅏㅏ 알림은 코드가 정말 복잡한 거 같아요ㅠㅠ
그래도 깔끔하게 정리해 놓으셔서 좋네요~~!👍👍

답글 달기
comment-user-thumbnail
2023년 8월 29일

엇 슨생님 잠시만여 이거 교재 그대로 복붙하신거 같은데 기분탓이겠죠~? ^^

답글 달기
comment-user-thumbnail
2023년 9월 1일

"단순한 결과물에 비해서 코드가 어려운 것 같다" 공감입니당

답글 달기