具有自定义外观的Android通知

时间:2018-04-24 06:28:11

标签: android firebase notifications firebase-cloud-messaging

截至目前,我正在使用Firebase云消息传递作为我的应用程序的通知系统。根据我的理解,即使是最大的公司也使用GCM,现在正在被FCM取代。然而,我被困在通过将事物作为“通知”工资负荷强加的限制。

Firebase在OnMessageRecieved中收到数据消息,我可以通过使用此功能获得我所需的确切行为。但是,在过去的三个月里,我注意到我的应用程序的通知根本无法正常工作,因为当应用程序处于后台/非活动状态时,未收到数据有效负载。这非常令人沮丧,因为我发现实际发送警报用户通知的唯一解决方法是发送通知有效负载。

我不知道如何使用通知有效负载获得我想要的行为,就像我使用数据有效负载一样,但是我意识到当应用程序位于前台时,如果它们不显示在应用程序处于前台,那么通知显示是完全没有意义的所有当应用程序在后台时。

我在想什么,以及我真正感谢指导的是,如果有人可以推荐一种方式来显示我想要的风格的通知,而不是默认的Firebase 通知风格。简单来说,我目前拥有一个功能齐全的系统,允许用户通过通知响应消息而无需打开应用程序,只能通过数据有效负载。

我知道有一种方法以某种方式以自定义方式发送通知(添加意图,按钮等),当应用程序在后台或未运行时,因为这是由Facebook,WhatsApp和许多其他应用程序完成的市场。我知道一些名为AlarmManagers的东西,但不知道如何使用它们来获得我想要的行为,或者这是否是人们使用的东西。

谢谢,如果有办法通过onMessagesRecieved或任何其他方法在应用程序处于后台或非活动状态时自定义有效负载,请告诉我。截至目前,唯一的其他解决方案是以某种方式将消息的内容发送到服务,但我遇到的问题是服务无法在后台显示通知而不会崩溃应用程序而且不会非常黑客。

1 个答案:

答案 0 :(得分:0)

我想出的唯一方法是仅发送数据有效载荷,无论应用程序处于何种状态(前景/背景),都应将其传递到onMessageReceived回调。

然后将所有必填字段放入数据有效负载并从中构建通知。这里的地图“数据”来自remoteMessage.getData()

private void sendNotification(Map<String, String> data) {
    String body = Optional.ofNullable(data.get("body")).orElse("");
    if (body.isEmpty()) {
        return;
    }

    Intent intent = new Intent(this, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    Uri sound = getSoundUri(Optional.ofNullable(data.get("sound")).orElse(""));
    String defaultChannel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
                                ? NotificationChannel.DEFAULT_CHANNEL_ID
                                : DEFAULT_CHANNEL_ID;

    String channel = Optional.ofNullable(data.get("android_channel_id")).orElse(defaultChannel);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channel)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(getString(R.string.app_name))
        .setContentText(body)
        .setAutoCancel(true)
        .setWhen(System.currentTimeMillis())
        .setShowWhen(true)
        .setContentIntent(resultPendingIntent);
    if (sound != null)
        notificationBuilder.setSound(sound);

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

    if (notificationManager != null)
        notificationManager.notify(0, notificationBuilder.build());
}