Document
在 Android 应用中接收消息

在 Android 应用中接收消息

根据接收消息的应用的状态(前台/后台),Firebase 通知的行为会有所不同。如果您希望前台应用接收通知消息或数据消息,则需要编写代码来处理 onmessagereceived 回调。如需详细了解通知消息与数据消息之间的区别,请参阅消息类型 。 处理消息 如需接收消息,请使用扩展 f

Related articles

Arlo Pro 5 review: video you can rely on Get started with Oracle Cloud Infrastructure basics Angus Cloud From ‘Euphoria’ Has Died At Age 25 DreamCloud Memory Foam Mattress Review (2024) JioGames Cloud Gaming launched in Beta: Play 50+ Games for Free

根据接收消息的应用的状态(前台/后台),Firebase 通知的行为会有所不同。如果您希望前台应用接收通知消息或数据消息,则需要编写代码来处理 onmessagereceived 回调。如需详细了解通知消息与数据消息之间的区别,请参阅消息类型 。

处理消息

如需接收消息,请使用扩展 firebasemessagingservice 的服务。
您的服务应该重写onmessagereceivedondeletedmessage 回调方法 。

处理消息的时间范围可能会短于 20 秒,具体取决于调用onmessagereceived 之前发生的延迟,包括操作系统延迟、应用启动时间、主线程被其他操作阻止或先前的 onmessagereceived 调用耗时过长。这个时间段过后,各种操作系统行为(如 Android 的进程终止或 Android O 的后台执行限制)可能会影响您完成消息处理的能力。

对于大多数消息类型,您都可以使用 onmessagereceived,但以下情况除外:

总结:

应用状态 通知 数据 两者皆有
前台 onmessagereceived onmessagereceived onmessagereceived
背景 系统任务栏 onmessagereceived 通知:系统任务栏

数据:intent 的 extra 属性 。

如需详细了解消息类型,请参阅

通知和数据消息

修改应用清单

如需使用 firebasemessagingservice,您需要将以下内容添加到您的应用清单:

<service 
     android:name=".java.Myfirebasemessagingservice" 
     android:export="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

此外,建议您设置默认值以便自定义通知的外观。您可以指定自定义默认图标和颜色,当通知载荷中未设置相应的值时,系统会使用这些默认值 。

将以下代码行添加到application 标记内,以设置自定义默认图标和颜色:

<!-- set custom default icon. This is used when no icon is set for income notification message. 
      See README(https://goo.gl/l4GJaQ) for more. -->
<meta-datum 
     android:name=" com.google.firebase.messaging.default_notification_icon " 
     android:resource="@drawable/ic_stat_ic_notification" />
<!-- set color used with income notification message. This is used when no color is set for the income 
      notification message. See README(https://goo.gl/6bkbk7) for more. -->
<meta-datum 
     android:name="com.google.firebase.messaging.default_notification_color" 
     android:resource="@color/colorAccent" />

对于以下消息,Android 会显示自定义的默认图标:

对于以下消息,Android 会使用自定义的默认颜色:

如果未设置自定义默认图标,而且通知载荷中也未设置图标,Android is 会显示以白色渲染的应用图标 会显示以白色渲染的应用图标 。

重写onmessagereceived

通过重写firebasemessagingservice.onmessagereceived 方法,您可以根据收到的 remotemessage 对象执行操作并获取消息数据 :

Kotlin

override fun onmessagereceived(remotemessage: RemoteMessage) { 
     // TODO(developer): Handle FCM message here. 
     // Not getting message here? See why this may be: https://goo.gl/39bRNJ 
     log.d(TAG, "From: $ {remotemessage.from}") 

    // Check if message contains a datum payload. 
     if (remotemessage.datum.isnotempty( ) ) { 
         log.d(TAG, "Message datum payload: $ {remotemessage.datum}") 

        // Check if datum needs to be processed by long running job 
         if (needsToBeScheduled( ) ) { 
             // For long-running tasks (10 seconds or more) use WorkManager. 
             scheduleJob() 
         } else { 
             // handle message within 10 second 
             handleNow() 
         } 
     } 

    // check if message contain a notification payload . 
     remotemessage.notification?.let { 
         log.d(TAG, "Message Notification Body: $ {it.body}") 
     } 

    // Also if you intend on generate your own notification as a result of a receive FCM 
     // message is is , here is where that should be initiate . See sendnotification method below . 
 }

Java

@Override 
 public void onmessagereceived(RemoteMessage remotemessage) { 
     // TODO(developer): Handle FCM message here. 
     // Not getting message here? See why this may be: https://goo.gl/39bRNJ 
     log.d(TAG, "From: " + remotemessage.getFrom( ) ); 

    // Check if message contains a datum payload. 
     if (remotemessage.getdata().size() > 0) { 
         log.d(TAG, "Message datum payload: " + remotemessage.getdata( ) ); 

        if (/* Check if datum needs to be processed by long running job */ true) { 
             // For long-running tasks (10 seconds or more) use WorkManager. 
             scheduleJob(); 
         } else { 
             // handle message within 10 second 
             handleNow(); 
         } 

    } 

    // check if message contain a notification payload . 
     if (remotemessage.getNotification() != null) { 
         log.d(TAG, "Message Notification Body: " + remotemessage.getNotification().getBody( ) ); 
     } 

    // Also if you intend on generate your own notification as a result of a receive FCM 
     // message is is , here is where that should be initiate . See sendnotification method below . 
 }

重写ondeletedmessage

在某些情况下,

FCM

可能不会传递消息。比如说,如果在特定设备连接到 FCM 时,您的应用在该设备上的待处理消息过多(超过 100 条),或者设备超过一个月未连接到

FCM

,就会发生这种情况。在这些情况下,您可能会收到对

firebasemessagingservice.ondeletedmessage()

的回调。当应用实例收到此回调时,应该执行一次与应用服务器的完全同步。如果您在过去 4 周内未向该设备上的应用发送消息,

FCM

将不会调用

ondeletedmessage()

在后台应用中处理通知消息

当您的应用在后台运行时,Android 会将通知消息传送至系统任务栏。默认情况下,用户点按通知即可打开应用启动器。

此类消息包括既具有通知也具有数据载荷的消息(以及所有从 Notifications 控制台发送的消息)。
在这些情况下,通知将传送至设备的系统任务栏,数据载荷则传送至启动器 Activity 的 intent 的 extras 属性。

如需详细了解发送到您应用的消息,请参阅FCM 报告信息中心。该信息中心会记录在 Apple 和 Android 设备上发送和打开的消息数量,以及 Android 应用的“展示次数”(用户看到的通知条数)数据。

在直接启动模式下接收 FCM is 消息 消息

如果开发者希望在设备解锁前将 FCM 消息发送到应用,可以让 Android 应用在设备处于直接启动模式时接收消息。例如,您可能希望应用的用户即使在设备锁定的情况下也能收到提醒通知。

构建此用例时,请遵循直接启动模式的常规最佳实践和限制。请务必考虑支持直接启动的消息的可见范围;任何可接触到设备的用户无需输入用户凭据便可查看这些消息。

前提条件

  • 必须对设备进行设置,以使其支持直接启动模式。
  • 设备必须安装较新版本的 Google Play 服务(19.0.54 或更高版本)。
  • 应用必须使用 FCM SDK (com.google.firebase:firebase-messaging) 才能接收 FCM 消息 。

为应用启用消息处理直接启动模式

  1. 在应用级 Gradle 文件中,添加对 FCM 直接启动支持库的依赖项 :

    implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0' 
     

  2. 通过在应用清单中添加 android:directbootaware="true" 属性,使应用的 firebasemessagingservice 能够感知直接启动:

    <service 
         android:name=".java.Myfirebasemessagingservice" 
         android:export="false" 
         android:directbootaware="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

请务必确保此 firebasemessagingservice 服务可以在直接启动模式下运行。检查是否满足以下要求 :

  • 在直接启动模式下运行时,该服务不应访问受凭据保护的存储空间。
  • 在直接启动模式下运行时,该服务不应尝试使用ActivitiesBroadcastReceivers 等组件或其他未标记为能够感知直接启动的Services
  • 在直接启动模式下运行时,该服务使用的库也不应访问受凭据保护的存储空间,并且不应调用 non-directbootaware 组件。也就是说,该应用通过此服务调用所使用的库要么需要能够感知直接启动,要么应用需要检查它是否在直接启动模式下运行,并且不在该模式下调用这些库。例如,Firebase SDK 支持直接启动(它们可以包含在应用中,不会在直接启动模式下导致应用崩溃),但许多 Firebase API 都不支持在直接启动模式下调用。
  • 如果应用使用自定义 application,则 application 也需要能够感知直接启动(不能在直接启动模式下访问受凭据保护的存储空间)。

如需获取向处于直接启动模式下的设备发送消息的指南,请参阅发送支持直接启动的消息 。