在Android 8.1 API 27上,通知未显示。

41

我在Android 8.1 API 27上收到Toast:

针对“my_package_name”软件包的开发人员警告
在...上发布通知失败。

Logcat包含以下字符串:

通知:使用流类型除音量控制外的操作已过时

W / Notification:请参阅setSound()的文档,了解如何使用android.media.AudioAttributes来限定您的播放用例,以代替使用流类型

E / NotificationService:未找到适用于pkg = my_package_name的频道

Toast和Logcat中的完整信息可以帮助定位此问题。


请发布代码。 - Samuel Robert
1
可能是Notifications fail to display in Android Oreo (API 26)的重复问题。 - Sky Kelsey
4个回答

98

如果出现此错误,应注意两个项目并按顺序进行:

  1. NotificationChannel mChannel = new NotificationChannel(id, name, importance);
  2. builder = new NotificationCompat.Builder(context, id);

另外,NotificationManager notifManager和NotificationChannel mChannel只创建一次。

通知需要设置以下必需的属性:

  • builder.setContentTitle() // 必需
  • .setSmallIcon() // 必需
  • .setContentText() // 必需

请参阅示例:

private NotificationManager notifManager;
public void createNotification(String aMessage, Context context) {
    final int NOTIFY_ID = 0; // ID of notification
    String id = context.getString(R.string.default_notification_channel_id); // default_channel_id
    String title = context.getString(R.string.default_notification_channel_title); // Default Channel
    Intent intent;
    PendingIntent pendingIntent;
    NotificationCompat.Builder builder;
    if (notifManager == null) {
        notifManager = (NotificationManager)context.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, title, importance);
            mChannel.enableVibration(true);
            mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
            notifManager.createNotificationChannel(mChannel);
        }
        builder = new NotificationCompat.Builder(context, id);
        intent = new Intent(context, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
        builder.setContentTitle(aMessage)                            // required
               .setSmallIcon(android.R.drawable.ic_popup_reminder)   // required
               .setContentText(context.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(context, id);
        intent = new Intent(context, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
        builder.setContentTitle(aMessage)                            // required
               .setSmallIcon(android.R.drawable.ic_popup_reminder)   // required
               .setContentText(context.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);
    }
    Notification notification = builder.build();
    notifManager.notify(NOTIFY_ID, notification);
}

1
  • 我已经设置了频道ID,但通知仍未显示;
  • 最终我发现我的问题是没有调用“setContentText()”方法;
  • 你提到的“必需的setter”真的帮了我很多!
- Jeffery Ma
工作正常。非常感谢 :) - Yesha
经过多个小时的尝试和错误,偶然发现了这个方法,太好了!谢谢。 - Maurice
1
非常棒的教程!!但是为了让它正常工作,我在if(SDK版本)中将NotificationCompat.Builder更改为Notification.Builder。 - San Juan

16

Andy的回答有效,但我想避免使用已弃用的 Builder,并遵循FireBase Quickstart项目。我只是在通知管理器之前添加了代码。

String channelId = "default_channel_id";
String channelDescription = "Default Channel";
// Since android Oreo notification channel is needed.
//Check if notification channel exists and if not create one
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
    NotificationChannel notificationChannel = notificationManager.getNotificationChannel(channelId);
    if (notificationChannel == null) {
        int importance = NotificationManager.IMPORTANCE_HIGH; //Set the importance level
        notificationChannel = new NotificationChannel(channelId, channelDescription, importance);
        notificationChannel.setLightColor(Color.GREEN); //Set if it is necesssary
        notificationChannel.enableVibration(true); //Set if it is necesssary
        notificationManager.createNotificationChannel(notificationChannel);
    }
}

//notificationManager.notify as usual

编辑:他们从示例中删除了通道存在检查,我不确定为什么。


10

我已经设置了渠道id,但通知仍未显示。

最后我发现我的问题是没有调用“setContentText()”方法。

真的很感谢@Andy Sander提到了“必需的setter”!

以下是Android 8 Oreo API 26及更高版本的通知所需的setter:

builder.setContentTitle() // required
.setSmallIcon() // required
.setContentText() // required
.setChannelId(id) // required for deprecated in API level >= 26 constructor .Builder(this)

1
有时候文档不够具体。 - filthy_wizard
你好 Allen,希望你一切都很好,请看一下我的问题 https://stackoverflow.com/questions/50748028/android-not-getting-notification-in-oreo-8-1-when-app-is-not-in-recent-task-but?noredirect=1#comment88503635_50748028 - Ankita Singh

4

还要记得将你的 channel_id 绑定到通知构建器上。绑定后,我的问题就解决了。

notificationBuilder.setChannelId(channelId)

或者
NotificationCompat.Builder(Context context, String channelId)

2
https://dev59.com/WlcO5IYBdhLWcg3wpjMz#45465542?s=2|291.3161#45465542 - Andy Sander
应该只使用第二种方法。 - barnacle.m

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