안드로이드와 앱/안드로이드

알림 Notification

정혜현 2024. 7. 29. 09:48

 

알림 Notification이란?

앱의 UI와 별도로 사용자에게 앱 관련정보를 보여주는 기능

 

표시형식

  • 위치별 알림 표시형식
  • 상태 표시줄 : 아이콘
  • 알림 창 : 자세한 항목.  상태 표시줄에서 아래로 스와이프하면 열어 볼 수 있으며 세부정보 확인,  제공되는 경우 추가 콘텐츠와 작업 버튼이 표시, 문자 답장처럼 바로 간단한 작업 가능(Android 7.0부터), 확장뷰로 긴텍스트, 이미지, 버튼, 프로그래스바 등 추가가능
  • 앱 아이콘 : 배지(Android 8.0부터)

 

  • 잠금 화면(Android 5.0부터)
    알림채널에서 잠금화면 알림 설정가능(Android 8.0부터)
    잠긴 기기의 알림에 보안 레이어를 추가해 잠금 해제해야 하는 옵션 설정가능(Android 12부터)

 

  • 페어링된 웨어러블에도 표시

 

  • 앱이나 사용자가 닫을 때까지 알림 창에 계속 표시
    알림을 클릭했을 때 setAutoCancel(true)로 앱이 닫게 할 수 있다. 

 

  • 헤드업 알림 : 플로팅 창에 알림을 잠시 표시(Android 5.0부터)

 

 

 

상태표시줄

 

알림창

 

헤드업 알림

 

 

 

 

알림 구성

  • 작은 아이콘: 필수. setSmallIcon()로 설정
  • 앱 이름: 시스템에서 제공
  • 타임스탬프: 시스템에서 제공. setWhen()로 재정의하거나 setShowWhen(false)로 숨길 수 있다.
  • 큰 아이콘: 선택. 일반적으로 연락처 사진에만 사용. setLargeIcon()로 설정
  • 제목: 선택. setContentTitle()로 설정
  • 텍스트: 선택. setContentText()로 설정

 

 

알림 그룹

 

 

 

추가 알림으로 사용자에게 여러 개의 알림 또는 중복 알림을 방지하려면 새 알림을 보내는 대신

  • 기존 알림을 업데이트
  • 여러 알림을 전송해야 한다면 그룹화(Android 7.0부터)

 

 

 

알림 채널

알림채널에 할당해야 하며 그렇지 않으면 알림이 표시되지 않는다.(Android 8.0부터)

사용자가 모든 알림을 사용 중지하는 대신 특정 알림 채널만 사용 중지할 수 있다.

Android 7.1 이하를 실행하는 기기에서는 사용자가 앱별로만 알림을 관리할 수 있다.

 

 

 

림 중요도

시각적 또는 청각적으로 방해하는 정도 결정

중요도가 높을수록 사용자를 방해하는 수준도 높아진다.

 

  • 긴급: 알림음, 헤드업 알림까지
  • 높음: 알림음까지
  • 중간: 상태표시줄까지
  • 낮음: 알림 창 및 배지와 같이 사용자를 방해하지 않는 알림만 표시

 

 

 

알림 생성방법

1. NotificationCompat.Builder 객체에서 알림에 대한 UI정보와 작업을 지정

setSmallIcon()//작은 아이콘 필수!

setWhen(System.currentTimeMillis())//알림시간
setContentTitle("알림")//타이틀
setContentText("알립니다.")//내용
setContentIntent(pendingIntent)//특정 시간까지 지연 시키는 방법
setAutoCancel(true)//상태표시줄에서 알림 자동 삭제

 

2. NotificationCompat.Builder.build()호출

 

3. NotificationManagerCompat.notify()를 호출해서 시스템에 Notification객체를 전달

 

생성예시

class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {

        if (intent != null) {
            val activityIntent = Intent(context, ContactActivity::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            }
            val pendingIntent = PendingIntent.getActivity(
                context, 0, activityIntent, PendingIntent.FLAG_UPDATE_CURRENT or
                        PendingIntent.FLAG_IMMUTABLE
            )

            val manager =
                context?.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
            val builder: NotificationCompat.Builder
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                val channelId = "one-channel"
                val channelName = "알림 설정시 뜨는 이름"
                val importance = NotificationManager.IMPORTANCE_DEFAULT
                val channel = NotificationChannel(
                    channelId,
                    channelName,
                    importance
                )
                manager.createNotificationChannel(channel)
                builder = NotificationCompat.Builder(context, channelId)
            } else {
                builder = NotificationCompat.Builder(context)
            }
            builder.run {
                setSmallIcon(R.drawable.ic_alert_on)
                setWhen(System.currentTimeMillis())//알림시간
                setContentTitle("알림")//타이틀
                setContentText("알립니다.")//내용
                setContentIntent(pendingIntent)//특정 시간까지 지연 시키는 방법
                setAutoCancel(true)//상태표시줄에서 알림 자동 삭제
            }
            manager.notify(1, builder.build())
            Toast.makeText(context, "토스트메시지도 동시에 가능", Toast.LENGTH_SHORT).show()
        }
    }
}

 

 

 

 

알림 예약

알람리시버와 함께 사용하면 특정 시간에 알림을 예약할 수 있다.

 <receiver
            android:name=".AlarmReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.SANTA" />
            </intent-filter>
        </receiver>

 

  @SuppressLint("ScheduleExactAlarm")
    private fun reserveAlarm() {
        val alarmManager = requireContext().getSystemService(ALARM_SERVICE) as AlarmManager
        val intent = Intent(requireContext(), AlarmReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(
            requireContext(),
            0,
            intent,
            PendingIntent.FLAG_MUTABLE
        )
        alarmManager.setExactAndAllowWhileIdle(
            AlarmManager.RTC_WAKEUP,
            calendar.timeInMillis, pendingIntent
        )
    }

 

알람 타입

  • RTC_WAKEUP : 실제  시간에 맞게 알림이 울리며 잠들어 있는 기기도 깨운다.
  • RTC : 실제 시간에 맞게 알림이 울리며 잠들어 있는 기기는 깨우지 않는다.
  • ELAPSED_REALTIME_WAKEUP : 잠들어 있는 기기도 깨운다.
  • ELAPSED_REALTIME : 기기가 부팅된 시점으로부터 시간이 경과된 후에 알람이 울리며 잠들어 있는 기기는 깨우지 않는다.

 

 

권한설정

안드로이드 12부터는 사용자의 프라이버시를 강화하고, 앱이 사용자의 동의 없이 알림을 보내는 것을 방지하기 위해 POST_NOTIFICATIONS 권한을 앱의 매니페스트 파일에 명시적으로 추가해야 한다.

알림 권한 요청은 사용자 경험을 고려하여 적절한 시점에 수행해야 하며 사용자가 알림의 가치를 이해할 수 있도록 설득력 있는 메시지를 제공해야 한다.

 

권한예시

private fun requireAlarmPermission() {
       //다이얼로그로 권한설정 여부 확인
       MaterialAlertDialogBuilder(
            requireContext(), R.style.detail_dialog_alert
        )
            .setTitle(getString(R.string.alarm_ask_permission))
            //이동 클릭시 Settings에 알림 권한설정하러 이동
            .setNegativeButton(getString(R.string.move)) { dialog, which ->
                val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
                    putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
                }
                startActivity(intent)
            }
            //취소 클릭시 알림의 필요성을 알리는 토스트메시지
            .setPositiveButton(getString(R.string.cancel)) { dialog, which ->
                Toast.makeText(
                    requireContext(),
                    getString(R.string.alarm_need_permission),
                    Toast.LENGTH_LONG
                ).show()
            }
            .show()
    }

 

 

 

 


ᖜ ‿ᖜ

 

알림을 정리해보며 기억장치에 보다 단단히 새길 수 있었고 새로운 정보도 습득할 수 있었다.

알람채널이나 중요도처럼 어느 버전 이상부터는 무엇이 필수로 필요하다 정도로만 알고 있던 부분은

이번 기회를 통해 왜 그렇게 바뀌었는지도 알게되자 훨씬 흡수가 용이해졌고,

헤드업알림처럼 용어를 새로 배우게 된 부분은 앞으로 알림 제작시 도움이 될 것으로 기대된다.