11package com.terning.core.firebase.messageservice
22
3+ import android.app.ActivityManager
34import android.app.NotificationChannel
45import android.app.NotificationManager
56import android.app.PendingIntent
7+ import android.content.Context
68import android.content.Intent
79import androidx.core.app.NotificationCompat
8- import androidx.core.app.NotificationManagerCompat
910import androidx.core.content.getSystemService
1011import androidx.core.net.toUri
12+ import coil3.BitmapImage
13+ import coil3.ImageLoader
14+ import coil3.request.ImageRequest
1115import com.google.firebase.messaging.FirebaseMessagingService
1216import com.google.firebase.messaging.RemoteMessage
17+ import com.terning.core.designsystem.type.NotificationRedirect
18+ import com.terning.core.designsystem.util.DeeplinkDefaults
19+ import com.terning.core.designsystem.util.DeeplinkDefaults.REDIRECT
1320import com.terning.core.firebase.R
1421import com.terning.domain.user.repository.UserRepository
1522import com.terning.navigator.NavigatorProvider
@@ -36,44 +43,53 @@ class TerningMessagingService : FirebaseMessagingService() {
3643 override fun handleIntent (intent : Intent ? ) {
3744 super .handleIntent(intent)
3845
39- if (intent?.getStringExtra(TITLE )?.isEmpty() == true
40- || ! userRepository.getAlarmAvailable()
41- ) return
42-
43- val title = intent?.getStringExtra(TITLE ).orEmpty()
44- val body = intent?.getStringExtra(BODY ).orEmpty()
45- val type = intent?.getStringExtra(TYPE ).orEmpty()
46-
47- sendNotification(
48- title = title,
49- body = body,
50- type = type
46+ extractInformation(
47+ title = intent?.getStringExtra(TITLE ),
48+ body = intent?.getStringExtra(BODY ),
49+ type = intent?.getStringExtra(TYPE ),
50+ imageUrl = intent?.getStringExtra(IMAGE_URL )
5151 )
5252 }
5353
5454 override fun onMessageReceived (message : RemoteMessage ) {
5555 super .onMessageReceived(message)
5656
57- if (message.data.isEmpty()
58- || ! userRepository.getAlarmAvailable()
59- ) return
57+ extractInformation(
58+ title = message.data[TITLE ],
59+ body = message.data[BODY ],
60+ type = message.data[TYPE ],
61+ imageUrl = message.data[IMAGE_URL ]
62+ )
63+ }
6064
61- val title = message.data[TITLE ].orEmpty()
62- val body = message.data[BODY ].orEmpty()
63- val type = message.data[TYPE ].orEmpty()
65+ private fun extractInformation (
66+ title : String? ,
67+ body : String? ,
68+ type : String? ,
69+ imageUrl : String?
70+ ) {
71+ if (title.isNullOrEmpty() || ! userRepository.getAlarmAvailable()) return
6472
6573 sendNotification(
6674 title = title,
67- body = body,
68- type = type
75+ body = body.orEmpty(),
76+ type = type.orEmpty(),
77+ imageUrl = imageUrl.orEmpty()
6978 )
7079 }
7180
72- private fun sendNotification (title : String , body : String , type : String ) {
81+ private fun sendNotification (
82+ title : String ,
83+ body : String ,
84+ type : String ,
85+ imageUrl : String
86+ ) {
7387 val notifyId = Random ().nextInt()
74- val intent = navigatorProvider.getMainActivityIntent(deeplink = type).apply {
88+ val isForeground = isAppInForeground()
89+ val deeplink = buildDeeplink(type, isForeground)
90+ val intent = navigatorProvider.getMainActivityIntent(deeplink = deeplink).apply {
7591 action = Intent .ACTION_VIEW
76- data = type .toUri()
92+ data = deeplink .toUri()
7793 flags = Intent .FLAG_ACTIVITY_NEW_TASK or Intent .FLAG_ACTIVITY_CLEAR_TOP
7894 }
7995 val pendingIntent = PendingIntent .getActivity(
@@ -82,32 +98,66 @@ class TerningMessagingService : FirebaseMessagingService() {
8298 intent,
8399 PendingIntent .FLAG_ONE_SHOT or PendingIntent .FLAG_MUTABLE
84100 )
85- val channelId: String = CHANNEL_ID
86101 val notificationBuilder =
87- NotificationCompat .Builder (this , channelId ).apply {
102+ NotificationCompat .Builder (this , CHANNEL_ID ).apply {
88103 setSmallIcon(R .mipmap.ic_terning_launcher)
89104 setContentTitle(title)
90105 setContentText(body)
91- setPriority(NotificationManagerCompat .IMPORTANCE_HIGH )
106+ setAutoCancel(true )
107+ setPriority(NotificationCompat .PRIORITY_HIGH )
92108 setContentIntent(pendingIntent)
93109 }
94-
95- getSystemService<NotificationManager >()?.run {
96- createNotificationChannel(
97- NotificationChannel (
98- channelId,
99- channelId,
100- NotificationManager .IMPORTANCE_HIGH ,
101- ),
110+ val notificationManager = getSystemService<NotificationManager >()
111+ notificationManager?.createNotificationChannel(
112+ NotificationChannel (
113+ CHANNEL_ID ,
114+ CHANNEL_ID ,
115+ NotificationManager .IMPORTANCE_HIGH
102116 )
103- notify(notifyId, notificationBuilder.build())
104- }
117+ )
118+ val imageLoader = ImageLoader (this )
119+ val request = ImageRequest .Builder (this )
120+ .data(imageUrl)
121+ .target(
122+ onSuccess = { image ->
123+ val bitmap = (image as BitmapImage ).bitmap
124+ notificationBuilder.setLargeIcon(bitmap)
125+ notificationManager?.notify(notifyId, notificationBuilder.build())
126+ },
127+ onError = {
128+ notificationManager?.notify(notifyId, notificationBuilder.build())
129+ }
130+ )
131+ .build()
132+
133+ imageLoader.enqueue(request)
134+ }
135+
136+ private fun isAppInForeground (): Boolean {
137+ val appProcesses =
138+ (getSystemService(Context .ACTIVITY_SERVICE ) as ActivityManager ).runningAppProcesses
139+
140+ return appProcesses?.any {
141+ val isForeground =
142+ it.importance == ActivityManager .RunningAppProcessInfo .IMPORTANCE_FOREGROUND
143+ val isCurrentApp = it.processName == packageName
144+
145+ isForeground && isCurrentApp
146+ } == true
147+ }
148+
149+ private fun buildDeeplink (type : String , isForeground : Boolean ): String {
150+ val base = NotificationRedirect .from(type) ? : return " "
151+
152+ return if (isForeground) DeeplinkDefaults .build(base.path)
153+ else DeeplinkDefaults .build(" splash?$REDIRECT =${base.path} " )
105154 }
106155
107156 companion object {
108157 private const val CHANNEL_ID : String = " terning"
109158 private const val TITLE : String = " title"
110159 private const val BODY : String = " body"
111160 private const val TYPE : String = " type"
161+ private const val IMAGE_URL : String = " imageUrl"
112162 }
113- }
163+ }
0 commit comments