j_iyeon 2023. 8. 25. 11:41

1. 정의

  • 앱의 UI와 별도로 사용자에게 앱과 관련한 정보 보여줌
  • 알림 터치하여 해당 앱 열기 가능 + 간단한 작업 가능 (ex. 문자 답하기)
  • 단말기 상단 부분 표시, 앱 아이콘 배지로도 표시

 

2. 알림 채널

- 알림 만들기 전에 알림 채널 생성!

- 알림 활성화나 방식 변경 가능

 

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."
        
				//NotificationManager 객체 가져옴 : 알림 관리+생성 가능
				val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        
				//채널을 NotificationManager에 등록
				notificationManager.createNotificationChannel(channel)
    }
}

 

3. 알림 생성

 

1) NotificationCompat.Builder

  • 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())
}

 

4. 알림 중요도

 

1) 채널 중요도

  • channelID, "defaultchannel", NotificationManager.IMPORTANCE_DEFAULT

2) 알림 중요

  • NotificationCompat.Builder(this,channelID).setPriority(NotificationCompat.PRIORITY_DEFAULT)

3) 순위

 

 

5. 알림 확장뷰 - 긴 텍스트

builder.setStyle(NotificationCompat.BigTextStyle()
                .bigText("이것은 긴텍스트 샘플입니다. 아주 긴 텍스트를 쓸때는 여기다 하면 됩니다.이것은 긴텍스트 샘플입니다. 아주 긴 텍스트를 쓸때는 여기다 하면 됩니다.이것은 긴텍스트 샘플입니다. 아주 긴 텍스트를 쓸때는 여기다 하면 됩니다."))

 

6. 알림 확장뷰 - 이미지

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.android_hsu)
val builder = NotificationCompat.Builder(this, channelID)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setContentTitle("새로운 알림")
    .setContentText("알림이 잘 보이시나요.")
    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    .setStyle(NotificationCompat.BigPictureStyle()
        .bigPicture(bitmap)
        .bigLargeIcon(null))

 

7. 알림 확장뷰 - 버튼 추가

val intent = Intent(this, TestActivity::class.java)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
val builder = NotificationCompat.Builder(this, channelID)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setContentTitle("새로운 알림")
    .setContentText("알림이 잘 보이시나요.")
    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    .addAction(R.drawable.andorid_hsu, "Action", pendingIntent)
        
NotificationManagerCompat.from(this).notify(myNotificationID, builder.build())

 

8. 알림 확장뷰 - 프로그레스바 추가

 

9. 알림에 액티비티 연결

 

- 알림을 터치하면 일반 액티비티인 SecondActivity 시작 + 백스택 생성

 

val intent = Intent(this, SecondActivity::class.java)
val pendingIntent = with(TaskStackBuilder.create(this)){
    addNextIntentWithParentStack(intent)
    getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
}
val builder = NotificationCompat.Builder(this, channelID)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setContentTitle("새로운 알림")
    .setContentText("알림이 잘 보이시나요.")
    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    .setContentIntent(pendingIntent)
    .setAutoCancel(true)
                
NotificationManagerCompat.from(this).notify(myNotificationID, 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">

    <Button
        android:id="@+id/notificationButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="알림 보내기"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

activity_second.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=".SecondActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="두번째 액티비티"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

MainActivity

class MainActivity : AppCompatActivity() {

    private lateinit var binding : ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.notificationButton.setOnClickListener {
            notification()
        }

    }

    fun notification(){
        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"
                // 앱의 기본 알림 소리를 가져옴
                val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
                // 소리 속성 설정
                val audioAttributes = AudioAttributes.Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) //소리의 콘텐츠 유형 설정 : 효과음에 적합
                    .setUsage(AudioAttributes.USAGE_ALARM) //소리 사용 용도
                    .build() //AudioAttribute 객체 생성
                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.ic_launcher_background)
        val intent = Intent(this, SecondActivity::class.java)

        // 플래그 설정 (여러 개의 상태나 동작 조합) : 새로운 작업으로 액티비티를 실행, 기존 작업의 모든 이전 액티비티 제거
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

        // PendingIntent : 다른 컴포넌트가 다른 컴포넌트에게 특정한 작업을 수행하도록 지연, 나중에 실행할 수 있도록 하는 객체
        // 주로 알림 클릭했을 때 앱 내부의 특정 화면으로 이동

        //PendingIntent.FLAG_UPDATE_CURRENT : 이미 생성된 PendingIntent가 있다면, 해당 PendingIntent를 업데이트하여 새로운 데이터로 갱신
        //PendingIntent.FLAG_IMMUTABLE: 생성된 PendingIntent를 불변(immutable)하게 만듦, PendingIntent에 저장된 데이터나 동작을 변경 할 수 X
        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("이것은 긴텍스트 샘플입니다. 아주 긴 텍스트를 쓸때는 여기다 하면 됩니다.이것은 긴텍스트 샘플입니다. 아주 긴 텍스트를 쓸때는 여기다 하면 됩니다.이것은 긴텍스트 샘플입니다. 아주 긴 텍스트를 쓸때는 여기다 하면 됩니다."))
            setLargeIcon(bitmap)
            addAction(R.mipmap.ic_launcher, "Action", pendingIntent)
        }

        //알림 표시 : 11 (고유한 숫자값), builder.build() (실제로 생성해 전달)
        manager.notify(11, builder.build())

    }

}

 

SecondActivity

package com.example.notification

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
    }
}