Android 中取消推送通知时如何发送请求
How to send a request when push notification is cancelled in Android
当应用程序从 FCM
接收到 push notification
时,它会调用 onMessageReceived
。 (参见 1, 2 or 3。)
当用户点击通知时,它会启动应用程序,然后向服务器发送用户已阅读通知的请求。
我想知道设备何时收到推送通知,但用户滑动它(或清除所有通知)。我想向服务器发送一个请求,用户只是取消了通知。
我尝试发送 BroadcastReceiver
并显示日志(请参阅 4 or 5),但是当应用程序 在通知已发送 时打开时它起作用了。我想,
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.getService
或PendingIntent.getForegroundService
。
我们可以向服务器发送请求吗?
在很短的时间后它工作正常(虽然我几乎没有改变)。经过大量研究,我提出了这个解决方案。在从 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. If a user presses "Force stop" at the application, it won't receive推送消息(“全球速卖通”除外,哈哈)。
当用户关闭推送通知时,将调用 NotificationBroadcastReceiver::onReceive()
。应用程序获取推送消息的参数。然后我们可以看到一条toast消息,将这些参数发送给服务器。
当用户按下“清除所有”通知时,将触发所有关闭事件。因此,您将看到一系列吐司。服务器将同时接收多个请求(检查它是否可以在 0.01 秒内处理例如 10 个请求)。
当应用程序从 FCM
接收到 push notification
时,它会调用 onMessageReceived
。 (参见 1, 2 or 3。)
当用户点击通知时,它会启动应用程序,然后向服务器发送用户已阅读通知的请求。
我想知道设备何时收到推送通知,但用户滑动它(或清除所有通知)。我想向服务器发送一个请求,用户只是取消了通知。
我尝试发送 BroadcastReceiver
并显示日志(请参阅 4 or 5),但是当应用程序 在通知已发送 时打开时它起作用了。我想,
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.getService
或PendingIntent.getForegroundService
。
我们可以向服务器发送请求吗?
在很短的时间后它工作正常(虽然我几乎没有改变)。经过大量研究,我提出了这个解决方案。在从 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. If a user presses "Force stop" at the application, it won't receive推送消息(“全球速卖通”除外,哈哈)。
当用户关闭推送通知时,将调用 NotificationBroadcastReceiver::onReceive()
。应用程序获取推送消息的参数。然后我们可以看到一条toast消息,将这些参数发送给服务器。
当用户按下“清除所有”通知时,将触发所有关闭事件。因此,您将看到一系列吐司。服务器将同时接收多个请求(检查它是否可以在 0.01 秒内处理例如 10 个请求)。