Android Firebase通知(FCM)

时间:2016-12-19 06:01:07

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

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

我可以在应用程序被杀死时在后台和前台接收消息通知。

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

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

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

但是,由于通知被传送到设备的系统托盘,我不知道如何在应用程序处于后台时收到的通知中执行此操作。 任何人都有任何想法或可以指出我的一些文件...我没有找到任何关于此的信息?

5 个答案:

答案 0 :(得分:1)

默认情况下,通知会影响每个用户。如果您希望允许用户选择停用所有通知(或某些通知子集),则应使用topic messaging:默认情况下,您需要为所有通知subscribeToTopic()如果用户选择退出通知,则您需要拨打unsubscribeToTopic()

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

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

  

用户可以停用应用设置中的所有通知。

您可以按自己的说法使用共享偏好设置。就一般方法而言,你应该研究@ianhanniballake的答案。

  

用户可以从应用设置

更改通知铃声

对于默认铃声,请参阅此link。此链接中的第3个答案还说明了如何从应用程序的设置活动中调出声音选择器。如果您想要自定义声音,请参阅this

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

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

答案 3 :(得分:0)

this AndroidHive 教程中,您可以找到我们如何更改特定应用的铃声,以及当应用处于前台且应用处于后台时如何处理通知。

$lastId = null;
foreach($items as $item){

    /*get total num for rowspan*/
    $group = $buyer->get_total_rowspan($obj->id, $obj->supplier);

    echo '<tr>
             <td>$item->id</td>
             <td>$item->name</td>
             <td>$item->supplier</td>';

          if($lastId != $group->Id){
             <td rowspan="$group->countRow"><a>Manage</a></td>
          }

    echo '</tr>'

    $lastId = $group->Id;
}

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

@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());
    }
}

您可以在此处理自定义通知声音

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
    }
}

答案 4 :(得分:0)

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

使firebase库在每种情况下调用onMessageReived

a)前景

b)背景

c)被杀

你不能把你的请求中的json密钥“通知”放到firebase api中,而是使用“data”,见下文。

例如,以下消息不会调用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);

    }