简体   繁体   English

通知无法在Android Oreo(API 26)中显示

[英]Notifications fail to display in Android Oreo (API 26)

I get this message when trying to display a notification on Android O. 尝试在Android O上显示通知时收到此消息。

Use of stream types is deprecated for operations other than volume control 对于音量控制以外的其他操作,不建议使用流类型

The notification is straight from the example docs, and displays fine on Android 25. 该通知直接来自示例文档,并在Android 25上正常显示。

Per the comments on this Google+ post : 根据对此Google+信息的评论:

those [warnings] are currently expected when using NotificationCompat on Android O devices ( NotificationCompat always calls setSound() even if you never pass in custom sound). 当前在Android O设备上使用NotificationCompat时会出现这些[警告] setSound()即使您从不传递自定义声音, NotificationCompat setSound()始终调用setSound() )。

until the Support Library changes their code to use the AudioAttributes version of setSound , you'll always get that warning. 在支持库将其代码更改为使用AudioAttributes版本setSound ,您将始终收到该警告。

Therefore there's nothing that you can do about this warning. 因此,您无法对此警告采取任何措施。 As per the notification channels guide , Android O deprecates setting a sound on an individual notification at all, instead having you set the sound on a notification channel used by all notifications of a particular type. 根据通知渠道指南 ,Android O完全不建议在单个通知上设置声音,而是让您在特定类型的所有通知使用的通知渠道上设置声音。

Starting with Android O, you are required to configure a NotificationChannel , and reference that channel when you attempt to display a notification. 从Android O开始,您需要配置NotificationChannel ,并在尝试显示通知时引用该通道。

private static final int NOTIFICATION_ID = 1;
private static final String NOTIFICATION_CHANNEL_ID = "my_notification_channel";

...

NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_DEFAULT);

  // Configure the notification channel.
  notificationChannel.setDescription("Channel description");
  notificationChannel.enableLights(true);
  notificationChannel.setLightColor(Color.RED);
  notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
  notificationChannel.enableVibration(true);
  notificationManager.createNotificationChannel(notificationChannel);
}

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
  .setVibrate(new long[]{0, 100, 100, 100, 100, 100})
  .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
  .setSmallIcon(R.mipmap.ic_launcher)
  .setContentTitle("Content Title")
  .setContentText("Content Text");

  notificationManager.notify(NOTIFICATION_ID, builder.build());

A couple of important notes: 一些重要的注意事项:

  1. Settings such as vibration pattern specified in the NotificationChannel override those specified in the actual Notification . NotificationChannel指定的设置(例如振动模式)会覆盖实际Notification指定的设置。 I know, its counter-intuitive. 我知道,这违反直觉。 You should either move settings that will change into the Notification, or use a different NotificationChannel for each configuration. 您应该将将更改设置更改为Notification,或者对每个配置使用不同的NotificationChannel。
  2. You cannot modify most of the NotificationChannel settings after you've passed it to createNotificationChannel() . NotificationChannel设置传递给createNotificationChannel()后,您将无法对其进行修改。 You can't even call deleteNotificationChannel() and then try to re-add it. 您甚至无法调用deleteNotificationChannel() ,然后尝试重新添加它。 Using the ID of a deleted NotificationChannel will resurrect it, and it will be just as immutable as when it was first created. 使用已删除的NotificationChannel的ID将重新启用它,并且它与第一次创建时一样不变。 It will continue to use the old settings until the app is uninstalled. 在卸载应用程序之前,它将继续使用旧设置。 So you had better be sure about your channel settings, and reinstall the app if you are playing around with those settings in order for them to take effect. 因此,您最好确定自己的频道设置,如果正在使用这些设置,请重新安装该应用程序,以使它们生效。

All that @sky-kelsey has described is good, Just minor additions : @ sky-kelsey所描述的一切都是好的, 只是一些小的补充

You should not register same channel every time if it has been already registered, so I have Utils class method that creates a channel for me: 如果已经注册了同一频道,则不应每次都注册该频道,因此我有Utils类方法可以为我创建一个频道:

public static final String NOTIFICATION_CHANNEL_ID_LOCATION = "notification_channel_location";

public static void registerLocationNotifChnnl(Context context) {
    if (Build.VERSION.SDK_INT >= 26) {
        NotificationManager mngr = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
        if (mngr.getNotificationChannel(NOTIFICATION_CHANNEL_ID_LOCATION) != null) {
            return;
        }
        //
        NotificationChannel channel = new NotificationChannel(
                NOTIFICATION_CHANNEL_ID_LOCATION,
                context.getString(R.string.notification_chnnl_location),
                NotificationManager.IMPORTANCE_LOW);
        // Configure the notification channel.
        channel.setDescription(context.getString(R.string.notification_chnnl_location_descr));
        channel.enableLights(false);
        channel.enableVibration(false);
        mngr.createNotificationChannel(channel);
    }
}

strings.xml: strings.xml:

<string name="notification_chnnl_location">Location polling</string>
<string name="notification_chnnl_location_descr">You will see notifications on this channel ONLY during location polling</string>

And I call the method every time before I'm going to show a notification of the type: 而且,我每次都会显示该类型的通知之前都调用该方法:

    ...
    NotificationUtil.registerLocationNotifChnnl(this);
    return new NotificationCompat.Builder(this, NotificationUtil.NOTIFICATION_CHANNEL_ID_LOCATION)
            .addAction(R.mipmap.ic_launcher, getString(R.string.open_app),
                    activityPendingIntent)
            .addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.remove_location_updates),
                    servicePendingIntent)
            .setContentText(text)
            ...

Another typical problem - channel default sound - described here: https://stackoverflow.com/a/45920861/2133585 另一个典型的问题-通道默认声音-在此处描述: https//stackoverflow.com/a/45920861/2133585

In Android O it's a must to use a NotificationChannel and NotificationCompat.Builder is deprecated ( reference ). 在Android O中,必须使用NotificationChannelNotificationCompat.Builder已过时( 参考 )。

Below is a sample code : 以下是示例代码:

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(mContext.getApplicationContext(), "notify_001");
Intent ii = new Intent(mContext.getApplicationContext(), RootActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, ii, 0);

NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
bigText.bigText(verseurl);
bigText.setBigContentTitle("Today's Bible Verse");
bigText.setSummaryText("Text in detail");

mBuilder.setContentIntent(pendingIntent);
mBuilder.setSmallIcon(R.mipmap.ic_launcher_round);
mBuilder.setContentTitle("Your Title");
mBuilder.setContentText("Your text");
mBuilder.setPriority(Notification.PRIORITY_MAX);
mBuilder.setStyle(bigText);

NotificationManager mNotificationManager =
        (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationChannel channel = new NotificationChannel("notify_001",
            "Channel human readable title",
            NotificationManager.IMPORTANCE_DEFAULT);
    mNotificationManager.createNotificationChannel(channel);
}

mNotificationManager.notify(0, mBuilder.build());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 应用程序在后台运行时未收到Oreo(API 26)通知 - Oreo (API 26) Notifications not received when app in background 通知Oreo API 26-正常运行,但现在无法运行 - Notifications oreo api 26 - were working perfectly, now they're not android app 26 api中的通知 - Notifications in android app 26 api Android Oreo(API26)和android.app.DownloadManager - Android Oreo (API26) and android.app.DownloadManager 如何在Android 8(API 26,Oreo)上使用片段过渡 - How to use Fragment transition on Android 8 (API 26, Oreo) Android Oreo(API 26) - 在外部存储中创建目录 - Android Oreo (API 26) - Create dir in external storage onTaskRemoved()在Android 8.0 Oreo API级别26上不起作用 - onTaskRemoved() doesn't work on Android 8.0 Oreo API level 26 无法在 android oreo(API 级别 26)上以设备管理员身份激活应用 - Unable to activate app as device admin on android oreo(API level 26) 如何更改Android O / Oreo / api 26应用程序语言 - How to change Android O / Oreo / api 26 app language Android API 26(Oreo)从Internet下载数据文件 - Android API 26 (Oreo) downloading data files from the Internet
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM