如何在安卓8.0或更高版本显示悬浮通知

12

我认为在Android 8.0中,抬头通知被禁用了,但是即使在运行Android 8.0的情况下,Android内置消息仍具有此功能。我知道如何通过将振动设置为通知来显示低于8.0设备的提醒通知。但是,在运行Oreo的通知上,通知上的振动已过时。所以我去搜索互联网,有人说启用setVibrationPattern到通知渠道会起作用。但可悲的是,这样不起作用。

以下是我的代码。

Notification  builder = new NotificationCompat.Builder(MainActivity.this)
                            .setAutoCancel(true)
                            .setWhen(System.currentTimeMillis())
                            .setSmallIcon(R.drawable.ic_android_black_24dp)
                            .setChannelId(id)
                            .setPriority(Notification.PRIORITY_HIGH)
                            .setColor(setActionColor(counter))
                            .setColorized(true)
                            .setContentIntent(pendingIntent)
                            .build();

//Notification channel code.

NotificationChannel chan2 = new NotificationChannel(SECONDARY_CHANNEL,
                            getString(R.string.noti_channel_second), NotificationManager.IMPORTANCE_HIGH);
                    chan2.setLightColor(Color.BLUE);
                    chan2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
                    manager.createNotificationChannel(chan2);
                    manager.notify(notificationID, builder);

你尝试过使用notificationBuilder.setPriority(Notification.PRIORITY_HIGH)吗? - lib4backer
是的,但可悲的是没有起作用。 - Rk215 Tech
您可能需要创建通知渠道以支持在Android 8上的悬浮通知。 - lib4backer
4
你尝试重新安装应用程序了吗?我的代码结构类似,可以获得悬浮通知。我发现,如果你在首次编译应用程序时没有正确设置优先级(应该是 NotificationBuilder.setPriority(Notification.PRIORITY_HIGH) 和通知渠道的 NotificationManager.IMPORTANCE_HIGH),即使你在代码中进行了更正并重新编译了应用程序,它也不起作用。 - TimeString
6个回答

27

晚回答:但我认为值得分享。 我正在做与上述相同的事情,但在Oreo中,Heads-up notifications不会显示。

Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationManager notificationManager = 
        (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationChannel notificationChannel = 
        new NotificationChannel("ch_nr", "CHART", NotificationManager.IMPORTANCE_HIGH);
    notificationChannel.setVibrationPattern(new long[]{300, 300, 300});

    if (defaultSoundUri != null) {
        AudioAttributes att = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build();
        notificationChannel.setSound(defaultSoundUri, att);
    }

    notificationManager.createNotificationChannel(notificationChannel);
    notificationBuilder = 
        new NotificationCompat.Builder(context, notificationChannel.getId());
}

核心代码在上面。问题是我每次在设备上重写构建,而且importance没有改变为高。我直到阅读了这篇文档才明白。

重要性级别有以下限制:

您分配的重要性级别将成为通道的默认值。用户可以在 Android 设置中更改通道的重要性级别。选择重要性级别后,您受到如何更改它的限制:只能降低重要性,而且仅当用户没有显式更改时才能这样做。

结论:在升级通知渠道的重要性之前,完全卸载先前的构建或清除数据(不确定)。


3
在更改通知代码时,卸载通常是一个好主意。感谢你强迫我不再那么懒惰,这对我很有帮助。 - Lou Morda
1
非常有帮助。在卸载之前,我的代码无法工作。非常感谢。 - dazed
1
谢谢!我以为我要疯了,但是你帮了我。 - Sirelon
1
谢谢!你救了我 :) 我卸载了应用程序并重新运行。它可以工作了! - BurtK

13

您可以通过这种方式来实现...这在每个Android版本上都有效。

private NotificationManager notifManager;
public void createNotification(String aMessage) {
    final int NOTIFY_ID = 1002;

    // There are hardcoding only for show it's just strings
    String name = "my_package_channel";
    String id = "my_package_channel_1"; // The user-visible name of the channel.
    String description = "my_package_first_channel"; // The user-visible description of the channel.

    Intent intent;
    PendingIntent pendingIntent;
    NotificationCompat.Builder builder;

    if (notifManager == null) {
        notifManager =
                (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel mChannel = notifManager.getNotificationChannel(id);
        if (mChannel == null) {
            mChannel = new NotificationChannel(id, name, importance);
            mChannel.setDescription(description);
            mChannel.enableVibration(true);
            mChannel.setLightColor(Color.GREEN);
            mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
            notifManager.createNotificationChannel(mChannel);
        }
        builder = new NotificationCompat.Builder(this, id);

        intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

        builder.setContentTitle(aMessage)  // required
                .setSmallIcon(android.R.drawable.ic_popup_reminder) // required
                .setContentText(this.getString(R.string.app_name))  // required
                .setDefaults(Notification.DEFAULT_ALL)
                .setAutoCancel(true)
                .setContentIntent(pendingIntent)
                .setTicker(aMessage)
                .setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
    } else {

        builder = new NotificationCompat.Builder(this);

        intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

        builder.setContentTitle(aMessage)                           // required
                .setSmallIcon(android.R.drawable.ic_popup_reminder) // required
                .setContentText(this.getString(R.string.app_name))  // required
                .setDefaults(Notification.DEFAULT_ALL)
                .setAutoCancel(true)
                .setContentIntent(pendingIntent)
                .setTicker(aMessage)
                .setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400})
                .setPriority(Notification.PRIORITY_HIGH);
    } // else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

    Notification notification = builder.build();
    notifManager.notify(NOTIFY_ID, notification);
}

1
无论你现在在哪里,我只想让你知道,非常感谢你!与旧的API相比,Oreo中的通知变得如此复杂。我需要一个示例来做参考,这个真的非常好。 - Mark Lapasa

4

您还需要在“设置”中设置应用通知设置为“紧急”。除非用户将应用程序设置为紧急,否则不会出现弹窗式通知。


感谢您的回答,我已经自己解决了这个问题。问题是 ROM 不允许所有应用程序都弹出通知,除了内置短信应用程序。 - Rk215 Tech
@Rk215Tech,您能否提供您看到的仅启用内置消息应用程序的 heads-up 的参考资料?我发现像 FB Messenger 和 Venmo 这样的应用程序也可以在 Android 8.0 上显示 heads-up。 - TimeString

2
注意通知可以通过创建通知渠道并执行以下操作来工作。
NotificationChannel chan2 = new NotificationChannel(SECONDARY_CHANNEL,
                getString(R.string.noti_channel_second), NotificationManager.IMPORTANCE_HIGH);
        chan2.setLightColor(Color.BLUE);
        chan2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        getManager().createNotificationChannel(chan2);

0
在一些手机中,有状态栏和通知设置,如果将通知的顶部预览设置为不预览,则不允许任何应用程序显示悬浮通知,将其设置为横幅将解决您的问题,如果您已经正确设置了通道和通知。
我在Android 9操作系统,Vivo y1902手机中遇到了同样的问题,通过进行上述更改后问题得到解决。

0

您正在设置错误的频道ID。

setChannelId(String channelId)指定应在其上传递通知的频道。

在您的示例中,您将某个id设置为通知生成器:setChannelId(id),然后创建一个未指定的新辅助频道:chan2


这是我的工作示例:

private static final String CHANNEL_ID = "CHANNEL_NO_1";

    public void sendNotification(Context context) {

       // Create your notification channel 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            CharSequence name = "New riddle";
            String description = "Riddle of the day";
            int importance = NotificationManager.IMPORTANCE_HIGH;

            // IMPORTANT: CHANNEL_ID
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID,name, importance);
            channel.setDescription(description);


            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }


        // Get an instance of NotificationManager
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
                .setSmallIcon(R.drawable.ic_launcher)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setContentTitle("Riddle of the day:")

                //IMPORTANT: CHANNEL_ID
                .setChannelId(CHANNEL_ID)

        // It won't show "Heads Up" unless it plays a sound     
        if (Build.VERSION.SDK_INT >= 21) mBuilder.setVibrate(new long[0]);


        // Gets an instance of the NotificationManager service//
        NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);


        mNotificationManager.notify(001, mBuilder.build());
    }

还有一件事,确保在进行这些更改后重新安装您的应用程序。


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