通知的显示方式有所不同,具体取决于应用程序是在前台还是在后台

时间:2018-09-27 09:45:17

标签: java android android-notifications

我在Android上遇到通知问题。每当我的应用收到GCM消息时,我都会使用以下代码在设备上生成通知。但是,它产生了意外的结果。

public class MyGcmListenerService extends GcmListenerService implements Constants {
    private static final String TAG = "MyGcmListenerService";

    @Override
    public void onMessageReceived(String from, Bundle data) {
        String message = data.getString("msg");
        sendNotification(message);
    }

    private void sendNotification(String message) {
        NotificationManager notificationManager =
                (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.gcm_notification_channel_name);
            String description = getString(R.string.gcm_notification_channel_description);
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel channel = new NotificationChannel(GCM_NOTIFICATION_CHANNEL_ID, name,
                    importance);
            channel.setDescription(description);
            channel.setLockscreenVisibility(NotificationCompat.VISIBILITY_PUBLIC);
            channel.enableVibration(true);
            channel.setSound(defaultSoundUri,
                    new AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                        .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT)
                        .build());
            notificationManager.createNotificationChannel(channel);
        }

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this,
                GCM_NOTIFICATION_CHANNEL_ID)
                .setContentText(message)
                .setContentTitle("My Title")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setSmallIcon(R.drawable.ic_notification);

        notificationManager.notify(0, notificationBuilder.build());
    }
}

如果在打开应用程序时收到了GCM消息(不仅正在运行,而是在屏幕上实际打开了),则生成的通知只有标题,并且不显示消息。 This screenshot演示了这种情况。此外,如果我在应用程序处于前台状态时向设备发送多条GCM消息,则只会显示一条消息。

如果在应用关闭或在后台运行时收到消息,则生成的通知仅显示消息,没有标题。 This screenshot并排显示了两条消息-最下面的一条消息是前台应用程序接收的,最上面的一条消息是后台应用程序接收的。如果在应用程序处于后台时收到多条消息,则会显示所有消息(与应用程序在前台时发生的情况相反)。 This screenshot显示,在后台通过应用程序收到消息时会显示多条消息。

此外,当应用程序位于前台时,通知仅显示为heads-up

最后,如果在前台收到,则在点击时生成的通知将不执行任何操作。但是,如果在后台收到通知,则在点击时通知会打开应用程序。对此并没有真正打扰,只是认为这可能是问题的征兆。

仅供参考:在测试时,我尝试过每次都将GCM消息保持相同,以及对其进行更改。两种情况都得出相同的结果。

我想知道的事情:

  • 无论应用程序是否在前台,都如何显示标题和消息。这是最重要的。

  • 当应用程序在后台时如何以通知形式显示通知。

根据我们的用户的说法,只是先占任何不要滥用提示的回答,这是该应用程序的最重要功能(该应用程序必须实时通知用户某些事件)。

更新:

Bas van Stein的answer让我弄清楚为什么只显示标题或消息。

正如他正确指出的那样,当应用程序在后台运行时,GCM消息由系统处理。这促使我检查了后端用于发送消息的脚本。我意识到编写此脚本的人已经在GCM消息的title字段的notification字段中发送了消息,而没有body字段。因此,我更正了此问题,并正确显示了通知(针对后台应用程序)。

这也使我意识到String message = data.getString("msg");中的行onMessageReceived返回了null。我将方法更改如下:

public void onMessageReceived(String from, Bundle data) {
    Bundle notification = data.getBundle("notification");
    String title = notification.getString("title");
    String message = notification.getString("body");

    sendNotification(title, message);
}

然后,我将title作为参数添加到sendNotification,并将设置通知标题的行更改为:.setContentTitle(title)。现在,当应用程序位于前台时,通知会正确显示。

此外,我在用作通知ID的类中添加了static int(每次递增),因此现在可以正确显示多个通知。

仍未解决:

当应用程序在后台运行时,我仍然无法以提示形式显示通知。我尝试将"priority": "high"添加到GCM消息notification负载中,但这没有任何效果-显然,这仍然是GCM通知的默认值。

1 个答案:

答案 0 :(得分:1)

此答案只是完整解决方案的一部分,但我们开始:

第一个问题,后台和前台通知似乎是由两个不同的函数生成的,您可以通过在代码中应用断点并连接调试器来进行测试。您可能会看到后台通知未在此代码中触发断点。也许您错过了清单服务?

第二个问题,仅显示一条通知是由于以下原因:

notificationManager.notify(0, notificationBuilder.build());

这里的0是通知ID,如果您创建多个具有相同ID的通知,它将覆盖该通知,而不是显示新的通知。

第三个问题,未在通知选项卡上打开该应用程序,是因为您在代码中生成的通知没有附加意图。

您可以将以下内容用于意图:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent,
             PendingIntent.FLAG_ONE_SHOT);
notificationBuilder.setContentIntent(pIntent);

单击通知时将调用该意图,这可以是任何意图,因此您可以打开一个特殊的活动。

希望这会带给您正确的方向。