-
Notifications
You must be signed in to change notification settings - Fork 8
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
[AN/USER] feat: fcm 푸시 알림 구현 (#522) #537
Changes from 13 commits
c64d3d0
0e3bff7
a56f8c3
4ca5d96
76eef23
49680d7
c8d18ad
8b52913
5fc6435
13ee204
c31cc5d
18e89c6
7376ead
41668f2
81c666f
3333abc
c2e18c7
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,7 @@ | ||
package com.festago.festago.presentation.fcm | ||
|
||
enum class FcmMessageType(val id: Int, val channelId: String) { | ||
ENTRY_ALERT(id = 0, channelId = "ENTRY_ALERT"), | ||
ENTRY_PROCESS(id = 1, channelId = "ENTRY_PROCESS"), | ||
; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.festago.festago.presentation.fcm | ||
|
||
import android.app.PendingIntent | ||
import android.content.Context | ||
import android.content.Intent | ||
import android.content.pm.PackageManager | ||
import androidx.core.app.ActivityCompat | ||
import androidx.core.app.NotificationCompat | ||
import androidx.core.app.NotificationManagerCompat | ||
import com.festago.festago.R | ||
import com.festago.festago.presentation.fcm.FcmMessageType.ENTRY_ALERT | ||
import com.festago.festago.presentation.ui.home.HomeActivity | ||
|
||
class NotificationManager(private val context: Context) { | ||
|
||
private val intent = HomeActivity.getIntent(context).apply { | ||
flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK | ||
} | ||
|
||
private val pendingIntent = PendingIntent.getActivity( | ||
context, | ||
HOME_REQUEST_CODE, | ||
intent, | ||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT | ||
) | ||
|
||
private val entryAlertNotificationBuilder = | ||
NotificationCompat.Builder(context, ENTRY_ALERT.channelId) | ||
.setSmallIcon(R.mipmap.ic_festago_logo_round) | ||
.setPriority(NotificationCompat.PRIORITY_DEFAULT) | ||
.setAutoCancel(true) | ||
.setContentIntent(pendingIntent) | ||
|
||
fun sendEntryAlertNotification(title: String, body: String) { | ||
entryAlertNotificationBuilder | ||
.setContentTitle(title) | ||
.setContentText(body) | ||
|
||
if (ActivityCompat.checkSelfPermission( | ||
context, | ||
android.Manifest.permission.POST_NOTIFICATIONS | ||
) == PackageManager.PERMISSION_GRANTED | ||
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. 이부분도 PermissionUtil안에서 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. 반영완료! |
||
) { | ||
NotificationManagerCompat.from(context).notify(0, entryAlertNotificationBuilder.build()) | ||
} | ||
} | ||
|
||
companion object { | ||
private const val HOME_REQUEST_CODE = 0 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.festago.festago.presentation.fcm | ||
|
||
import com.festago.festago.presentation.fcm.FcmMessageType.ENTRY_ALERT | ||
import com.festago.festago.presentation.fcm.FcmMessageType.ENTRY_PROCESS | ||
import com.google.firebase.messaging.FirebaseMessagingService | ||
import com.google.firebase.messaging.RemoteMessage | ||
import kotlinx.coroutines.flow.MutableSharedFlow | ||
import kotlinx.coroutines.runBlocking | ||
|
||
class TicketEntryService : FirebaseMessagingService() { | ||
|
||
private val notificationManager by lazy { NotificationManager(this) } | ||
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. Firebase Service 도 힐트로 주입할 수 있나요? |
||
|
||
override fun onMessageReceived(remoteMessage: RemoteMessage) { | ||
when (remoteMessage.notification?.channelId) { | ||
ENTRY_ALERT.channelId -> handleEntryAlert(remoteMessage) | ||
|
||
ENTRY_PROCESS.channelId -> { | ||
runBlocking { | ||
ticketStateChangeEvent.emit(Unit) | ||
} | ||
} | ||
|
||
else -> Unit | ||
} | ||
} | ||
|
||
private fun handleEntryAlert(remoteMessage: RemoteMessage) { | ||
notificationManager.sendEntryAlertNotification( | ||
remoteMessage.notification?.title ?: "", | ||
remoteMessage.notification?.body ?: "" | ||
) | ||
} | ||
|
||
override fun onNewToken(token: String) { | ||
// TODO: 토큰이 변경되었을 때 처리 | ||
} | ||
|
||
companion object { | ||
val ticketStateChangeEvent: MutableSharedFlow<Unit> = MutableSharedFlow() | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ package com.festago.festago.presentation.ui.home | |
import android.content.Context | ||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.widget.Toast | ||
import androidx.activity.result.contract.ActivityResultContracts | ||
import androidx.activity.viewModels | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.fragment.app.Fragment | ||
|
@@ -13,6 +15,7 @@ import com.festago.festago.presentation.ui.home.mypage.MyPageFragment | |
import com.festago.festago.presentation.ui.home.ticketlist.TicketListFragment | ||
import com.festago.festago.presentation.ui.signin.SignInActivity | ||
import com.festago.festago.presentation.util.repeatOnStarted | ||
import com.festago.festago.presentation.util.requestNotificationPermission | ||
import dagger.hilt.android.AndroidEntryPoint | ||
|
||
@AndroidEntryPoint | ||
|
@@ -23,11 +26,24 @@ class HomeActivity : AppCompatActivity() { | |
|
||
private val vm: HomeViewModel by viewModels() | ||
|
||
private val requestPermissionLauncher = registerForActivityResult( | ||
ActivityResultContracts.RequestPermission(), | ||
) { isGranted: Boolean -> | ||
if (!isGranted) { | ||
Toast.makeText( | ||
this, | ||
getString(R.string.home_notification_permission_denied), | ||
Toast.LENGTH_SHORT | ||
).show() | ||
} | ||
} | ||
|
||
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. 이 부분도 함수로 분리할 수 있지 않을까요? 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 onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
initBinding() | ||
initView() | ||
initObserve() | ||
requestNotificationPermission(requestPermissionLauncher) | ||
} | ||
|
||
private fun initBinding() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.festago.festago.presentation.util | ||
|
||
import android.Manifest.permission.POST_NOTIFICATIONS | ||
import android.app.Activity | ||
import android.content.pm.PackageManager.PERMISSION_GRANTED | ||
import android.os.Build | ||
import androidx.activity.result.ActivityResultLauncher | ||
import androidx.core.content.ContextCompat | ||
|
||
fun Activity.requestNotificationPermission(resultLauncher: ActivityResultLauncher<String>) { | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | ||
if (ContextCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED) { | ||
resultLauncher.launch(POST_NOTIFICATIONS) | ||
} | ||
} | ||
} |
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.
entryAlertNotificationBuilder 를 초기화하기 위해서만 필요한 것 같아요!
프로퍼티로 있는 이유가 있을까요?
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.
아까 논의한대로 프로퍼티로 가지고 있을 필요는 없지만 싱글톤으로 관리하기 위해서 이대로 둘게요!