[Android/Kotlin] 알림(Notification) 만들기

Notepad96

·

2022. 9. 10. 11:05

300x250

 

 

1. 요약

 

결과

 

이번 글에서는 알림(Notification)을 생성하는 방법에 관하여 기술한다.

 

단, 이번 글의 내용만으로는 흔히 우리가 사용하는 Application에서 발생하는 Notification은 이것만으로는 똑같이 구현해낼 수 없다.

 

 

해당 예시에서는 Application에서 Button을 클릭하였을 때 Notification이 발생하는 데 보통이었다면 "이벤트가 발생하였거나 특정 시간"에 Notification이 자동으로 발생하도록 하여야 한다.

 

 

여기서 "이벤트가 발생하였거나 특정 시간"이라는 조건을 충족시키기 위해서 메시지 서비스를 이용하거나 AlarmManager를 추가적으로 구현하여 특정 시간에 Notification이 발생하도록 기능을 구현할 수 있다.

 

 

 

[Android/Kotlin] AlarmManager - 알람 등록

1. 요약 이번 글에서는 AlarmManager를 사용하여 Alarm을 정의하고 등록하는 방법에 관하여 기술한다. AlarmManager를 통하여 Alarm을 등록하면 특정 시간에 Alarm을 발생하도록 할 수도 있으며, 지정한 시간

notepad96.tistory.com

 

 

 

 

2. 레이아웃

2-1. activity_main.xml

메인 레이아웃을 정의한 파일로서 Button 2개로 구성하였다.

 

Button을 클릭할 경우 Notification이 발생하게 되며 각각 1개의 Button은 기본적인 Notification을 다른 1개의 Button은 확장(Exapandable)이 되는 Notification을 발생하도록 한다.

 

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">

    <Button
        android:id="@+id/button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Notification 1"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.286" />

    <Button
        android:id="@+id/button02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Notification 2"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.59" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

 

 

3. 코드 및 설명

3-1. MainActivity.kt

 

 Android 8.0 이상에서는 Notification을 제공하기 위해서는 Notification 채널을 시스템에 등록할 필요가 있다.

 

따라서 Notification을 구현하기 위해서는 우선 Notification 채널을 생성해야 한다.

 

채널을 생성하기 위해서 아래와 같이 createNotificationChannel 함수를 정의하였다.

 

private fun createNotificationChannel() {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = "Notification_Ch"
        val descriptionText = "Test Notification"
        val channel = NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT).apply {
            description = descriptionText
        }

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

 

채널을 생성할 때 중요도(IMPORTANCE)를 지정하여 알림의 우선도를 어떻게 측정하여 나타낼지를 지정이 가능하다.

 


 

다음으로 intent를 정의한 후 pendingIntent를 초기화해준다.

 

pendingIntent는 Notification을 클릭하였을 때 어떠한 동작을 할지 미리 정의를 해두는 것으로, 어떤 동작을 하는지 Intent 부분을 보면 된다.

 

Intent는 MainActivity로 Application을 시작하도록 만들며 FLAG 값을 주어 현재 Application을 사용 중에 Notification을 클릭하여도 MainActivity가 NEW_TASK로 시작되도록 한다.

 

 

package com.notepad96.notification

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.notepad96.notification.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private val binding: ActivityMainBinding by lazy { ActivityMainBinding.inflate(layoutInflater) }

    companion object {
        const val CHANNEL_ID = "Test"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        createNotificationChannel()

        val intent = Intent(this, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent = PendingIntent.getActivity(this, 101, intent, 0)

        val contents = "Contents Contents Contents Contents Contents Contents Contents " +
                "Contents Contents Contents Contents Contents Contents Contents "

        // Notification
        var builder01 = NotificationCompat.Builder(this, CHANNEL_ID).apply {
            setSmallIcon(R.drawable.ic_baseline_alarm_24)   // Set Icon
            setContentTitle("Title 1")  // Set Title
            setContentText(contents)   // Set Content
            priority = NotificationCompat.PRIORITY_DEFAULT  // Set PRIORITY
            setContentIntent(pendingIntent) // Notification Click Event
            setAutoCancel(true) // Remove After Click Notification
        }

        // Expandable Notification
        var builder02 = NotificationCompat.Builder(this, CHANNEL_ID).apply {
            setSmallIcon(R.drawable.ic_baseline_alarm_24)
            setContentTitle("Title 2")
            setContentText(contents)
            priority = NotificationCompat.PRIORITY_DEFAULT
            setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.bread))
            setStyle(NotificationCompat.BigPictureStyle()
                .bigPicture(BitmapFactory.decodeResource(resources, R.drawable.bread))
                .bigLargeIcon(null)
                .setBigContentTitle("확장")
            )
            setContentIntent(pendingIntent)
//            setAutoCancel(true)
        }

        binding.button01.setOnClickListener {
            with(NotificationManagerCompat.from(this)) {
                notify(5, builder01.build())
            }
        }

        binding.button02.setOnClickListener {
            with(NotificationManagerCompat.from(this)) {
                notify(6, builder02.build())
            }
        }
    }

    private fun createNotificationChannel() {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = "Notification_Ch"
            val descriptionText = "Test Notification"
            val channel = NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT).apply {
                description = descriptionText
            }

            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
}

 

builder 부분은 Notification을 구성하는 부분으로서 Notification의 아이콘이나 제목, 내용 등을 설정하며 어떤 Style의 Notification이 나타나도록 정의하는 부분이다.

 

● setSmallIcon

Notification에서 나타낼 작은 Icon을 지정한다. 보통 Application의 Main Icon을 사용하여 어떤 Application의 Notification인지 보여준다.

 

● setContenTitle

Notification에 나타낼 제목

 

● setContenText

Notification에 나타낼 내용

 

● setContentIntent 

앞서 선언하였던 pendingIntent를 넣어주며 Notification 클릭 시 Application이 실행된다.

 

● setAutoCancel

Notification을 클릭하였을 때 Notification의 제거 여부를 지정하며 Default로 false를 갖는다.

 

여기서는 True로 지정하였으며 Notification을 클릭할 경우 Application이 실행되며 해당 Notification은 제거된다.

 

두 번째 Button으로 생성한 알림은 false이기 때문에 Notification을 클릭하여 Application이 실행되었어도 Notification은 남아있다.

 

 

● setStyle

Notification의 Style을 지정하는 부분이며, NotificationCompat의 이미 정의되어 있는 Style들을 사용하여 다양한 Style의 Notification 구현이 가능하다.

 

여기서는 두 번째 Notification을 나타내는 builder2를 정의할 때 사용하여 Expandable(확장)되며 Big Picture를 보여줄 수 있는 Style을 적용하여 Notification을 나타내었다.

 

 

 

 

4. 전체 파일

 

 

GitHub - Notepad96/BlogExample02

Contribute to Notepad96/BlogExample02 development by creating an account on GitHub.

github.com

 

 

 

300x250