【问题标题】:How to send a request when push notification is cancelled in Android如何在Android中取消推送通知时发送请求
【发布时间】:2021-01-13 14:01:28
【问题描述】:

当应用程序从FCM 接收到push notification 时,它会调用onMessageReceived。 (见123。)

当用户点击通知时,它会启动应用程序,然后向服务器发送用户已阅读通知的请求。

我想知道设备何时收到推送通知,但用户刷了它(或清除了所有通知)。我想向服务器发送一个请求,用户只是取消了通知

我尝试发送BroadcastReceiver 并显示日志(请参阅45),但它在应用程序在通知传递时打开时工作。我想,那个

MyFirebaseMessagingService:

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    ...
    // An event when a user swipes a notification.
    val intent = Intent(this, NotificationBroadcastReceiver::class.java)
    intent.action = "notification_cancelled"
    val deleteIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)
    notificationBuilder.setDeleteIntent(deleteIntent)

    // Navigation to an activity when a user taps the notification.
    // It doesn't matter to this question.
    val intent2 = Intent(this, MainActivity::class.java)
    val navigateIntent = PendingIntent.getActivity(this, notificationId, intent2,
        PendingIntent.FLAG_UPDATE_CURRENT)
    notificationBuilder.setContentIntent(navigateIntent)
    ...
}

NotificationBroadcastReceiver:

class NotificationBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Timber.d("NotificationBroadcastReceiver onReceive")
        Toast.makeText(context, "Notification dismissed", Toast.LENGTH_LONG).show()
        // Send a request to the server.
    }
}

AndroidManifest:

<uses-permission android:name="com.uremont.NOTIFICATION_PERMISSION" />

    <receiver
        android:name=".receiver.NotificationBroadcastReceiver"
        android:exported="true"
        android:permission="NOTIFICATION_PERMISSION"
        >
        <intent-filter>
            <action android:name="notification_cancelled" />
        </intent-filter>
    </receiver>

仅在应用程序打开时有效。但是当应用程序在后台或被杀死时,它不会对滑动做出反应。可能我们不应该使用BroadcastReceiver,例如,使用PendingIntent.getServicePendingIntent.getForegroundService

我们可以向服务器发送请求吗?

【问题讨论】:

    标签: android firebase-cloud-messaging android-pendingintent


    【解决方案1】:

    不久之后它就正常工作了(尽管我几乎没有改变太多)。经过大量研究,我提出了这个解决方案。在从 API 19 到 API 30 的多个 Android 模拟器和设备上进行了测试。

    因为使用BroadcastReceiver就是not safe,所以在AndroidManifest中添加:

    <receiver
        android:name=".NotificationBroadcastReceiver"
        android:exported="false"
        />
    

    NotificationBroadcastReceiver:

    class NotificationBroadcastReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            Timber.d("NotificationBroadcastReceiver onReceive")
    
            if (intent.extras != null) {
                // Receive parameters of a cancelled notification.
                val authToken = intent.getStringExtra(EXTRA_TOKEN)
                val code = intent.getStringExtra(EXTRA_CODE)
                Timber.d("token = $authToken, code = $code")
                // We can access context even if the application was removed from the recent list.
                Toast.makeText(context, "Notification $code was cancelled", Toast.LENGTH_SHORT).show()
                // Send data to a server.
            }
        }
    
        companion object {
            const val EXTRA_TOKEN = "EXTRA_TOKEN"
            const val EXTRA_CODE = "EXTRA_CODE"
        }
    }
    

    MyFirebaseMessagingService:

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        ...
        // Get notification code from data.
        val code = remoteMessage.data["code"]
    
        val notificationBuilder = NotificationCompat.Builder(this,
        ...
    
        val notificationId = Random.nextInt()
        val intent = Intent(this, NotificationBroadcastReceiver::class.java).apply {
            putExtra(EXTRA_TOKEN, authToken)
            putExtra(EXTRA_CODE, code)
        }
        val deleteIntent = PendingIntent.getBroadcast(this, notificationId, intent,
            PendingIntent.FLAG_CANCEL_CURRENT)
        notificationBuilder.setDeleteIntent(deleteIntent)
    
        val notification = notificationBuilder.build()
        notificationManager.notify(notificationId, notification)
    }
    

    使用推送令牌向 Android 设备发送推送消息,例如:

    {
      "to": "ddSOGiz4QzmY.....:APA91bHgoincFw.......",
      "data": {
        "title": "Test",
        "message": "Test",
        "code": "ABCDEF"
      }
    }
    

    您可以看到传递推送消息的不同方案here。如果用户在应用程序上按下“强制停止”,它会won't receive推送消息(“速卖通”除外,哈哈)。

    当用户关闭推送通知时,NotificationBroadcastReceiver::onReceive() 被调用。应用程序获取推送消息的参数。然后我们可以看到一个 toast 消息,并将这些参数发送到服务器。

    当用户按下“全部清除”通知时,会触发所有关闭事件。因此,您将看到一系列祝酒词。服务器将同时接收多个请求(检查它是否可以在 0.01 秒内处理例如 10 个请求)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-21
      • 2019-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多