-
Notifications
You must be signed in to change notification settings - Fork 0
feat: 푸시 알림 클라이언트 로직 구현 및 서버 API 연동 #204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
46a039f
574e36c
f264a63
48835f4
d612f6b
fa6ff4a
e31938e
d858e13
3160f5d
5105ac1
78ec9c4
cebcb31
4d4f40f
4e75d7f
a407c12
2ce8b80
3f06f9c
a9bd7e6
fc249ab
7dec07a
f05cad2
70770ed
c2d6c92
651c7df
1e0795b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,93 @@ | ||||||||||||||
| package com.ninecraft.booket | ||||||||||||||
|
|
||||||||||||||
| import android.app.NotificationChannel | ||||||||||||||
| import android.app.NotificationManager | ||||||||||||||
| import android.app.PendingIntent | ||||||||||||||
| import android.content.Context | ||||||||||||||
| import android.content.Intent | ||||||||||||||
| import androidx.core.app.NotificationCompat | ||||||||||||||
| import androidx.core.content.ContextCompat | ||||||||||||||
| import com.google.firebase.messaging.FirebaseMessagingService | ||||||||||||||
| import com.google.firebase.messaging.RemoteMessage | ||||||||||||||
| import com.ninecraft.booket.core.data.api.repository.UserRepository | ||||||||||||||
| import com.ninecraft.booket.core.designsystem.R | ||||||||||||||
| import com.ninecraft.booket.feature.main.MainActivity | ||||||||||||||
| import dagger.hilt.android.AndroidEntryPoint | ||||||||||||||
| import kotlinx.coroutines.CoroutineScope | ||||||||||||||
| import kotlinx.coroutines.Dispatchers | ||||||||||||||
| import kotlinx.coroutines.SupervisorJob | ||||||||||||||
| import kotlinx.coroutines.cancel | ||||||||||||||
| import kotlinx.coroutines.launch | ||||||||||||||
| import javax.inject.Inject | ||||||||||||||
|
|
||||||||||||||
| @AndroidEntryPoint | ||||||||||||||
| class ReedFirebaseMessagingService : FirebaseMessagingService() { | ||||||||||||||
|
|
||||||||||||||
| @Inject | ||||||||||||||
| lateinit var userRepository: UserRepository | ||||||||||||||
|
|
||||||||||||||
| private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) | ||||||||||||||
|
|
||||||||||||||
| override fun onNewToken(token: String) { | ||||||||||||||
| super.onNewToken(token) | ||||||||||||||
|
|
||||||||||||||
| scope.launch { | ||||||||||||||
| userRepository.syncFcmToken(token) | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| override fun onMessageReceived(message: RemoteMessage) { | ||||||||||||||
| super.onMessageReceived(message) | ||||||||||||||
|
|
||||||||||||||
| val title = message.notification?.title ?: "Reed" | ||||||||||||||
| val body = message.notification?.body ?: "" | ||||||||||||||
|
|
||||||||||||||
| val intent = Intent(this, MainActivity::class.java).apply { | ||||||||||||||
| flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| val pendingIntent = PendingIntent.getActivity( | ||||||||||||||
| this, | ||||||||||||||
| 0, | ||||||||||||||
| intent, | ||||||||||||||
| PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| val builder = NotificationCompat.Builder(this, REED_CHANNEL_ID) | ||||||||||||||
| .setSmallIcon(R.drawable.ic_notification) | ||||||||||||||
| .setColor(ContextCompat.getColor(this, R.color.green_500)) | ||||||||||||||
| .setContentTitle(title) | ||||||||||||||
| .setContentText(body) | ||||||||||||||
| .setContentIntent(pendingIntent) | ||||||||||||||
| .setAutoCancel(true) | ||||||||||||||
| .setPriority(NotificationCompat.PRIORITY_DEFAULT) | ||||||||||||||
|
|
||||||||||||||
| val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager | ||||||||||||||
| manager.notify(System.currentTimeMillis().toInt(), builder.build()) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| override fun onDestroy() { | ||||||||||||||
| scope.cancel() | ||||||||||||||
|
easyhooon marked this conversation as resolved.
|
||||||||||||||
| super.onDestroy() | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| companion object { | ||||||||||||||
| private const val REED_CHANNEL_ID = "REED_PUSH_CHANNEL" | ||||||||||||||
| private const val REED_CHANNEL_NAME = "리드 푸시 알림" | ||||||||||||||
| private const val REED_CHANNEL_DESC = "리드 앱에서 보내는 푸시 알림을 관리합니다." | ||||||||||||||
|
|
||||||||||||||
| // Android 8.0 이상 필수 채널 생성 | ||||||||||||||
| fun createNotificationChannel(context: Context) { | ||||||||||||||
| val channel = NotificationChannel( | ||||||||||||||
| REED_CHANNEL_ID, | ||||||||||||||
| REED_CHANNEL_NAME, | ||||||||||||||
| NotificationManager.IMPORTANCE_DEFAULT, | ||||||||||||||
| ).apply { | ||||||||||||||
| description = REED_CHANNEL_DESC | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| val manager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager | ||||||||||||||
| manager.createNotificationChannel(channel) | ||||||||||||||
| } | ||||||||||||||
|
seoyoon513 marked this conversation as resolved.
Comment on lines
+89
to
+91
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 컴파일 에러: NOTIFICATION_SERVICE 미수입 사용
- val manager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
+ val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.ninecraft.booket.initializer | ||
|
|
||
| import android.content.Context | ||
| import androidx.startup.Initializer | ||
| import com.ninecraft.booket.ReedFirebaseMessagingService.Companion.createNotificationChannel | ||
|
|
||
| class NotificationChannelInitializer : Initializer<Unit> { | ||
|
|
||
| override fun create(context: Context) { | ||
| createNotificationChannel(context) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오.. 이런 방식이 가능하군여 👍 |
||
| } | ||
|
|
||
| override fun dependencies(): List<Class<out Initializer<*>>> { | ||
| return emptyList() | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
smallIcon 관련 문서
해당 아이콘으로 기존 런처 아이콘이 아닌 notification 전용 벡터 아이콘으로 만들어서 넣어줬는데요, 기존에 런처 아이콘과 동일한 아이콘을 사용할 경우(mipmap/ic_launcher) 기기 OS 별로 다르게 노출되기 때문입니다.
[에뮬레이터 Pixel 기종]

[갤럭시 S21]

따라서 statusBar 등에 노출되는 알림용 아이콘의 통일성을 위해, 흰색 단색 로고 'r'만 남긴 알림 전용 아이콘 (ic_notification)으로 적용했습니다.
[에뮬레이터 Pixel 기종]


[갤럭시 S21]
