Send messages via intent; Broadcast received messages
This commit is contained in:
parent
c163e6e96e
commit
323e013391
10 changed files with 144 additions and 23 deletions
|
@ -3,6 +3,7 @@
|
||||||
package="io.heckel.ntfy">
|
package="io.heckel.ntfy">
|
||||||
<!--
|
<!--
|
||||||
Permissions
|
Permissions
|
||||||
|
- INTERNET is needed because we need to talk to the ntfy server(s)
|
||||||
- FOREGROUND_SERVICE is needed to support "use another server" feature
|
- FOREGROUND_SERVICE is needed to support "use another server" feature
|
||||||
- WAKE_LOCK & RECEIVE_BOOT_COMPLETED are required to restart the foreground service
|
- WAKE_LOCK & RECEIVE_BOOT_COMPLETED are required to restart the foreground service
|
||||||
if it is stopped; see https://robertohuertas.com/2019/06/29/android_foreground_services/
|
if it is stopped; see https://robertohuertas.com/2019/06/29/android_foreground_services/
|
||||||
|
@ -56,14 +57,20 @@
|
||||||
<service android:name=".msg.SubscriberService"/>
|
<service android:name=".msg.SubscriberService"/>
|
||||||
|
|
||||||
<!-- Subscriber service restart on reboot -->
|
<!-- Subscriber service restart on reboot -->
|
||||||
<receiver
|
<receiver android:name=".msg.SubscriberService$StartReceiver" android:enabled="true">
|
||||||
android:name=".msg.SubscriberService$StartReceiver"
|
|
||||||
android:enabled="true">
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<!-- Broadcast receiver to send messages via intents -->
|
||||||
|
<receiver android:name=".msg.BroadcastService$BroadcastReceiver" android:enabled="true" android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="io.heckel.ntfy.SEND_MESSAGE"/>
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
|
||||||
<!-- Firebase messaging (note that this is empty in the F-Droid flavor) -->
|
<!-- Firebase messaging (note that this is empty in the F-Droid flavor) -->
|
||||||
<service
|
<service
|
||||||
android:name=".firebase.FirebaseService"
|
android:name=".firebase.FirebaseService"
|
||||||
|
|
|
@ -85,19 +85,16 @@ class Repository(private val sharedPrefs: SharedPreferences, private val subscri
|
||||||
|
|
||||||
@Suppress("RedundantSuspendModifier")
|
@Suppress("RedundantSuspendModifier")
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
suspend fun addNotification(notification: Notification): Boolean {
|
suspend fun addNotification(notification: Notification): NotificationAddResult {
|
||||||
val maybeExistingNotification = notificationDao.get(notification.id)
|
val maybeExistingNotification = notificationDao.get(notification.id)
|
||||||
if (maybeExistingNotification == null) {
|
if (maybeExistingNotification == null) {
|
||||||
notificationDao.add(notification)
|
notificationDao.add(notification)
|
||||||
return shouldNotify(notification)
|
val detailsVisible = detailViewSubscriptionId.get() == notification.subscriptionId
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun shouldNotify(notification: Notification): Boolean {
|
|
||||||
val detailViewOpen = detailViewSubscriptionId.get() == notification.subscriptionId
|
|
||||||
val muted = isMuted(notification.subscriptionId)
|
val muted = isMuted(notification.subscriptionId)
|
||||||
return !detailViewOpen && !muted
|
val notify = !detailsVisible && !muted
|
||||||
|
return NotificationAddResult(notify = notify, broadcast = true, muted = muted)
|
||||||
|
}
|
||||||
|
return NotificationAddResult(notify = false, broadcast = false, muted = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("RedundantSuspendModifier")
|
@Suppress("RedundantSuspendModifier")
|
||||||
|
@ -217,6 +214,12 @@ class Repository(private val sharedPrefs: SharedPreferences, private val subscri
|
||||||
return connectionStatesLiveData.value!!.getOrElse(subscriptionId) { ConnectionState.NOT_APPLICABLE }
|
return connectionStatesLiveData.value!!.getOrElse(subscriptionId) { ConnectionState.NOT_APPLICABLE }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class NotificationAddResult(
|
||||||
|
val notify: Boolean,
|
||||||
|
val broadcast: Boolean,
|
||||||
|
val muted: Boolean,
|
||||||
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val SHARED_PREFS_ID = "MainPreferences"
|
const val SHARED_PREFS_ID = "MainPreferences"
|
||||||
const val SHARED_PREFS_POLL_WORKER_VERSION = "PollWorkerVersion"
|
const val SHARED_PREFS_POLL_WORKER_VERSION = "PollWorkerVersion"
|
||||||
|
|
|
@ -28,20 +28,25 @@ class ApiService {
|
||||||
.readTimeout(77, TimeUnit.SECONDS) // Assuming that keepalive messages are more frequent than this
|
.readTimeout(77, TimeUnit.SECONDS) // Assuming that keepalive messages are more frequent than this
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
fun publish(baseUrl: String, topic: String, message: String, title: String, priority: Int, tags: List<String>) {
|
fun publish(baseUrl: String, topic: String, message: String, title: String, priority: Int, tags: List<String>, delay: String) {
|
||||||
val url = topicUrl(baseUrl, topic)
|
val url = topicUrl(baseUrl, topic)
|
||||||
Log.d(TAG, "Publishing to $url")
|
Log.d(TAG, "Publishing to $url")
|
||||||
|
|
||||||
var builder = Request.Builder()
|
var builder = Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.addHeader("X-Priority", priority.toString())
|
|
||||||
.put(message.toRequestBody())
|
.put(message.toRequestBody())
|
||||||
|
if (priority in 1..5) {
|
||||||
|
builder = builder.addHeader("X-Priority", priority.toString())
|
||||||
|
}
|
||||||
if (tags.isNotEmpty()) {
|
if (tags.isNotEmpty()) {
|
||||||
builder = builder.addHeader("X-Tags", tags.joinToString(","))
|
builder = builder.addHeader("X-Tags", tags.joinToString(","))
|
||||||
}
|
}
|
||||||
if (title.isNotEmpty()) {
|
if (title.isNotEmpty()) {
|
||||||
builder = builder.addHeader("X-Title", title)
|
builder = builder.addHeader("X-Title", title)
|
||||||
}
|
}
|
||||||
|
if (delay.isNotEmpty()) {
|
||||||
|
builder = builder.addHeader("X-Delay", delay)
|
||||||
|
}
|
||||||
client.newCall(builder.build()).execute().use { response ->
|
client.newCall(builder.build()).execute().use { response ->
|
||||||
if (!response.isSuccessful) {
|
if (!response.isSuccessful) {
|
||||||
throw Exception("Unexpected response ${response.code} when publishing to $url")
|
throw Exception("Unexpected response ${response.code} when publishing to $url")
|
||||||
|
|
80
app/src/main/java/io/heckel/ntfy/msg/BroadcastService.kt
Normal file
80
app/src/main/java/io/heckel/ntfy/msg/BroadcastService.kt
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
package io.heckel.ntfy.msg
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.util.Log
|
||||||
|
import io.heckel.ntfy.R
|
||||||
|
import io.heckel.ntfy.data.Notification
|
||||||
|
import io.heckel.ntfy.data.Subscription
|
||||||
|
import io.heckel.ntfy.util.joinTagsMap
|
||||||
|
import io.heckel.ntfy.util.splitTags
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class BroadcastService(private val ctx: Context) {
|
||||||
|
fun send(subscription: Subscription, notification: Notification, muted: Boolean) {
|
||||||
|
val intent = Intent()
|
||||||
|
intent.action = MESSAGE_RECEIVED_ACTION
|
||||||
|
intent.putExtra("id", notification.id)
|
||||||
|
intent.putExtra("base_url", subscription.baseUrl)
|
||||||
|
intent.putExtra("topic", subscription.topic)
|
||||||
|
intent.putExtra("title", notification.title)
|
||||||
|
intent.putExtra("message", notification.message)
|
||||||
|
intent.putExtra("tags", notification.tags)
|
||||||
|
intent.putExtra("tags_map", joinTagsMap(splitTags(notification.tags)))
|
||||||
|
intent.putExtra("priority", notification.priority)
|
||||||
|
intent.putExtra("muted", muted)
|
||||||
|
|
||||||
|
Log.d(TAG, "Sending intent broadcast: $intent")
|
||||||
|
ctx.sendBroadcast(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
class BroadcastReceiver : android.content.BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
Log.d(TAG, "Broadcast received: $intent")
|
||||||
|
when (intent.action) {
|
||||||
|
MESSAGE_SEND_ACTION -> send(context, intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun send(ctx: Context, intent: Intent) {
|
||||||
|
val api = ApiService()
|
||||||
|
val topic = intent.getStringExtra("topic") ?: return
|
||||||
|
val message = intent.getStringExtra("message") ?: return
|
||||||
|
val baseUrl = intent.getStringExtra("base_url") ?: ctx.getString(R.string.app_base_url)
|
||||||
|
val title = intent.getStringExtra("title") ?: ""
|
||||||
|
val tags = intent.getStringExtra("tags") ?: ""
|
||||||
|
val priority = if (intent.getStringExtra("priority") != null) {
|
||||||
|
when (intent.getStringExtra("priority")) {
|
||||||
|
"min", "1" -> 1
|
||||||
|
"low", "2" -> 2
|
||||||
|
"default", "3" -> 3
|
||||||
|
"high", "4" -> 4
|
||||||
|
"urgent", "max", "5" -> 5
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
intent.getIntExtra("priority", 0)
|
||||||
|
}
|
||||||
|
val delay = intent.getStringExtra("delay") ?: ""
|
||||||
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
api.publish(
|
||||||
|
baseUrl = baseUrl,
|
||||||
|
topic = topic,
|
||||||
|
message = message,
|
||||||
|
title = title,
|
||||||
|
priority = priority,
|
||||||
|
tags = splitTags(tags),
|
||||||
|
delay = delay
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "NtfyBroadcastService"
|
||||||
|
private const val MESSAGE_RECEIVED_ACTION = "io.heckel.ntfy.MESSAGE_RECEIVED"
|
||||||
|
private const val MESSAGE_SEND_ACTION = "io.heckel.ntfy.SEND_MESSAGE" // If changed, change in manifest too!
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ class SubscriberService : Service() {
|
||||||
private val connections = ConcurrentHashMap<String, SubscriberConnection>() // Base URL -> Connection
|
private val connections = ConcurrentHashMap<String, SubscriberConnection>() // Base URL -> Connection
|
||||||
private val api = ApiService()
|
private val api = ApiService()
|
||||||
private val notifier = NotificationService(this)
|
private val notifier = NotificationService(this)
|
||||||
|
private val broadcaster = BroadcastService(this)
|
||||||
private var notificationManager: NotificationManager? = null
|
private var notificationManager: NotificationManager? = null
|
||||||
private var serviceNotification: Notification? = null
|
private var serviceNotification: Notification? = null
|
||||||
|
|
||||||
|
@ -175,11 +176,15 @@ class SubscriberService : Service() {
|
||||||
val url = topicUrl(subscription.baseUrl, subscription.topic)
|
val url = topicUrl(subscription.baseUrl, subscription.topic)
|
||||||
Log.d(TAG, "[$url] Received notification: $n")
|
Log.d(TAG, "[$url] Received notification: $n")
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
val shouldNotify = repository.addNotification(n)
|
val result = repository.addNotification(n)
|
||||||
if (shouldNotify) {
|
if (result.notify) {
|
||||||
Log.d(TAG, "[$url] Showing notification: $n")
|
Log.d(TAG, "[$url] Showing notification: $n")
|
||||||
notifier.send(subscription, n)
|
notifier.send(subscription, n)
|
||||||
}
|
}
|
||||||
|
if (result.broadcast) {
|
||||||
|
Log.d(TAG, "[$url] Broadcasting notification: $n")
|
||||||
|
broadcaster.send(subscription, n, result.muted)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -334,7 +334,7 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
|
||||||
val tags = possibleTags.shuffled().take(Random.nextInt(0, 4))
|
val tags = possibleTags.shuffled().take(Random.nextInt(0, 4))
|
||||||
val title = if (Random.nextBoolean()) getString(R.string.detail_test_title) else ""
|
val title = if (Random.nextBoolean()) getString(R.string.detail_test_title) else ""
|
||||||
val message = getString(R.string.detail_test_message, priority)
|
val message = getString(R.string.detail_test_message, priority)
|
||||||
api.publish(subscriptionBaseUrl, subscriptionTopic, message, title, priority, tags)
|
api.publish(subscriptionBaseUrl, subscriptionTopic, message, title, priority, tags, delay = "")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
Toast
|
Toast
|
||||||
|
|
|
@ -27,6 +27,7 @@ import io.heckel.ntfy.msg.ApiService
|
||||||
import io.heckel.ntfy.msg.NotificationService
|
import io.heckel.ntfy.msg.NotificationService
|
||||||
import io.heckel.ntfy.work.PollWorker
|
import io.heckel.ntfy.work.PollWorker
|
||||||
import io.heckel.ntfy.firebase.FirebaseMessenger
|
import io.heckel.ntfy.firebase.FirebaseMessenger
|
||||||
|
import io.heckel.ntfy.msg.BroadcastService
|
||||||
import io.heckel.ntfy.util.fadeStatusBarColor
|
import io.heckel.ntfy.util.fadeStatusBarColor
|
||||||
import io.heckel.ntfy.util.formatDateShort
|
import io.heckel.ntfy.util.formatDateShort
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -56,6 +57,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
||||||
private var actionMode: ActionMode? = null
|
private var actionMode: ActionMode? = null
|
||||||
private var workManager: WorkManager? = null // Context-dependent
|
private var workManager: WorkManager? = null // Context-dependent
|
||||||
private var notifier: NotificationService? = null // Context-dependent
|
private var notifier: NotificationService? = null // Context-dependent
|
||||||
|
private var broadcaster: BroadcastService? = null // Context-dependent
|
||||||
private var subscriberManager: SubscriberManager? = null // Context-dependent
|
private var subscriberManager: SubscriberManager? = null // Context-dependent
|
||||||
private var appBaseUrl: String? = null // Context-dependent
|
private var appBaseUrl: String? = null // Context-dependent
|
||||||
|
|
||||||
|
@ -68,6 +70,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
||||||
// Dependencies that depend on Context
|
// Dependencies that depend on Context
|
||||||
workManager = WorkManager.getInstance(this)
|
workManager = WorkManager.getInstance(this)
|
||||||
notifier = NotificationService(this)
|
notifier = NotificationService(this)
|
||||||
|
broadcaster = BroadcastService(this)
|
||||||
subscriberManager = SubscriberManager(this)
|
subscriberManager = SubscriberManager(this)
|
||||||
appBaseUrl = getString(R.string.app_base_url)
|
appBaseUrl = getString(R.string.app_base_url)
|
||||||
|
|
||||||
|
@ -315,10 +318,13 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
||||||
newNotifications.forEach { notification ->
|
newNotifications.forEach { notification ->
|
||||||
newNotificationsCount++
|
newNotificationsCount++
|
||||||
val notificationWithId = notification.copy(notificationId = Random.nextInt())
|
val notificationWithId = notification.copy(notificationId = Random.nextInt())
|
||||||
val shouldNotify = repository.addNotification(notificationWithId)
|
val result = repository.addNotification(notificationWithId)
|
||||||
if (shouldNotify) {
|
if (result.notify) {
|
||||||
notifier?.send(subscription, notificationWithId)
|
notifier?.send(subscription, notificationWithId)
|
||||||
}
|
}
|
||||||
|
if (result.broadcast) {
|
||||||
|
broadcaster?.send(subscription, notification, result.muted)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val toastMessage = if (newNotificationsCount == 0) {
|
val toastMessage = if (newNotificationsCount == 0) {
|
||||||
|
|
|
@ -30,6 +30,10 @@ fun joinTags(tags: List<String>?): String {
|
||||||
return tags?.joinToString(",") ?: ""
|
return tags?.joinToString(",") ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun joinTagsMap(tags: List<String>?): String {
|
||||||
|
return tags?.mapIndexed { i, tag -> { "${i+1}=${tag}" }}?.joinToString(",") ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
fun splitTags(tags: String?): List<String> {
|
fun splitTags(tags: String?): List<String> {
|
||||||
return if (tags == null || tags == "") {
|
return if (tags == null || tags == "") {
|
||||||
emptyList()
|
emptyList()
|
||||||
|
|
|
@ -8,6 +8,7 @@ import io.heckel.ntfy.BuildConfig
|
||||||
import io.heckel.ntfy.data.Database
|
import io.heckel.ntfy.data.Database
|
||||||
import io.heckel.ntfy.data.Repository
|
import io.heckel.ntfy.data.Repository
|
||||||
import io.heckel.ntfy.msg.ApiService
|
import io.heckel.ntfy.msg.ApiService
|
||||||
|
import io.heckel.ntfy.msg.BroadcastService
|
||||||
import io.heckel.ntfy.msg.NotificationService
|
import io.heckel.ntfy.msg.NotificationService
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -25,6 +26,7 @@ class PollWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx,
|
||||||
val sharedPrefs = applicationContext.getSharedPreferences(Repository.SHARED_PREFS_ID, Context.MODE_PRIVATE)
|
val sharedPrefs = applicationContext.getSharedPreferences(Repository.SHARED_PREFS_ID, Context.MODE_PRIVATE)
|
||||||
val repository = Repository.getInstance(sharedPrefs, database.subscriptionDao(), database.notificationDao())
|
val repository = Repository.getInstance(sharedPrefs, database.subscriptionDao(), database.notificationDao())
|
||||||
val notifier = NotificationService(applicationContext)
|
val notifier = NotificationService(applicationContext)
|
||||||
|
val broadcaster = BroadcastService(applicationContext)
|
||||||
val api = ApiService()
|
val api = ApiService()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -34,10 +36,13 @@ class PollWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx,
|
||||||
.onlyNewNotifications(subscription.id, notifications)
|
.onlyNewNotifications(subscription.id, notifications)
|
||||||
.map { it.copy(notificationId = Random.nextInt()) }
|
.map { it.copy(notificationId = Random.nextInt()) }
|
||||||
newNotifications.forEach { notification ->
|
newNotifications.forEach { notification ->
|
||||||
val shouldNotify = repository.addNotification(notification)
|
val result = repository.addNotification(notification)
|
||||||
if (shouldNotify) {
|
if (result.notify) {
|
||||||
notifier.send(subscription, notification)
|
notifier.send(subscription, notification)
|
||||||
}
|
}
|
||||||
|
if (result.broadcast) {
|
||||||
|
broadcaster.send(subscription, notification, result.muted)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Finished polling for new notifications")
|
Log.d(TAG, "Finished polling for new notifications")
|
||||||
|
|
|
@ -6,6 +6,7 @@ import com.google.firebase.messaging.RemoteMessage
|
||||||
import io.heckel.ntfy.R
|
import io.heckel.ntfy.R
|
||||||
import io.heckel.ntfy.app.Application
|
import io.heckel.ntfy.app.Application
|
||||||
import io.heckel.ntfy.data.Notification
|
import io.heckel.ntfy.data.Notification
|
||||||
|
import io.heckel.ntfy.msg.BroadcastService
|
||||||
import io.heckel.ntfy.msg.NotificationService
|
import io.heckel.ntfy.msg.NotificationService
|
||||||
import io.heckel.ntfy.util.toPriority
|
import io.heckel.ntfy.util.toPriority
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -17,6 +18,7 @@ class FirebaseService : FirebaseMessagingService() {
|
||||||
private val repository by lazy { (application as Application).repository }
|
private val repository by lazy { (application as Application).repository }
|
||||||
private val job = SupervisorJob()
|
private val job = SupervisorJob()
|
||||||
private val notifier = NotificationService(this)
|
private val notifier = NotificationService(this)
|
||||||
|
private val broadcaster = BroadcastService(this)
|
||||||
|
|
||||||
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
||||||
// We only process data messages
|
// We only process data messages
|
||||||
|
@ -56,13 +58,17 @@ class FirebaseService : FirebaseMessagingService() {
|
||||||
tags = tags ?: "",
|
tags = tags ?: "",
|
||||||
deleted = false
|
deleted = false
|
||||||
)
|
)
|
||||||
val shouldNotify = repository.addNotification(notification)
|
val result = repository.addNotification(notification)
|
||||||
|
|
||||||
// Send notification (only if it's not already known)
|
// Send notification (only if it's not already known)
|
||||||
if (shouldNotify) {
|
if (result.notify) {
|
||||||
Log.d(TAG, "Sending notification for message: from=${remoteMessage.from}, data=${data}")
|
Log.d(TAG, "Sending notification for message: from=${remoteMessage.from}, data=${data}")
|
||||||
notifier.send(subscription, notification)
|
notifier.send(subscription, notification)
|
||||||
}
|
}
|
||||||
|
if (result.broadcast) {
|
||||||
|
Log.d(TAG, "Sending broadcast for message: from=${remoteMessage.from}, data=${data}")
|
||||||
|
broadcaster.send(subscription, notification, result.muted)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue