繁体   English   中英

当应用程序处于后台时,FCM Intent 与数据交付在哪里?

[英]Where is FCM Intent with data delivered, when app is in background?

我已经在我的应用程序中实施了 Firebase,并且正在发送带有额外数据的推送。 当我的应用程序处于前台时,我正在正确处理数据并显示我自己的通知,但是当 Firebase 在应用程序“归巢”(未终止)时“自动”显示通知时,我在获取数据时遇到了问题。 根据DOCSActivity应该获得新的Intent ,并用我的价值观实现额外的功能,而不是应用程序回到前面,恢复旧状态。

设想:

  1. 打开应用程序,按主页
  2. 通过 Firebase 控制台发送推送,Firebase 正在创建Notification而不调用onMessageReceived (根据文档中的表,它应该?)
  3. 当用户选择通知应用程序将以与“主页”相同的状态被带到前面时,并且Intent被用于在顶部打开Activity的“原始”附加功能实现

我在onCreateonNewIntentonResume ( Activity ) 和onMessageReceived ( Service ) 中登录,只调用onResume ,我在其中打印如下所示的额外内容:

if (getIntent().getExtras() != null) {
        for (String key : getIntent().getExtras().keySet()) {
            Object value = getIntent().getExtras().get(key);
            Log.d("Activity onResume", "Key: " + key + " Value: " + value);
        }
    }

具有通知和数据负载的消息,包括背景和前景。 在这种情况下,数据有效负载被传送到您的启动器活动的意图的额外部分。 如果您想在其他活动中获取它,则必须在数据负载上定义 click_action。 因此,在您的启动器活动中获得额外的意图。

编辑:-

文档中:- 在后台时,应用程序在通知托盘中接收通知有效负载,并且仅在用户点击通知时处理数据有效负载。

因此,在单击通知时使用 getIntent() extras 检查启动器活动的 oncreate() 方法。

所以我一直在寻找这个答案并阅读相同的内容。 它必须在某个地方。 我知道这是一岁了,但他们还没有真正说清楚。 在与通知关联的 pendingActivity 中(在我的例子中是 MainActivity )我添加了以下内容。 请注意,我正在通过 Google Codelabs com.example.android.eggtimernotifications 工作,而不是在答案中。

    override fun onResume() {
        super.onResume()
        intent?.run {
            val keys = this.extras?.keySet()
            if (!keys.isNullOrEmpty()) {
                keys.forEach { key ->
                    when (this.extras!![key]) {
                        is Long -> println("$key = ${this.getLongExtra(key, 0L)}")
                        is Int -> println("$key = ${this.getIntExtra(key, 0)}")
                        is String -> println("$key = ${this.getStringExtra(key)}")
                        is Boolean -> println("$key = ${this.getBooleanExtra(key, false)}")
                        else -> println("unkonwn Type")
                    }
                }
            }
        }
    }

这导致了以下结果。

  • I/System.out: google.delivered_priority = 高
  • 我/System.out: google.sent_time = 1585284914411
  • 我/System.out: google.ttl = 2419200
  • I/System.out: google.original_priority = 高
  • I/System.out:谷物=碎纸片
  • I/System.out: 来自 = /topics/breakfast
  • I/System.out: 牛奶 = 1 杯
  • I/System.out: sugar = 无
  • 我/System.out: google.message_id = 0:1585284914700957%f6ddf818f6ddf818
  • I/System.out: collapse_key = com.example.android.eggtimernotifications

数据键是谷物、牛奶和糖。

根据文档Cloud messaging docs消息可以以 3 种状态传递:

  1. 通知
  2. 数据
  3. 通知和数据

后台处理:

对于 2. onMessageReceived将在没有 UI 和额外处理的情况下被调用。 稍后你可以展示一些定制的东西。

当涉及到3时,android会显示通知并保持数据,直到有用户交互。 单击后,它只是恢复您现有的活动。 您的onNewIntent未被触发,因为您的启动模式不是FLAG_ACTIVITY_SINGLE_TOP

您还应该检查您的 logcat 输出: Google Play services out of date

应用程序在后台时不会调用 onMessageReceived()。 几个月前我遇到了这个问题。 我通过覆盖 handlerIntent 方法来解决它。 但是你的 firebase 消息库应该

implementation 'com.google.firebase:firebase-messaging:10.2.1'

在那之后:

@Override
    public void handleIntent(Intent intent) {
        try
        {
            if (intent.getExtras() != null)
            {
                RemoteMessage.Builder builder = new RemoteMessage.Builder("MessagingService");

                for (String key : intent.getExtras().keySet())
                {
                    builder.addData(key, intent.getExtras().get(key).toString());
                }

                onMessageReceived(builder.build());
            }
            else
            {
                super.handleIntent(intent);
            }
        }
        catch (Exception e)
        {
            super.handleIntent(intent);
        }
    }

如果你不想降级你的图书馆那么

您可以指定一个 click_action 来指示当用户点击通知时应启动的意图。 如果未指定 click_action,则使用主要活动。

启动意图时,您可以使用

getIntent().getExtras();

检索一个 Set,其中包含随通知消息一起发送的任何数据。

有关通知消息的更多信息,请参阅https://firebase.google.com/docs/cloud-messaging/android/receive#sample-receive

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM