【问题标题】:Android Firebase notifications (FCM)Android Firebase 通知 (FCM)
【发布时间】:2017-05-04 03:36:26
【问题描述】:

我在我的应用中使用 FCM。我遵循了 Firebase 文档,一切似乎都按预期工作。

当应用程序被终止时,我能够在后台和前台接收消息通知。

现在我想通过添加一些应用偏好来完全控制用户。

  • 用户可以从应用设置中禁用所有通知
  • 用户可以从应用设置中更改通知铃声

当应用程序被杀死或在前台时,我有一个想法。我正在考虑访问我的 FirebaseMessagingService 中的 sharedprefs 以查看应用程序是否应该显示通知并检查要使用的铃声。除非有一种通用的方法来设置这些参数,例如“取消订阅”所有通知或更改我不知道的应用程序默认通知铃声?

但是我不知道如何处理应用程序在后台时收到的通知,因为通知已传递到设备的系统托盘。 任何人有任何想法或可以向我指出一些文档...我没有找到任何相关信息?

【问题讨论】:

  • 所以即使应用程序被终止或在后台运行,您也想显示来自共享偏好设置的通知视图和自定义声音?

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


【解决方案1】:

默认情况下,通知会影响每个用户。如果您希望允许用户选择退出所有通知(或某些通知子集),您应该使用topic messaging:默认情况下,您会为所有用户调用subscribeToTopic(),如果他们选择退出通知,你会打电话给unsubscribeToTopic()

通过向主题发送通知,只有订阅的用户会收到它。

notification payload support documentation 解释了如何包含 sound 参数来覆盖铃声 - 在 Android 上,它可以是应用程序的 res/raw 目录中捆绑的任何声音。

需要注意的是,控制台不支持这些功能,但需要您创建自己的Firebase Cloud Messaging Server

【讨论】:

    【解决方案2】:

    由于 firebase 通知服务有 2 个对象,第一个是“数据”,第二个是“通知”,当您从 firebase 控制台发送推送时,它会在“通知”对象中发送数据。当您在 FirebaseMessagingService.class 中处理通知时,您正在使用 NotificationBuilder 创建自定义通知。当应用程序处于后台时,您将无法从“通知”对象创建通知。因此,您的自定义通知不会出现在通知托盘中,您需要从后端推送通知并在“数据”对象中发送通知内容。您将能够每次自定义通知。 更多请参考:https://firebase.google.com/docs/cloud-messaging/android/send-multiple

    【讨论】:

      【解决方案3】:

      用户可以从应用设置中禁用所有通知。

      您可以按照您自己的说明使用共享首选项。就通用方法而言,您应该查看@ianhanniballake 的答案。

      用户可以从应用设置中更改通知铃声

      有关默认铃声,请参阅此link。此链接中的第三个答案还解释了如何从应用程序的设置活动中引入声音选择器。如果您想要自定义声音,请参阅 this

      当然,您必须存储用户偏好,这样您就不会每次都要求用户选择声音。

      还有一件事,因为您使用的是一项服务,因此您无需每次都访问共享首选项来查找要播放的声音,您可以将选择存储在任何变量中。每当用户更改通知声音时,您可以设置侦听器或{停止服务->更新首选项->重新启动服务}。确保每次服务启动时都会读取首选项。

      【讨论】:

        【解决方案4】:

        this AndroidHive 教程中,您可以了解我们如何为特定应用更改铃声,以及如何在应用处于前台和应用处于后台时处理通知。

        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
             ......
        
             // Check if message contains a notification payload.
            if (remoteMessage.getNotification() != null) {
                Log.e(TAG, "Notification Body: " + remoteMessage.getNotification().getBody());
                handleNotification(remoteMessage.getNotification().getBody());
            }
        }
        

        发送通知类型消息时,firebase 会在应用处于后台时自动显示通知。如果应用在前台,handleNotification() 方法会处理通知消息。

        private void handleNotification(String message) {
            if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) {
                // app is in foreground, broadcast the push message
                Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION);
                pushNotification.putExtra("message", message);
                LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
        
                // play notification sound
                NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
                notificationUtils.playNotificationSound();
            }else{
                // If the app is in background, firebase itself handles the notification
            }
        }
        

        在这里您可以处理自定义通知声音-

        // Playing notification sound
        public void playNotificationSound() {
            try {
                Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
                        + "://" + mContext.getPackageName() + "/raw/notification");
                Ringtone r = RingtoneManager.getRingtone(mContext, alarmSound);
                r.play();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        

        【讨论】:

          【解决方案5】:

          当您的应用处于后台或被终止时,Firebase 不会调用您的 onMessageReceived,并且您无法自定义通知。将显示系统生成的通知。

          让 firebase 库在每种情况下都调用你的 onMessageReived

          a) 前景

          b) 背景

          c) 被杀死

          您不能将 json 键“通知”放在对 firebase api 的请求中,而是使用“数据”,见下文。

          例如下面的消息不会调用 onMessagereceived()

            {
            "to": "/topics/test",
            "notification": {
              "title" : "title",
              "text": "data!",
              "icon": "ic_notification"
             }
          }
          

          但这会起作用

            {
            "to": "/topics/test",
             "data": {
                 "text":"text",
                 "title":"",
                 "line1":"testline",
                 "line2":"test"
             }
          } 
          

          查看此链接:https://firebase.google.com/docs/cloud-messaging/concept-options 它有firebase消息类型的详细描述 例如:

          @Override
          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());
              }
          
              if(remoteMessage.getData().get("state").toString().equals("Request")){
                  sendNotification(remoteMessage.getData().get("body").toString(), remoteMessage.getData().get("message").toString(), remoteMessage.getData().get("state").toString(),Activity_name.class);
              }
          }
          
              private void sendNotification(String messageBody, String data, String state,Class<?> activityCompat) {
                  int requestID = (int) System.currentTimeMillis();
                  Intent intent = new Intent(this, activityCompat);
                  Bundle bundle = new Bundle();
                  bundle.putString("message", data);
                  bundle.putString("state", state);
                  intent.putExtras(bundle);
                  PendingIntent pendingIntent = PendingIntent.getActivity(this, requestID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
          
                  NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                          .setSmallIcon(R.drawable.small_logo)
                          .setContentTitle("Title")
                          .setContentText(messageBody).setContentIntent(pendingIntent)
                          .setAutoCancel(true)
                          .setStyle(new NotificationCompat.BigTextStyle()
                                  .bigText(messageBody))
                          .setTicker(messageBody);
          
                  NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                  notificationBuilder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
                  Notification notification = notificationBuilder.build();
          
                  notificationManager.notify((int) Calendar.getInstance().getTimeInMillis(), notification);
          
              }
          

          【讨论】:

          • 如何确保如果应用程序被杀死,onMessageReceived() 仍然会被调用?有文档吗?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-06-18
          • 2022-08-15
          • 2017-07-01
          • 2018-04-14
          • 2017-01-12
          • 2017-02-03
          • 2019-04-13
          相关资源
          最近更新 更多