【问题标题】:Identify if an activity was opened from FCM notification click确定是否从 FCM 通知单击打开了活动
【发布时间】:2018-04-30 06:11:51
【问题描述】:

我正在使用 fcm 控制台向所有安装了我的应用的设备发送消息,通知没有任何额外的有效负载,只有通知消息。

我想知道是否有一种简单的方法可以知道是否通过 FCM 通知点击打开了 Activity。

有一个解决方案是扩展FirebaseMessagingService 服务并自己创建通知。

我想知道是否有另一种解决方案,无需扩展服务或将额外内容传递给通知。

用于从通知点击打开活动的 Intent 是否传递了任何额外内容?

【问题讨论】:

  • 你到底想要什么?我不清楚你想知道你的条目有多少来自通知??!!
  • @Ashkan:它是用简单的英语写的,我的朋友:“我想知道是否有一种简单的方法可以知道是否通过 FCM 通知单击打开了 Activity。”
  • 如果您没有子类化FirebaseMessagingService,点击通知将如何启动您需要的活动?
  • 在通知中有一个包含活动上下文的上下文,因此您可以从通知上下文中获取。
  • @azizbekian,发送和显示通知 firebase 不会强迫您继承他们的服务,您可以发送消息并让用户仅通过在 build.gradle 文件中添加消息依赖项来接收它们。

标签: android firebase-cloud-messaging


【解决方案1】:

我希望您知道基于 FCM 的消息传递创建了两种类型的通知

首先,我们通过onMessageReceived()方法创建的通知,这里需要注意的是,如果应用在前台,onMessageReceived()会被触发。

其次,当应用程序处于后台时,FCM 会创建自己的默认通知,在这种情况下,onMessageReceived() 不会被拦截,因此我们无法自行设置待处理的 Intent。

注意:当您向您的应用程序发送“通知”推送消息时,上述类型会发挥作用或后台(从 FCM 控制台发送的通知是“通知”类型的推送消息)

回到你的问题,不清楚你是从 FCM 控制台发送推送消息还是发出 FCM 服务器请求,所以让我们在这里做案例。

  1. FCM 控制台正在发送消息:
    从 FCM 通知面板中的高级部分发送数据有效负载,如下所示

当app在前台时onMessageReceived()会被拦截 使用下面的代码接收数据负载

public class MyFirebaseMessagingService extends FirebaseMessagingService {

private static final String TAG = "MyFirebaseMsgService";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    //Displaying data in log
    //It is optional


    //Calling method to generate notification
    sendNotification(remoteMessage.getData());
}

//This method is only generating push notification
//It is same as we did in earlier posts
private void sendNotification(Map<String, String> messageBody) {

    Intent intent = new Intent(this, SplashScreen.class);

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(
            this,
            0,
            setNotificationRoute(messageBody),
            PendingIntent.FLAG_UPDATE_CURRENT);
    Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(android.R.drawable.sym_def_app_icon)
            .setContentTitle(messageBody.get("title"))
            .setContentText(messageBody.get("text"))
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

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

    notificationManager.notify(0, notificationBuilder.build());


}

private Intent setNotificationRoute(Map<String, String> messageBody) {
    Intent intent = null;
    String type = messageBody.get("type");
    if (type != null) {
        switch (type) {
            case "android":    //intercept your payload here to create swit 
                intent = new Intent(this, MainActivity.class);
                break;
            default:
                break;

        }

    }
    return intent;
}
}

如果应用程序在后台,那么在通知点击应用程序将在“默认”活动上打开,您可以通过在活动的意图过滤器的应用程序清单中添加以下行来将任何活动设置为默认活动:

<category android:name="android.intent.category.DEFAULT" />

在此活动中,您可以调用以获取额外的意图,然后获取数据有效负载以决定您需要登陆哪个活动。代码如下

    .
    .
    .

        Bundle bundle = getIntent().getExtras();
            if (bundle != null) {
                setNotificationRoute(getIntent().getExtras());
    .
    .
}
 private void setNotificationRoute(Bundle extras) {
    String type = extras.getString("type");
    Intent intent = null;
    if (type != null) {
        switch (type) {
            case "message":
                String room = extras.getString("room");
                intent = new Intent(this, MainActivity.class);
                startActivity(intent);
                break;
            default:
                break;
        }
      }
    }
  1. 从 FCM 服务器发送的消息:从上面的 FCM 控制台发送的消息与将以下 json 正文作为 post 请求发送到 FCM 服务器相同:

    { 
        "notification": {
        "title": "Hi Tester",
        "text": "News for testing",
        "sound": "default",
        "badge": 0
      },
      "data":{
        "type": "credits"
      },
      "priority": "high",
      "to": "{{device_token}}"
    }
    

在这种情况下拦截通知的过程将是相同的。

【讨论】:

  • 我正在使用 fcm 控制台向所有设备发送消息,我已经提到过,所以基本上我需要在高级部分添加额外内容,以便能够在 onCreate( ) 的活动?不扩展消息服务? (我只希望未打开应用的用户收到通知)
  • “(我只希望没有打开应用程序的用户接收通知)”所以基本上你希望后台通知工作,因为你采取的后台通知处理方法是在清单中提到的“默认”活动中获取意图,并使用您从控制台的高级部分传递的键值获取捆绑包。
  • intent.getExtras 上的结果为空。怎么办?
  • @PinkeshDarji 请详细说明您从哪里获得 NPE
【解决方案2】:

无需有意传递任何额外内容。只需将标志设置为

  Intent lIntent = new Intent(getApplicationContext(),YourActivity.class);
        lIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        lIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
        lIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(lIntent);

【讨论】:

    【解决方案3】:

    如果您想在不扩展 FireBaseMessaging 类的情况下启动任何活动,那么您可以使用您的 FCM 数据负载设置此标志。

    因此,每当用户单击系统托盘上的 FCM 通知时。定义的 Activity 应该打开。如果你想获得额外的捆绑数据。你可以使用 getIntent().getExtras();方法。

        "message":{
         "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
         "notification":{
           "title":"Match update",
           "body":"Arsenal goal in added time, score is now 3-0"
         },
    "android":{
               "ttl":"86400s",
               "notification"{
                 "click_action":"MainActivity.class" // define your activity here
               }
             },
     "payload": {
             "aps": {
               "category": "NEW_MESSAGE_CATEGORY"
             }
           }
         }
    

    请参考以下链接:-

    "sets the appropriate keys to define the result of a user tap on the notification on Android and iOS — click_action, and category, respectively."

    【讨论】:

    • 我真的需要为每条消息添加一个令牌吗?
    • yes fcm token is required.please follow official documentations
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多