【问题标题】:Open specific Activity when notification clicked in FCM在 FCM 中单击通知时打开特定的 Activity
【发布时间】:2017-04-04 17:29:58
【问题描述】:

我正在开发需要显示通知的应用程序。 对于通知,我正在使用 FireBase Cloud Messaging (FCM)。 当应用程序处于后台时,我能够收到通知。

但是当我点击通知时,它会重定向到 home.java 页面。我希望它重定向到 Notification.java 页面。

所以,请告诉我如何在点击通知时指定活动。 我正在使用两种服务:

1.)MyFirebaseMessagingService

2.)MyFirebaseInstanceIDService

这是我在 MyFirebaseMessagingService 类中的 onMessageReceived() 方法的代码示例。

public class MyFirebaseMessagingService extends FirebaseMessagingService {

private static final String TAG = "FirebaseMessageService";
Bitmap bitmap;


public void onMessageReceived(RemoteMessage remoteMessage) {



    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}
/**
 * Create and show a simple notification containing the received FCM message.
 */

private void sendNotification(String messageBody, Bitmap image, String TrueOrFalse) {
    Intent intent = new Intent(this, Notification.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    intent.putExtra("Notification", TrueOrFalse);
    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)
            .setLargeIcon(image)/*Notification icon image*/
            .setContentTitle(messageBody)
            .setStyle(new NotificationCompat.BigPictureStyle()
             .bigPicture(image))/*Notification with Image*/
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

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

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

/*
*To get a Bitmap image from the URL received
* */
public Bitmap getBitmapfromUrl(String imageUrl) {
    try {
        URL url = new URL(imageUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap bitmap = BitmapFactory.decodeStream(input);
        return bitmap;

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return null;

    }
}

【问题讨论】:

  • 从你的 fcm 有效载荷中删除“通知”,它将起作用
  • 感谢您的回复!
  • 你的意思是说,从getNotification().getBody()中去掉getNotification();??
  • 完全没有。阅读此stackoverflow.com/a/37876727/1843331
  • 先生!我收到了正确的通知,没问题!当我们单击收到的通知时,我想打开活动 Notification.java。如何在代码中指定。

标签: android android-notifications firebase-cloud-messaging firebase-notifications


【解决方案1】:

AndroidManifest.xml

<activity android:name="YOUR_ACTIVITY">
    <intent-filter>
        <action android:name="com.example.yourapplication_YOUR_NOTIFICATION_NAME" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

您的 FirebaseMessagingService.java 文件 onMessageReceived 方法:

public void onMessageReceived(RemoteMessage remoteMessage){
    String title=remoteMessage.getNotification().getTitle();
    String message=remoteMessage.getNotification().getBody();
    String click_action=remoteMessage.getNotification().getClickAction();
    Intent intent=new Intent(click_action);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent=PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
    NotificationCompat.Builder notificationBuilder=new NotificationCompat.Builder(this);
    notificationBuilder.setContentTitle(title);
    notificationBuilder.setContentText(message);
    notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
    notificationBuilder.setAutoCancel(true);
    notificationBuilder.setContentIntent(pendingIntent);
    NotificationManager notificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(0,notificationBuilder.build());
}

您的通知的云功能/服务器代码必须是这样的:

    notification: {
        title: "TITLE OF NOTIFICATION",
        body: "NOTIFICATION MESSAGE",
        sound: "default",
        click_action:"com.example.yourapplication_YOUR_NOTIFICATION_NAME"
    }

【讨论】:

    【解决方案2】:

    当应用处于后台时,Intent 必须在您的启动器活动中传递。因此,它会打开您的 Launcher 活动。现在您检查启动器活动中的 Intent 中是否有数据,然后启动所需的活动。

    在您的启动器活动中

    Bundle extras = getIntent().getExtras(); 
    
    if (extras != null) {
      // possible launched from notification
      // check if desired notification data present in extras then its 
      // confirmed that launched from notification
      
      }else{
       // not launched from notification
    }
    

    【讨论】:

    • 你能举个例子吗?如何检查启动器 Activity 中是否有 Intent 数据。
    【解决方案3】:

    这是理解这一点的最简单方法。

    当您发送带有通知负载的数据负载时

     notification: {
                title: "Your order status.",
                body: orderStatusDetail,
                clickAction: "ShopFragment"
            },
            data: {
                ORDER_ID: orderId
            }
    

    通知 clickAction 将是您将用于将数据传递到 Activity 的过滤器,什么数据? data: { } 对象发送的数据附加到负载中。

    所以,clickAction 会触发 Manifest 中的 Intent 过滤器,所以首先我们需要创建它

     <activity
                android:name=".activity.MainActivity"
                android:label="@string/app_name">
    
                <intent-filter>
                    <action android:name="ShopFragment"/>
                    <category android:name="android.intent.category.DEFAULT"/>
                </intent-filter>
    
            </activity>
    

    现在我们将 Intent 过滤器设置为与 clickAction 相同的名称,这样做会触发每当我们在通知选项卡上按下通知时,此 Intent 过滤器将启动,以此类推与此 Intent 过滤器关联的 Activity。

    然后,只需在 MainActivity 中使用 intent.getStringExtra("ORDER_ID") 即可在数据负载中发送额外的字符串。

    确保在这种情况下 ORDER_ID 是我们从 data { } 对象发送的密钥,并且需要在客户端中相同才能获取此数据。

    【讨论】:

      【解决方案4】:

      使用 FCM,您可以向客户发送两个 types of messages

      1.通知消息: 有时被认为是“显示消息”。

      FCM 会代表客户端应用自动向最终用户设备显示消息。通知消息具有一组预定义的用户可见键。

      2。数据消息:由客户端应用处理。

      客户端应用负责处理数据消息。数据消息只有自定义键值对。

      根据FCM文档Receive Messages in an Android App

      • 当您的应用处于后台时发送通知。在这种情况下,通知会发送到设备的系统托盘。 默认情况下,用户点击通知会打开应用启动器。
      • 同时包含通知和数据负载的消息,包括后台和前台。在这种情况下,通知将发送到
        设备的系统托盘,数据负载在附加组件中交付 启动器 Activity 的意图。

      在通知负载中设置click_action

      所以,如果你想处理后台到达的消息,你必须发送click_action 和消息。

      click_actionparameter of the notification payload

      如果您想打开您的应用并执行特定操作,请在通知负载中设置click_action,并将其映射到您要启动的活动中的意图过滤器。

      例如,将click_action 设置为OPEN_ACTIVITY_1 以触发如下所示的意图过滤器:

      <intent-filter>
        <action android:name="OPEN_ACTIVITY_1" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
      

      FCM 负载如下所示:

      {
        "to":"some_device_token",
        "content_available": true,
        "notification": {
            "title": "hello",
            "body": "test message",
            "click_action": "OPEN_ACTIVITY_1"
        },
        "data": {
            "extra":"juice"
        }
      }
      

      【讨论】:

      • 当应用程序在后台时,此“click_action: 键也适用于数据消息。
      • @ManishJoshi 不,它仅适用于通知消息。但是您可以使用数据消息将待处理的意图设置为通知,以便在用户单击它时打开特定的活动。
      • stackoverflow.com/questions/62446449/… 我遇到了这个问题,为了解决它,我将 click_action 键添加到我的有效负载中以解决它
      【解决方案5】:

      打开 MyFirebaseMessagingService.java 文件

      在该文件中有一个 sendNotification() 方法,您必须在 Intent 中指定您需要导航到的活动,如下所示

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

      如果您要发送多个通知,并且希望在单击特定通知时导航到不同的活动,您可以使用任何条件语句来实现它,我的建议是使用 switch case,如图所示下面

      private void sendNotification(String messageBody, Bitmap image, String TrueOrFalse) {
      
          Intent intent = new Intent();
          switch(condition) {
             case '1': intent = new Intent(this, ActivityOne.class);
                       break;
             case '2': intent = new Intent(this, ActivityTwo.class);
                       break;
             case '3': intent = new Intent(this, ActivityThree.class);
                       break;
             default : intent = new Intent(this, DefaultActivity.class);
                       break;
          }
          intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      
          intent.putExtra("Notification", TrueOrFalse);
          PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
              PendingIntent.FLAG_ONE_SHOT);
      }
      

      使用此逻辑,您可以在 FCM 中的通知点击上打开特定活动。 这对我来说非常有效。 谢谢

      【讨论】:

      • 这总是打开启动器活动。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-30
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多