📝 스파르타코딩클럽의 '내일배움캠프' 지급 강좌를 정리한 글 입니다.
알람을 그룹하여 알람 활성화나 방식을 변경할 수 있다.
Android 8.0(API 수준 26) 이상 적용이기 때문에 안드로이드 버전을 확인하여 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 버전 체크
// 채널 생성 - 채널 ID, 이름, 중요도가 들어간다
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)
}
}
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())
}
중요도 | 설명 | 중요도(Android 8.0 이상) | 우선순위(Android 7.1 이하) |
---|---|---|---|
긴급 | 알림음이 울림, 헤드업 알림 표시 | IMPORTANCE_HIGH | PRIORITY_HIGH |
높음 | 알림음이 울림 | IMPORTANCE_DEFAULT | PRIORITY_DEFAULT |
중간 | 알림음이 없음 | IMPORTANCE_LOW | PRIORITY_LOW |
낮음 | 알림음이 없음, 상태 표시줄에 표시 안됨 | IMPORTANCE_MIN | PRIORITY_MIN |
builder.setStyle(
NotificationCompat.BigTextStyle()
.bigText(resources.getString(R.string.long_notification_body))
)
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.android.test)
val builder = NotificationCompat.Builder(this, channelID)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(bitmap)
.setContentTitle("Notification Title")
.setContentText("Notification body")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setStyle(
NotificationCompat.BigPictureStyle()
.bigPicture(bitmap)
.bigLargeIcon((null)) // hide largeIcon while expanding
)
알림에 버튼을 추가하고 버튼을 누르면 Intent로 Activity나 Broadcast를 시작한다.
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)
.setLargeIcon(bitmap)
.setContentTitle("Notification Title")
.setContentText("Notification body")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.addAction(R.drawable.android_test, "Action", pendingIntent)
NotificationManagerCompat.from(this).notify(myNotificationID, builder.build())
val builder = NotificationCompat.Builder(this, channelID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Progress")
.setContentText("In progress")
.setProgress(100, 0, false)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
NotificationManagerCompat.from(this).notify(myNotificationID, builder.build())
Thread { // 스레드로 프로그래스바 업데이트
for (i in (1..100).step(10)) {
Thread.sleep(1000)
builder.setProgress(100, i, false)
NotificationManagerCompat.from(this)
.notify(myNotificationID, builder.build())
}
builder.setContentText("Complete")
.setProgress(0, 0, false) // max = 0 이면 프로그래스바 사라짐
NotificationManagerCompat.from(this)
.notify(myNotificationID, builder.build()) // 같은 ID로 notify
}.start()
알림을 터치하면 SecondActivity가 시작, 이때 MainActivity 위에 SecondActivity가 있는 백스택을 생성
<activity
android:name=".SecondActivity"
android:parentActivityName=".MainActivity" />
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("Notification Title")
.setContentText("Notification body")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setAutoCancel(true) // auto remove this notification when user touches it
NotificationManagerCompat.from(this).notify(myNotificationID, builder.build())
<?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>
<?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="두 번째 액티비티"
android:textColor="#FF0000"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.test
class MainActivity : AppCompatActivity() {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.notificationButton.setOnClickListener {
notification()
}
}
@SuppressLint("NotificationPermission")
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"
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.img6)
val intent = Intent(this, SecondActivity::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(
"이것은 긴텍스트 샘플입니다. 아주 긴 텍스트를 쓸때는 여기다 하면 됩니다.이것은 긴텍스트 샘플입니다." +
"아주 긴 텍스트를 쓸때는 여기다 하면 됩니다.이것은 긴텍스트 샘플입니다. 아주 긴 텍스트를 쓸때는 여기다 하면 됩니다."
)
)
setLargeIcon(bitmap)
// setStyle(
// NotificationCompat.BigPictureStyle()
// .bigPicture(bitmap)
// .bigLargeIcon(null)) // hide largeIcon while expanding
addAction(R.mipmap.ic_launcher, "Action", pendingIntent)
}
manager.notify(11, builder.build())
}
}