在Android中取消推送通知时如何发送请求 [英] How to send a request when push notification is cancelled in Android
问题描述
当应用程序从 FCM
收到 push通知
时,它将调用 onMessageReceived
.(请参见 1 , 3 .)
When an application receives push notification
from FCM
, it calls onMessageReceived
. (See 1, 2 or 3.)
当用户点击通知时,它会启动应用程序,然后向服务器发送一个请求,要求用户已阅读该通知.
When a user taps the notification, it launches the applications, then it sends a request to a server that the user has read the notification.
我想知道设备何时收到推送通知,但用户刷了它(或清除了所有通知).我想向服务器发送请求,要求用户只需取消通知.
I want to know when a device received a push notification, but the user swiped it (or cleared all notifications). I want to send a request to the server that the user simply cancelled the notification.
我尝试发送 BroadcastReceiver
并显示日志(请参阅 4 或 5 ),但当应用程序通知发送时已打开.我想那
I tried to send BroadcastReceiver
and show logs (see 4 or 5), but it works when the application was opened when the notification delivered. I suppose, that
MyFirebaseMessagingService:
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:
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:
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
.
works only when the application is opened. But when the application is in background or killed, it doesn't react to swipe. Probably we shouldn't use BroadcastReceiver
, for instance, use PendingIntent.getService
or PendingIntent.getForegroundService
.
我们可以向服务器发送请求吗?
Can we send a request to the server?
推荐答案
短时间后,它正常工作了(尽管我几乎没有做太大改变).经过大量研究,我提出了此解决方案.在从API 19到API 30的多个Android模拟器和设备上进行了测试.
After a short time it worked right (though I hardly changed much). After a lot of research I made this solution. Tested on several Android emulators and devices from API 19 to API 30.
因为使用 BroadcastReceiver
是不安全,在AndroidManifest中添加:
Because using BroadcastReceiver
is not safe, add in AndroidManifest:
<receiver
android:name=".NotificationBroadcastReceiver"
android:exported="false"
/>
NotificationBroadcastReceiver:
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:
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设备,例如:
Send a push message to Android device with it's push token, for instance:
{
"to": "ddSOGiz4QzmY.....:APA91bHgoincFw.......",
"data": {
"title": "Test",
"message": "Test",
"code": "ABCDEF"
}
}
您可以在此处中看到不同的传递推送消息的方案.如果用户按下强行停止",则在屏幕上显示强制停止".在应用程序上,它赢得了没有收到推送消息("AliExpress"除外,哈哈).
You can see different schemes of delivering push messages here. If a user presses "Force stop" at the application, it won't receive push messages (except "AliExpress", ha-ha).
当用户关闭推送通知时,将调用 NotificationBroadcastReceiver :: onReceive()
.应用程序获取推送消息的参数.然后,我们可以看到一条敬酒消息并将这些参数发送到服务器.
When the user dismisses push notification, NotificationBroadcastReceiver::onReceive()
is called. An application gets parameters of the push message. Then we can see a toast message and send these parameters to the server.
当用户按下全部清除"时,通知,将触发所有撤消事件.因此,您将看到一系列的敬酒.服务器将同时接收几个请求(例如,检查它是否可以在0.01秒内处理10个请求).
When the user presses "Clear all" notifications, all dismiss events are fired. So, you will see a sequence of toasts. The server will receive several requests simultaneously (check that it can handle, for instance, 10 requests in 0.01 second).
这篇关于在Android中取消推送通知时如何发送请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!