Android如何在任何应用程序的顶部弹出一个通知弹窗?

71

使用以下代码,我的通知只会添加到通知栏,不会像在其他应用程序中收到 WhatsApp 消息时那样显示弹出样式消息。是什么导致了这种情况?

private void sendNotification(int distance, ViewObject viewObject) {
    Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    notificationIntent.putExtra("path", viewObject.getPath());
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    stackBuilder.addParentStack(MainActivity.class);
    stackBuilder.addNextIntent(notificationIntent);
    PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(Integer.parseInt(viewObject.getRefId()), PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
    bigText.bigText(String.format(getString(R.string.notification), viewObject.getTitle()));
    bigText.setBigContentTitle(getString(R.string.hello));

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    builder.setSmallIcon(R.drawable.ic_wald_poi)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_poi))
            .setColor(getResources().getColor(R.color.primary))
            .setContentTitle(getString(R.string.hello))
            .setContentIntent(notificationPendingIntent)
            .setContentText(String.format(getString(R.string.notification), viewObject.getTitle()))
            .setDefaults(Notification.DEFAULT_ALL)
            .setStyle(bigText);

    builder.setAutoCancel(true);
    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(0, builder.build());
}
4个回答

147

如果您想使用像这样的 悬浮通知

enter image description here

您必须更改 Notification 优先级或 NotificationChannel 重要性。

通过 setPriority() 设置通知优先级。优先级决定了 Android 7.1 及以下版本上通知的侵入程度。(对于 Android 8.0 及更高版本,您必须设置通道重要性)

在 Android 7.1(API 级别 25)及以下版本上:

  • 将通知优先级设置为 NotificationCompat.PRIORITY_HIGHNotificationCompat.PRIORITY_MAX
  • 设置铃声和震动 - 您可以使用 setDefaults(Notification.DEFAULT_ALL)

在 Android 8.0(API 级别 26)及更高版本上:

  • 将通知通道优先级设置为 NotificationManager.IMPORTANCE_HIGH

通知:

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
            builder.setSmallIcon(R.drawable.ic_wald_poi)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_poi))
                    .setColor(getResources().getColor(R.color.primary))
                    .setContentTitle(getString(R.string.hello))
                    .setContentIntent(notificationPendingIntent)
                    .setContentText(String.format(getString(R.string.notification), viewObject.getTitle()))
                    .setDefaults(NotificationCompat.DEFAULT_ALL)
                    .setStyle(bigText)
                    .setPriority(NotificationCompat.PRIORITY_HIGH) // or NotificationCompat.PRIORITY_MAX

通知渠道:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    // Create the NotificationChannel
    val name = getString(R.string.notification_channel_name)
    val descriptionText = getString(R.string.notification_channel_description)
    val importance = NotificationManager.IMPORTANCE_HIGH
    val mChannel = NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance)
    mChannel.description = descriptionText
    // Register the channel with the system; you can't change the importance
    // or other notification behaviors after this
    val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    notificationManager.createNotificationChannel(mChannel)
}

重要提示

如果您想进一步定制频道的默认通知行为,可以在 NotificationChannel 上调用 enableLights()setLightColor()setVibrationPattern() 等方法。但请记住,一旦创建了该频道,就无法更改这些设置,用户有最终控制权决定这些行为是否激活。另外一种选择是卸载并重新安装应用程序。 阅读更多


可能触发悬浮通知的条件示例包括:

  • 用户的活动处于全屏模式(应用使用 fullScreenIntent)。
  • 通知具有高优先级,并在运行 Android 7.1(API 级别 25)及更低版本的设备上使用铃声或振动。
  • 通知渠道在运行 Android 8.0(API 级别 26)及更高版本的设备上具有高重要性。

优先级:

Notification.PRIORITY_HIGHNotification.PRIORITY_MAX 在 API 级别 26 中已过时。请改用 NotificationCompat

这里 有更多信息 :-)


2
现在 Notification.PRIORITY_HIGHNotification.PRIORITY_MAX 已经被弃用。 - pRaNaY
4
优先级不够,必须像我回答中所描述的那样有铃声或震动。在您的示例中,通知可以通过setDefaults()添加铃声和震动,但您没有提及。 - mbo
45
对于那些按照这些指示进行尝试的人,我观察到当在代码中更改重要性时,最好卸载该应用程序并重新安装它。否则,您可能无法看到通知小部件在重要性和外观方面的任何变化,这会浪费你数小时的时间。 - Hermann Klecker
2
@Herman,你是个大神,这个回答被接受了但是不起作用。我看了你的评论并尝试了一下,现在它可以工作了。 - Surya Reddy
1
@RediOne1 是的,我也用过这个。所以我觉得这种行为很奇怪,不知道可能是什么原因。另外,我想澄清一下,当应用程序在后台时,只有弹出窗口消失了,通知图标会带着声音出现。 - Ankush Chauhan
显示剩余8条评论

36

你必须将通知优先级设置为Notification.PRIORITY_HIGHNotification.PRIORITY_MAX。我还需要执行.setDefaults(Notification.DEFAULT_ALL)


9
在API级别26以下: 发送消息时,在Builder中设置Notification.PRIORITY_HIGH或Notification.PRIORITY_MAX。
在API级别26及以上: 设置通道优先级为高。
重要提示: 一旦通道已经建立了优先级,它就无法更改。如果它是低优先级,则不会显示弹出窗口,除非您重新安装应用程序。

5
谢谢,我可以确认重新安装后通知最终弹出。请确保频道的重要性永远不会改变。 - Irfandi D. Vendy
2
谢谢,这部分“一旦通道建立了优先级,就不能更改。如果它在LOW中,则不会显示弹出窗口,除非重新安装APP”是问题的关键。在我在代码中设置新的优先级后,我只需将我的通道ID更改为新的即可解决问题。 - Tommy89

5
Android系统会决定一个通知是否以Heads-up通知的形式显示。有一些条件可能会触发头部通知,例如:
- 用户的活动处于全屏模式(应用程序使用fullScreenIntent)。 - 通知具有高优先级并在运行Android 7.1(API级别25)及以下版本的设备上使用铃声或振动。 - 通知渠道在运行Android 8.0(API级别26)及更高版本的设备上具有重要性。
来源:https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Heads-up 因此,如果您使用的是Android 7.1及以下版本,请确保添加铃声或振动以及高优先级。对于Android 8.0及更高版本,请将优先级更改为高重要性
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
    // ...
    .setDefaults(DEFAULT_SOUND | DEFAULT_VIBRATE)
    .setPriority(NotificationCompat.PRIORITY_HIGH); // or HIGH_IMPORTANCE for Android 8.0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接