Firebase云消息推送 - Android:当应用程序关闭时,通知的click-action不起作用

15

我正在使用Firebase Cloud Messaging将数据消息传递到我正在开发的应用程序中。根据FCM文档,在应用程序处于前台时:

客户端应用程序在onMessageReceived()中接收数据消息,并可以相应地处理键值对。

它可以正常工作。当应用程序处于后台时,行为不同:

数据有效负载可以在用于启动活动的Intent中检索。

但这似乎并不起作用。我在通知JSON中使用了“click_action”参数,其中指定了Android清单中“activity”标记内使用的意图过滤器的名称,我想要打开该标记。例如,我的通知可能是:

{
    "to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
    "notification" : {
        "body" : "This is a test",
        "title" : "Test",
        "click_action" : "com.test.click"
    },
    "data" : {
        "key" : "data"
    }
}

我的清单文件中在“MainActivity”中添加了这个意图过滤器:

And my manifest has this intent-filter, in the "MainActivity":


<intent-filter>
    <action android:name="com.test.click" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
当我的应用程序在后台时,如果我启动通知,则一切似乎都正常工作:我单击通知,正确的活动将显示,并且数据键位于接收到的意图的“extras”中。 问题出现在我的应用程序关闭时:当我点击通知时,应用程序正确地启动并打开具有“com.test.click”意图过滤器的活动,但是如果我尝试发送另一个通知,则点击它时什么也不会发生,并且后台通知不再起作用,直到我重新启动应用程序。
更明确地说:通知在我的应用程序前台或后台正常工作。如果我的应用程序关闭,则第一个通知将被正确处理,但是每个其他后台通知都不再起作用,直到我重新启动应用程序:如果我点击通知,则我的应用程序显示上次观看的最后一个活动,就好像我从“最近使用的应用程序”菜单中选择了该应用程序。如果我关闭并重新启动应用程序,则通知会恢复正常工作。
这是Android中数据消息的错误还是FCM的问题?有没有方法解决此问题?
我正在使用 Nexus 5 API 23 进行测试。

1
你有这个问题的解决方案吗? - Bahu
很遗憾,我没有找到解决方案,只使用数据消息就可以了。使用系统托盘通知,这个错误仍然存在。我认为这是FCM的一个bug。你是否遇到了我在问题中描述的相同的bug? - Mattia Ruggiero
1
是的兄弟,我正在尝试解决这个问题。如果你有除“数据消息,使用系统托盘通知”之外的建议,请告诉我。 - Bahu
@Bahu 我可以用我的方法写出这个问题的解决方案,但是正如我之前所说,我的解决方案只使用数据消息。这意味着您的服务器始终必须发送数据消息,而不是显示消息。仅使用此类型的消息通知可以正常工作。如果您希望我在下面写出完整的答案,请告诉我。 - Mattia Ruggiero
好的兄弟,请写下答案。谢谢。 - Bahu
1个回答

13

我会尝试描述一下它在我的情况下是如何工作的

通知负载示例:

{
"notification": {
    "body": "This is a test message",
    "title": "Message",
    "click_action" : "OPEN_ACTIVITY_1"
},
"data": {
    "key": "test key"

}

在活动中体现

<intent-filter>
    <action android:name="OPEN_ACTIVITY_1" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
当应用程序在后台或关闭时,FCM将创建一个“通知消息”,并在单击时打开正确的活动。为了处理应用程序关闭时的通知,请在onCreate()方法中调用getIntent()。
例如:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_hub);

    handleIntents(getIntent()); //for simplicity I'm passing the value forward


}

当应用程序在前台时,我正在在FirebaseMessagingService的onMessageReceived方法中创建自定义通知。

例如。

    Intent intent = new Intent(this, HubActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra("url", remoteMessage.getData().get("url"));
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle("Message")
            .setContentText("This is a test message")
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());

并且为了适当处理它,在我重写的活动中使用onNewIntent(Intent intent)方法。

例如:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    handleIntents(intent); //for simplicity I'm passing the value foward


}

我认为你需要加上onNewIntent(Intent intent)方法,因为它可以在Activity已经创建后处理新的Intent。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接