[android : kotlin] 코틀린 Notification 사용 예제
알림(Notification)은 사용자에게 알림, 다른 사용자로부터의 메시지 또는 앱의 기타 실시간 정보를 제공하도록 Android가 앱의 UI 외부에 표시하는 메시지이다. 사용자는 알림을 탭하여 앱을 열거나 알림에서 바로 작업할 수 있다.알림은 상태 표시줄의 아이콘, 알림 창의 더 자세한 항목, 앱 아이콘의 배지, 페어링된 웨어러블 기기처럼 다양한 위치와 형식으로 사용자에게 자동 표시된다.알림을 보내면 먼저 상태 표시줄에 아이콘으로 표시된다.사용자는 상태 표시줄에서 아래로 스와이프하여 알림 창을 열고 세부정보를 보거나 알림에서 작업할 수 있다. 사용자는 창의 알림에서 아래로 드래그하여 상세 내용을 펼쳐볼 수 있으며, 여기에는 제공되는 경우 추가 콘텐츠와 작업 버튼이 표시된다. 알림은 앱 또는 사용자가 닫을 때까지 알림 창에 계속 표시된다.
6개의 샘플코드를 구현하였다. 크게 어려운 부분은 없어 보인다.
[MainActivity.kt]
package edu.kotlin.study
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 android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.Toolbar
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
val channel_name: String = "CHANNEL_1"
val CHANNEL_ID: String = "MY_CH"
val notificationId: Int = 1002
val notificationId2: Int = 1003
val notificationId3: Int = 1004
val notificationId4: Int = 1005
val notificationId5: Int = 1006
val notificationId6: Int = 1007
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button1.setOnClickListener {
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Default notification")
.setContentText("How Trump's favorite doctor helped influence Florida")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
createNotificationChannel(builder, notificationId)
}
button2.setOnClickListener {
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("BigTextStyle notification")
.setContentText("We made it to the Friday before Election Day.")
.setStyle(
NotificationCompat.BigTextStyle()
.bigText(
"Here's what to know.Interesting new tone from President Donald Trump on masks: CNN's Maegan Vazquez reports that after making the case that "lockdowns" to prevent the spread of coronavirus don't work, Trump told rallygoers in Tampa, Florida: "We know the disease. We social distance. We do all of the things that you have to do."n" +
""If you get close, wear a mask. 'Oh, it's controversial.' It's not controversial to me. You get close, you wear a mask. Social distance, social distance," he told the audience.n" +
"Problem: Vazquez notes the audience Trump delivered this message to was largely maskless. They were packed so tightly that several people required medical attention due to the heat and a nearby fire truck had to cool supporters down. Staff was also seen without masks"
)
)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
createNotificationChannel(builder, notificationId2)
}
button3.setOnClickListener {
var myBitmap = BitmapFactory.decodeResource(resources, R.drawable.blue_sky)
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("BigPictureStyle notification")
.setContentText("Google revenue jumps 14% to $46 billion, stock soars")
.setStyle(
NotificationCompat.BigPictureStyle().bigPicture(myBitmap)
.bigLargeIcon(null)
)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
createNotificationChannel(builder, notificationId3)
}
button4.setOnClickListener {
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("InBoxStyle notification")
.setContentText("You've got mail...")
.setStyle(
NotificationCompat.InboxStyle()
.addLine("Can the President overcome a Covid-19 spike in Wisconsin?")
.addLine("Opinion: Modern conservatives have perfected scandal-by-proxy")
.addLine(
"Analysis: Election Day is also a referendum on Trump's era of 'fake news'n" +
"Analysis: Donald Trump Jr. put a perfect exclamation point on his father's bungling of Covid-19n" +
"$284 million has already been wagered by British bettors on the US election outcome"
)
.addLine(
"Al Gore on what makes this election different from 2000n" +
"The cops who shot Walter Wallace Jr. didn't have Tasers. Here's why that might not have made a differencen" +
"Lil Wayne met with Trump and praised the President's plan for Black Americans"
)
)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
createNotificationChannel(builder, notificationId4)
}
button5.setOnClickListener {
var albumArtBitmap = BitmapFactory.decodeResource(resources, R.drawable.blue_sky)
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Wonderful music")
.setContentText("My Awesome Band")
// Show controls on lock screen even when user hides sensitive content.
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true)
//전달하는 데이터가 없을 때
var intent2 = Intent(this, AnotherActivity::class.java)
var paddingIntent2 = PendingIntent.getActivity(this, 0, intent2, 0)
//전달하는 데이터가 있을 때 플래그 처리 필요 PendingIntent.FLAG_UPDATE_CURRENT 처리
var intent1 = Intent(this, AnotherActivity::class.java)
intent1.putExtra("data1", "데이터 보낸다.")
intent1.putExtra("data2", 1004)
var paddingIntent1 =
PendingIntent.getActivity(this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT)
builder.setContentIntent(paddingIntent1)
createNotificationChannel(builder, notificationId5)
}
button6.setOnClickListener {
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Wonderful music")
.setContentText("My Awesome Band")
// Show controls on lock screen even when user hides sensitive content.
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
//.setAutoCancel(true)
//전달하는 데이터가 없을 때
var intent2 = Intent(this, AnotherActivity::class.java)
var paddingIntent2 = PendingIntent.getActivity(this, 10, intent2, 0)
//전달하는 데이터가 있을 때 플래그 처리 필요 PendingIntent.FLAG_UPDATE_CURRENT 처리
var intent1 = Intent(this, AnotherActivity::class.java)
intent1.putExtra("data1", "데이터 보낸다.")
intent1.putExtra("data2", 1004)
var paddingIntent1 =
PendingIntent.getActivity(this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT)
builder.addAction(
NotificationCompat.Action.Builder(
android.R.drawable.ic_btn_speak_now,
"답장",
paddingIntent2
).build()
)
builder.addAction(
NotificationCompat.Action.Builder(
android.R.drawable.ic_lock_idle_low_battery,
"메일쓰기",
paddingIntent2
).build()
)
builder.setContentIntent(paddingIntent1)
createNotificationChannel(builder, notificationId6)
}
}
private fun createNotificationChannel(
builder: NotificationCompat.Builder,
notificationId: Int
) {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val descriptionText = "1번 채널입니다. "//getString(R.string.channel_description)
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(CHANNEL_ID, channel_name, importance).apply {
description = descriptionText
}
channel.lightColor = Color.BLUE
channel.enableVibration(true)
// Register the channel with the system
val notificationManager: NotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
notificationManager.notify(notificationId, builder.build())
// with(NotificationManagerCompat.from(this)) {
// // notificationId is a unique int for each notification that you must define
// notify(notificationId, builder.build())
// }
} else {
val notificationManager: NotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(notificationId, builder.build())
}
}
}
[activity_main.xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="텍스트뷰"
android:textAppearance="@style/TextAppearance.AppCompat.Display2" />
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Default"/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="BigTextStyle(큰 텍스트 블록)"/>
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="BigPictureStyle"/>
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="InBoxStyle(받은편지함 스타일 알림 만들기)"/>
<Button
android:id="@+id/button5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="PendingIntent 사용"/>
<Button
android:id="@+id/button6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="PendingIntent 2"/>
</LinearLayout>
[AnotherActivity.kt]
package edu.kotlin.study
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_another.*
class AnotherActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_another)
var receiveData1 = intent.getStringExtra("data1")
var receiveData2 = intent.getIntExtra("data2", 0)
textView1.text = "$receiveData2 : $receiveData1"
}
}
[activity_another.xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="또다른 페이지"
android:textAppearance="@style/TextAppearance.AppCompat.Display2" />
</LinearLayout>
[build.gradle(:app)]
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
defaultConfig {
applicationId "edu.kotlin.study"
minSdkVersion 22
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
[REFERENCE]
알림 개요 – Android Developer 가이드 문서
알림 만들기 – Android Developer 가이드 문서
확장형 알림 만들기 – Android Developer 가이드 문서