#1 ์ด์ ๊ธ
[Android] Notifications - ๊ธฐ์ด
#1 ๊ฐ์ ์๋ฆผ ๊ฐ์ | Views | Android Developers์ด ํ์ด์ง๋ Cloud Translation API๋ฅผ ํตํด ๋ฒ์ญ๋์์ต๋๋ค. ์๋ฆผ ๊ฐ์ ์ปฌ๋ ์ ์ ์ฌ์ฉํด ์ ๋ฆฌํ๊ธฐ ๋ด ํ๊ฒฝ์ค์ ์ ๊ธฐ์ค์ผ๋ก ์ฝํ ์ธ ๋ฅผ ์ ์ฅํ๊ณ ๋ถ๋ฅํ์ธ
kenel.tistory.com
์ ๊ฒ์๊ธ์ ์์ฑ๋ ์ฑ์ ์ผ๋ถ ์์ ํด์, ์๋ฆผ ๋ฉ์์ง ํด๋ฆญ ์์ ๋์์ ๊ตฌํํด๋ณธ๋ค.
#2 PendingIntent
PendingIntent | Android Developers
developer.android.com
Intent๋ ์๋๋ก์ด๋์์ ์ปดํฌ๋ํธ(Activity, Service, BroadcastReceiver, ContentProvider) ๊ฐ ํต์ ์ ์ํด ์ฌ์ฉ๋๋ ๋ฉ์์ง ๊ฐ์ฒด๋ค. PendingIntent๋ ๋์ค์ ์คํ๋ Intent๋ฅผ ํฌ์ฅ(Wrapping)ํ๋ ๊ฐ์ฒด๋ค. ๊ทธ๋ฆฌ๊ณ ์ํ๋ฐ์ ์ฌ๋ผ๊ฐ ์๋ฆผ(Notifications) ๋ฉ์์ง์ PendingIntent๋ฅผ ๋ฌ์์ค ์ ์๋๋ฐ, ๊ทธ๋ ๊ฒ ํจ์ผ๋ก์จ ํด๋น ๋ฉ์์ง๋ฅผ ํด๋ฆญํ ๋์ ๋์์ ๊ตฌํํด์ค ์ ์๋ค. PendingIntent๊ฐ ์๋ค๋ฉด, ์๋ฆผ ๋ฉ์์ง๋ฅผ ํด๋ฆญํด๋ ์๋ฌด๋ฐ ๋ฐ์์ด ์๋ค.
#3 ์ฝ๋ ์์ - Tab behavior
#3-1 ๊ฐ์
์๋ฆผ ๋ง๋ค๊ธฐ | Views | Android Developers
์ด ํ์ด์ง๋ Cloud Translation API๋ฅผ ํตํด ๋ฒ์ญ๋์์ต๋๋ค. ์๋ฆผ ๋ง๋ค๊ธฐ ์ปฌ๋ ์ ์ ์ฌ์ฉํด ์ ๋ฆฌํ๊ธฐ ๋ด ํ๊ฒฝ์ค์ ์ ๊ธฐ์ค์ผ๋ก ์ฝํ ์ธ ๋ฅผ ์ ์ฅํ๊ณ ๋ถ๋ฅํ์ธ์. ์๋ฆผ์ ์ฌ์ฉ ์ค์ด ์๋ ์ฑ์ ์ด๋ฒคํธ์ ๊ด
developer.android.com
์ํ๋ฐ์ ์๋ฆผ ํจ๋์ ํด๋ฆญ(Tab)ํ๋ฉด ๋ฐ์(ํน์ ์กํฐ๋นํฐ๋ก ์ด๋)ํ๊ฒ ๋ง๋ค์ด๋ณธ๋ค.
#3-2 MainActivity.kt ์์
...
class MainActivity : AppCompatActivity() {
...
private val channelId = "com.example.pendingintent.channel1"
private val myRequestCode1 = 12345
override fun onCreate(savedInstanceState: Bundle?) {
...
}
private fun displayNotification() {
val notificationId = ...
val tabBehavior = getSecondActivityPendingIntent()
val notification = NotificationCompat.Builder(this@MainActivity, channelId).apply {
...
setContentIntent(tabBehavior)
}.build()
notificationManager?.notify(notificationId, notification)
}
private fun getSecondActivityPendingIntent(): PendingIntent {
val intent = Intent(this, SecondActivity::class.java)
return PendingIntent.getActivity(
this, myRequestCode1, intent, PendingIntent.FLAG_IMMUTABLE
)
}
...
}
์์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ ํ๋ค. PendingIntent.getActivity()์ ์ฒซ๋ฒ์งธ ์ธ์๋ Context, ๋๋ฒ์งธ ์ธ์๋ ์๋ก ๋ค๋ฅธ PendingIntent๋ฅผ ๋ช
์์ ์ผ๋ก ๊ตฌ๋ถํ๊ธฐ ์ํ Intํ Id๊ฐ (๋๋ ์๋ฌด ์ซ์์ธ 12345๋ฅผ ๋ฃ์๋ค), ์ธ๋ฒ์งธ ์ธ์๋ Intent, ๋ค๋ฒ์งธ ์ธ์๋ PendingIntent์ ์์ฑ์ ์ ์ํ๋ Intํ ์์๋ค. FLAG_IMMUTABLE์ ๋ง์น valํ ๋ณ์์ ๋ถ๋ณ์ (Immutable) ์ฑ๊ฒฉ๊ณผ ๋น์ทํ ๋งฅ๋ฝ์ผ๋ก, ์ ์ฝ๋ ์ PendingIntent์ ์๋ก์ด Intent๋ฅผ ๊ฐ์ง๊ฒ ๋ง๋๋ ๋ฑ์ ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฉํ ์ ์๊ฒ ๋ง๋๋ ํ๋๊ทธ๋ค.
#3-3 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=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SecondActivity"
android:textSize="40dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
๊ฐ๋จํ View.
#3-4 SecondActivity.kt ์์ฑ
// package com.anushka.notificationdemo
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
}
}
๋น์ด์๋ Activity.
#3-5 AndroidMenifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
...
<application
...>
<activity
android:name=".SecondActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
AndroidMenifest.xml์ SecondActivity๋ฅผ ๋ฑ๋กํ๋ค.
#3-6 ์๋ ํ์ธ
๋ง์ฝ ๋ฒํผ์ ๋๋ฌ๋ ์๋ฆผ์ด ๋จ์ง ์๋๋ค๋ฉด, ์ค์น๋ ์ฑ์ ์๋ฆผ ๊ถํ์ด ์ฐจ๋จ๋์ง๋ ์์๋์ง ํ์ธํด๋ณด์. ๊ธฐ๋ณธ๊ฐ ์ค์ ์ด ์ฐจ๋จ์ธ ๊ฒฝ์ฐ๊ฐ ์๋ค.
#4 ์ฝ๋ ์์ - Action Button
#4-1 ๊ฐ์
NotificationCompat.Action | Android Developers
androidx.appsearch.builtintypes.properties
developer.android.com
์ํ๋ฐ์ ์๋ฆผ ํจ๋์ ์ฌ๋ฌ ๊ฐ์ Action Button์ ์ถ๊ฐํ๋ค. ๋ด๋ถ์ ์ธ ์ฝ๋๋ #3๊ณผ ๊ฑฐ์ ๊ฐ๋ค. #3๊ณผ์ ์ฐจ์ด๋ ์๋ฆผ ํจ๋์ ํด๋ฆญ ๊ฐ๋ฅํ ๋ฒํผ์ด ์กด์ฌํ๋ฉฐ, ๊ฐ ๋ฒํผ์ ์๋ก ๋ค๋ฅธ PendingIntent๋ฅผ ๋ฃ์ด ์ค ์ ์๋ค๋ ์ ์ด๋ค.
#4-2 MainActivity.kt ์์
...
class MainActivity : AppCompatActivity() {
...
private val myRequestCode2 = 12346
private val myRequestCode3 = 12347
override fun onCreate(savedInstanceState: Bundle?) {
...
}
private fun displayNotification() {
val notificationId = ...
val tabBehavior = getSecondActivityPendingIntent()
val actionButton1 = getThirdActivityAction()
val actionButton2 = getFourthActivityAction()
val notification = NotificationCompat.Builder(this@MainActivity, channelId).apply {
...
setContentIntent(tabBehavior)
addAction(actionButton1)
addAction(actionButton2)
}.build()
notificationManager?.notify(notificationId, notification)
}
private fun getSecondActivityPendingIntent(): PendingIntent {
...
}
private fun getThirdActivityAction(): NotificationCompat.Action {
val intent = Intent(this, ThirdActivity::class.java)
val pendingIntent: PendingIntent = PendingIntent.getActivity(
this, myRequestCode2, intent, PendingIntent.FLAG_IMMUTABLE
)
return NotificationCompat.Action.Builder(0, "Go Third", pendingIntent).build()
}
private fun getFourthActivityAction(): NotificationCompat.Action {
val intent = Intent(this, FourthActivity::class.java)
val pendingIntent: PendingIntent = PendingIntent.getActivity(
this, myRequestCode3, intent, PendingIntent.FLAG_IMMUTABLE
)
return NotificationCompat.Action.Builder(0, "Go Fourth", pendingIntent).build()
}
...
}
Action ๋ฒํผ์ NotificationCompat.Action์ ๋น๋ ํด๋์ค์ธ NotificationCompat.Action.Builder๋ฅผ ํตํด ๋ง๋ ๋ค. ํด๋น ํด๋์ค ์์ฑ์์ ์ฒซ๋ฒ์งธ ์ธ์๋ ์์ด์ฝ(IconCompat), ๋๋ฒ์งธ ์ธ์๋ Action ๋ฒํผ์ ์ ๋ชฉ, ์ธ๋ฒ์งธ ์ธ์๋ PendingIntent๋ค.
#4-3 ThirdActivity์ FourthActivity ๊ด๋ จ ์ฝ๋
์ฝ๋ ์๋ต
#3-3 ~ #3-5์ ๊ฐ์ ๋ฐฉ์์ผ๋ก, ThirdActivity ๋ฐ FourthActivity ๊ทธ๋ฆฌ๊ณ ๊ฐ๊ฐ์ View๋ฅผ ๋ง๋ ๋ค. AndroidManifest์ ๋ง๋ Activity๋ฅผ ๋ฑ๋กํ๋ ๊ฒ ๋ํ ์์ง ๋ง์.
#4-4 ์๋ ํ์ธ
#4-5 ํ์ํ ๊ฐ์ ์
Action Button์ ํด๋ฆญํด๋, Notification์ด ์ฌ๋ผ์ง์ง ์๋๋ค. Action Button์ด ์๋๋ผ Notification ์์ฒด๋ฅผ Tabํ์ ๋ Notification์ด ์๋ง ์ฌ๋ผ์ง๋ ๊ฒ๊ณผ๋ ๋์กฐ์ ์ด๋ค. ์ด์ด์ง๋ ๊ฒ์๊ธ(#7 ์ฐธ์กฐ)์์ ํด๋น ๋์์ ๊ตฌํํด๋ณธ๋ค.
#5 ์์ฝ
PendingIntent๋ ์ด๋ค ๊ฒ์ ๋งค๋ฌ๊ธฐ(Pend) ์ํ Intent๋ค.
#6 ์์ฑ๋ ์ฑ
android-practice/notifications/PendingIntent at master · Kanmanemone/android-practice
Contribute to Kanmanemone/android-practice development by creating an account on GitHub.
github.com
#7 ์ด์ด์ง๋ ๊ธ
[Android] Notifications - Action ๋ฒํผ ํด๋ฆญ ์ ์๋ฆผ Cancel
#1 ์ด์ ๊ธ [Android] Notifications - PendingIntent#1 ์ด์ ๊ธ [Android] Notifications - ๊ธฐ์ด#1 ๊ฐ์ ์๋ฆผ ๊ฐ์ | Views | Android Developers์ด ํ์ด์ง๋ Cloud Translation API๋ฅผ ํตํด ๋ฒ์ญ๋์์ต๋๋ค. ์๋ฆผ ๊ฐ์ ์ปฌ๋ ์ ์ ์ฌ์ฉ
kenel.tistory.com
'๊นจ์ ๊ฐ๋ ๐ > Android' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android] WorkManager - ๊ฐ์ (0) | 2024.06.14 |
---|---|
[Android] Notifications - Action ๋ฒํผ ํด๋ฆญ ์ ์๋ฆผ Cancel (0) | 2024.06.14 |
[Android] Notifications - ๊ธฐ์ด (0) | 2024.06.12 |
[Android] Retrofit - Post (0) | 2024.06.11 |
[Android] Retrofit - Logging, Timeout ๊ด๋ฆฌ (Interceptor) (0) | 2024.06.11 |