问题:
使用 Notification 时,
1. Log 报错如下:
Line 5223: 03-07 11:49:20.121 1122 9346 E NotificationService: No Channel found for pkg=priv.xxx.demo, channelId=test, id=99, tag=null, opPkg=priv.xxx.demo, callingUid=10233, userId=0, incomingUserId=0, notificationUid=10233, notification=Notification(channel=test shortcut=null contentView=null vibrate=null sound=null defaults=0x0 flags=0x0 color=0x00000000 vis=PRIVATE)
2. 对应的 UI 提示:
Failed to post notification on channel "test". See log for more details.
分析
从Log和toast上看,应该是 channelId 一致性出了问题。
问题代码
public static void sendNotice(Context context) {
Log.i(TAG, "[sendNotice] ENTER, context = " + context);
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Android O (8.0)新增的 API about channel。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 使用NotificationChannel 类构建一个通知渠道
NotificationChannel notificationChannel = new NotificationChannel("99", "TEMP",
NotificationManager.IMPORTANCE_DEFAULT);
//通知的一些行为样式配置。
notificationChannel.enableLights(true); //是否在launcher icon右上角展示提示点
notificationChannel.setLightColor(Color.GREEN); //提示点颜色
notificationManager.createNotificationChannel(notificationChannel);
}
Notification.Builder builder = new Notification.Builder(context,"test");
builder.setContentTitle(context.getString(R.string.test_notification_title))
.setContentText(context.getString(R.string.test_notification_content))
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher);
Notification notification = builder.build();
notificationManager.notify(99, notification);
}
问题解决
将channelId的内容统一,即问题代码中的“99”和“text”,取其一即可。
// channelId 要统一。
// channelId可以随便定义,只要保证全局唯一性就可以。
// 渠道名称是给用户看的,需要可以清楚地表达这个渠道的用途。
new NotificationChannel("99", "TEMP",
NotificationManager.IMPORTANCE_DEFAULT);
new Notification.Builder builder = new Notification.Builder(context,"99");
Nofitication 的用法
参考:通知概览 | Android 开发者 | Android Developers (google.cn)
- 获取 NotificationManager 对通知进行管理
- 构建一个通知渠道 NotificationChannel
- 通过 Builder 创建 Notification ,配置其内容。
- 通过 manager 的notify() 显示通知
Note:关注 channelId 参数的统一
public static void sendNotice(Context context, String channelId) {
Log.i(TAG, "[sendNotice] ENTER, context = " + context);
//1.获取 NotificationManager 对通知进行管理。
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//2.构建一个通知渠道 NotificationChannel。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && channelId != null) {
NotificationChannel notificationChannel = new NotificationChannel(channelId, "TEMP",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(notificationChannel);
}
//3.通过 Builder 创建 Notification ,配置其内容。
Notification.Builder builder = new Notification.Builder(context, channelId);
builder.setContentTitle(context.getString(R.string.test_notification_title))
.setContentText(context.getString(R.string.test_notification_content))
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher);
Notification notification = builder.build();
//4.通过 manager 的notify() 显示通知。
notificationManager.notify(1, notification);
}
相关源码
NotificationChannel & Notification 的内部类 Builder
//android-30\android\app\NotificationChannel.java
/**
* Creates a notification channel.
*
* @param id The id of the channel. Must be unique per package. The value may be truncated if
* it is too long.
* @param name The user visible name of the channel. You can rename this channel when the system
* locale changes by listening for the {@link Intent#ACTION_LOCALE_CHANGED}
* broadcast. The recommended maximum length is 40 characters; the value may be
* truncated if it is too long.
* @param importance The importance of the channel. This controls how interruptive notifications
* posted to this channel are.
*/
public NotificationChannel(String id, CharSequence name, @Importance int importance) {
this.mId = getTrimmedString(id);
this.mName = name != null ? getTrimmedString(name.toString()) : null;
this.mImportance = importance;
}
// android-30\android\app\Notification.java
/**
* Constructs a new Builder with the defaults:
*
* @param context
* A {@link Context} that will be used by the Builder to construct the
* RemoteViews. The Context will not be held past the lifetime of this Builder
* object.
* @param channelId
* The constructed Notification will be posted on this
* {@link NotificationChannel}. To use a NotificationChannel, it must first be
* created using {@link NotificationManager#createNotificationChannel}.
*/
public Builder(Context context, String channelId) {
this(context, (Notification) null);
mN.mChannelId = channelId;
}
Other
很多教程指导都是罗列方法和代码使用案例,缺少一些关键注意点的指引。
我这样的小白有点按部就班的不解,有些坑就是新手才会碰到的。