android - 应用程序未运行时如何堆叠 Firebase Cloud Messaging 通知?

标签 android firebase firebase-cloud-messaging

我正在使用 Firebase Cloud Messaging 将推送通知从我的服务器发送到我的 android 应用程序。

当应用程序运行时,通知会堆叠,因为我在我的 FirebaseMessagingService 中将它们设置为一个组。这很好。

但是,当应用程序未运行时,通知不会堆叠,每个通知都会单独显示。这不好。

如何确保即使在应用程序未运行时也能堆叠通知?

这就是我的 FirebaseMessagingService 的样子:

public class MyFcmListenerService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        RemoteMessage.Notification notification = remoteMessage.getNotification();

        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)

                .setSmallIcon(R.drawable.notif_white)
                .setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.notif_white))
                .setContentTitle(getResources().getString(R.string.app_name))
                .setContentText(notification.getBody())
                .setAutoCancel(true)
                .setPriority(2)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent)
                .setGroup("1")
                .setGroupSummary(true)
                .setOnlyAlertOnce(true);


        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0 , notificationBuilder.build());

        }
    }

最佳答案

要堆叠两个或多个通知(在消息列表中指定)并使它们看起来像 GMail 样式通知,您可以为您的通知添加收件箱样式,如下所示:-

    private void showNotification(Context mContext, String title, List messages, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {

    final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
            mContext);

    NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();

    for(int i=0;i<messages.size();i++)
        inboxStyle.addLine(messages.get(i));

    Notification notification;
    notification = mBuilder.setTicker(title)
            .setAutoCancel(true)
            .setContentTitle(title)
            .setContentIntent(resultPendingIntent)
            .setSound(alarmSound)
            .setStyle(inboxStyle)
            .setWhen(getTimeMilliSec(timeStamp))
            .setSmallIcon(R.drawable.notification_small_icon)
            .setLargeIcon(R.drawable.notification_large_icon)
            .setDeleteIntent(PendingIntent.getBroadcast(mContext,101,new Intent(mContext, NotificationDismissedReceiver.class),PendingIntent.FLAG_CANCEL_CURRENT))
            .build();

    NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(NConfig.NOTIFICATION_ID, notification);
    }

如果您注意到,我还为我的通知添加了删除 Intent ,它会触发 NotificationDismissedReceiver(BroadcastReceiver),其主要工作是清除已被滑动手势关闭的通知消息,以便下次只有新的通知消息堆叠在一起。

public class NotificationDismissedReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // TODO: This method is called when the BroadcastReceiver is receiving
    // an Intent broadcast.
    messages.clear();
}
}

主要逻辑是收集列表中所有未读/未刷过的通知,即消息,下面是 FirebaseMessagingService 的 onMessageReceive() :-

    public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.e(TAG, "From: " + remoteMessage.getFrom());

    if (remoteMessage == null)
        return;

    if (remoteMessage.getData()!=null && remoteMessage.getData().size() > 0) 
    {

        try {
            JSONObject json = new JSONObject(remoteMessage.getData().toString());
            Log.e(TAG, "Notification Data: " + json);
            Title = json.get("title").toString();
            Message = json.get("body").toString();
            messages.add(Message);

        } catch (Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
     }

       showNotification(...);
     }

当应用程序在前台时,上面的 FirebaseMessagingService 的 onMessageReceive() 执行正常,但当您的应用程序在后台或被杀死时,它不会执行。 要使其执行,您必须从服务器端发送的 JSON 消息中省略通知部分,只包含数据部分,如下所示:-

       var data = new
       {
           to = token,
        //   notification = new
        //   {
        //       body = messageBody,   //Omitting notification part of data
        //       title = messageTitle,
        //       icon = "myicon",
        //},
        data = new
        {
               body = messageBody,  // adding all notification information inside data
               title = messageTitle,
               icon = "myicon",
           }
       };

通过这样做,您的消息现在变成了仅数据消息,这意味着无论您的应用程序是在后台还是前台,它都会始终执行 FirebaseMessagingService 的 onMessageReceive()。

希望以上解释对您有所帮助。

关于android - 应用程序未运行时如何堆叠 Firebase Cloud Messaging 通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42273699/

相关文章:

java - 构建签名 APK 失败 - 找不到 [android/content/Context] 的通用父类(super class)

Android:某些手机上没有显示俄罗斯卢布货币?

javascript - 使用 firebase 查询 API 很痛苦?

ios - 在 NotificationService 中禁用从 didReceive 接收推送

firebase - flutter + Firebase | java.lang.IllegalStateException : FirebaseApp with name [DEFAULT] doesn't exist

android - 关于2019年4月11日后GCM实现Android应用(GCM废除)

react-native - 当应用程序在后台运行时使用振动

Android Broadcast Receiver 与 MainActivity 通信(向 Activity 发送数据)

java - 如何删除 Firebase 事件监听器?

ios - 将应用上传到 App Store 后,Firebase 号码身份验证不起作用