如何在 Android 中取消推送通知时发送请求

如何解决如何在 Android 中取消推送通知时发送请求

当应用程序从 push notification 收到 FCM 时,它会调用 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,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)
    ...
}

通知广播接收器:

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

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

解决方法

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

因为使用 BroadcastReceivernot safe,所以在 AndroidManifest 中添加:

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

通知广播接收器:

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 推送消息(“AliExpress”除外,哈哈)。

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?