NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("textTitle")
.setContentText("textContent")
.setPriority(NotificationCompat.PRIORITY_DEFAULT); //设置通知重要性,支持 Android 7.1 及更低版本,
使用 NotificationCompat.Builder 对象设置通知的内容和渠道。以下示例展示了如何创建包含以下内容的通知:
小图标,通过 setSmallIcon() 设置。这是所必需的唯一用户可见内容。
标题,通过 setContentTitle() 设置。
正文文本,通过 setContentText() 设置。
通知优先级,通过 setPriority() 设置。优先级决定了通知在 Android 7.1 及更低版本上的干扰程度。对于 Android 8.0 及更高版本,请改为设置渠道重要性,如下一部分所示。
NotificationCompat.Builder
构造函数要求您提供渠道 ID。这是与 Android 8.0(API 级别 26)及更高版本兼容所必需的,但被早期版本忽略。
默认情况下,通知的文字内容会被截断以放在一行。您可以通过创建展开式通知显示更多信息。
图 1. 处于收起和展开状态的展开式通知
如果想要更长的通知,可以使用 setStyle() 添加样式模板,以启用可展开的通知。后面会介绍.
先将 NotificationChannel 的实例传递给 createNotificationChannel(),在系统中注册应用的通知渠道,然后才能在 Android 8.0 及更高版本上发送通知.
NotificationChannel
构造函数需要一个 importance
,它使用 NotificationManager 类中的一个常量。此参数确定对于属于此渠道的任何通知,如何干扰用户。将优先级设置为 setPriority()
,以支持 Android 7.1 及更低版本,如上例所示。
private void createNotificationChannel() {
// Android 8.0 及更高版本上发送通知,需要创建NotificationChannel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_DEFAULT;//设置通知重要性,针对Android 8.0 及更高版本上; 用setPriority()以支持 Android 7.1 及更低版本,
NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", importance);
channel.setDescription("channel_description");
// 向系统注册通知渠道,此后您无法更改重要性或其他通知行为。
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
如需显示通知,请调用 NotificaitonManagerCompat.notify() , 并向其传递通知的唯一 ID 和 NotificationCompat.Builder.build() 的结果。具体可见以下示例:
int NOTIFICATION_ID = 10 ; //唯一标识该通知,在更新和清除通知时需要
notificationManager.notify(NOTIFICATION_ID, builder.build());
注意: 从 Android 8.1(API 级别 27)开始,应用每秒最多只能发出一次通知提示音。如果应用在一秒内发布了多条通知,这些通知都会按预期显示,但每秒中只有第一条通知会发出声音。
void createBigTextStyleNotification() {
Intent intent = new Intent(this, MainActivity1.class);
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_MUTABLE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("BigTextStyle")
.setContentText("hi i am big text style notification")
.setContentIntent(pendingIntent);
//设置 BigTextStyle
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Much longer text that cannot fit one line...") //设置需要显示的内容
.setBigContentTitle("通知列表中,通知展开后,显示的标题") )
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManager notificationManager = (NotificationManager.class);
NotificationChannel channel = new NotificationChannel("11", "channel-name", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
notificationManager.notify(11, builder.build());
}
void createBigPictureStyleNotification() {
Intent intent = new Intent(this, MainActivity1.class);
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_MUTABLE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("BigPictureStyle")
.setContentText("hi i am big picture style notification")
.setContentIntent(pendingIntent);
//设置 BigPictureStyle
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.pictiure)) //设置需要展示的图片
.setBigContentTitle("通知列表中,通知展开后,显示的标题") )
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManager notificationManager = (NotificationManager.class);
NotificationChannel channel = new NotificationChannel("11", "channel-name", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
notificationManager.notify(11, builder.build());
}
通知最多可以提供三个操作按钮,以便用户快速响应,例如暂停提醒或回复短信。但这些操作按钮不能重复用户在 点按通知 时执行的操作。添加操作按钮,通过 addAction() 添加按钮的动作. 下面例子中,设定第一个Button的name="确定",点击后跳转到MainActivity1; 设定第二个Button的name="取消",点击后跳转到MainActivity2;
void createActionNotification() {
Intent intent1 = new Intent(MainActivity.this, MainActivity1.class);
Intent intent2 = new Intent(MainActivity.this, MainActivity2.class);
PendingIntent PendingIntent1 = PendingIntent.getActivity(MainActivity.this, 0, intent1, PendingIntent.FLAG_MUTABLE);
PendingIntent PendingIntent2 = PendingIntent.getActivity(MainActivity.this, 0, intent2, PendingIntent.FLAG_MUTABLE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Action Notification")
.setContentText("hi i am action notification")
.setColorized(true)
.setColor(Color.RED) //设置颜色
.setSubText("重要提醒") //设置 通知显示的一些附加信息
.addAction(R.mipmap.ic_launcher_round, "确定", PendingIntent1) //添加第一个按钮
.addAction(R.mipmap.ic_launcher_round, "取消", PendingIntent2) //添加第二个按钮
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManager notificationManager = (NotificationManager.class);
NotificationChannel channel = new NotificationChannel("11", "channel-name", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
notificationManager.notify(11, builder.build());
}
效果如下:
注意 :在 Android 10(API 级别 29)及更高版本中,如果应用不提供自己的通知操作按钮,平台会自动生成通知操作按钮。如果您不希望应用通知显示任何建议的回复或操作,可以使用 setAllowGeneratedRepies() 和 setAllowSystemGneratedContextualActions() 选择停用系统生成的回复和操作。
Android 7.0(API 级别 24)中引入的直接回复操作,可在通知中输入文本。然后,文本会传递给应用,而不会打开 activity。例如,您可以使用直接回复操作,让用户从通知中回复短信.
void createResultNotification() {
//1.定义回复的操作
Intent replyIntent = new Intent();
replyIntent.setAction("reply"); //定义广播的Action
replyIntent.setClass(MainActivity.this, NotificationReceiver.class);//如需要接收广播,请自行实现NotificationReceiver.class
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(MainActivity.this, (int) SystemClock.uptimeMillis(), replyIntent, PendingIntent.FLAG_MUTABLE);
//2.默认的回复内容,可以不设置
CharSequence[] choices = {"A.参加", "B.不参加", "C.需要考虑,晚间再回复"};
//3.添加回复按钮
RemoteInput remoteInput = new RemoteInput.Builder("key_text_reply") //key_text_reply是唯一标识该回复按钮
.setLabel("请输入回复的内容") //输入框的提示文字
.setChoices(choices)
.setEditChoicesBeforeSending(RemoteInput.EDIT_CHOICES_BEFORE_SENDING_DISABLED)//设置是否能编辑默认的回复内容
.build();
//4.创建回复操作并添加远程输入
NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.icon, "快速回复", replyPendingIntent) //输入编辑框的入口,点击该按钮后,便可编辑回复的内容,按钮的text="快速回复",有些手机定制化原因,可能会不显示,如下面例子
.addRemoteInput(remoteInput) //添加远程输入
.setAllowGeneratedReplies(false)
.build();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("聚餐通知")
.setContentText("请问今晚您会参加聚餐活动吗?")
.setColorized(true)
.setColor(Color.BLUE) //设置颜色
.setSubText("工作通知") //设置 通知显示的一些附加信息
.addAction(action)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManager notificationManager = (NotificationManager.class);
NotificationChannel channel = new NotificationChannel("11", "channel-name", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
notificationManager.notify(11, builder.build());
}
当用户触发通知操作时,系统会提示用户输入回复,效果如下图:
如需从通知的回复界面接收用户输入,调用 RemoteInput.getResultsFromIntent(), 在广播的onReceive() 中处理新通知.
private CharSequence getMessageText(Intent intent) {
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput != null) {
return remoteInput.getCharSequence(KEY_TEXT_REPLY); //获取远程输入的内容
}
return null;
}
KEY_TEXT_REPLY 是在上一图中3.添加回复按钮RemoteInput 中定义的.
通知可以包含动画形式的进度指示器,向用户显示正在进行的操作的状态。如下所示:
通过setProgress( int max, int progress, boolean false) ,操作在任何时间的完成进度,其中第一个参数是设置进度条的最大值(如100),默认为0; 第二个参数是当前的进度值。最后一个是否在通知中显示通知进度值。其中,通过在后台不断调用setProgress( int max, int progress, boolean false),将更新的progress当前值更新到通知中.
void createProgressNotification() {
int PROGRESS_MAX = 100; //最大值
int PROGRESS_CURRENT = 0; //当前值
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setPriority(NotificationCompat.PRIORITY_LOW)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.icon)) //设置大图片
.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false); // 设置进度, false:显示进度
NotificationManager notificationManager = (NotificationManager.class);
NotificationChannel channel = new NotificationChannel("11", "channel-name", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
notificationManager.notify(11, builder.build());
//模拟后台更新进度
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < PROGRESS_MAX ; i++) { //
builder.setProgress(PROGRESS_MAX ,i,false);
notificationManager.notify(15,builder.build());
builder.setContentText("下载中..."+i+"%");
try {
Thread.sleep(50);
}catch (InterruptedException e){
e.printStackTrace();
}
}
//当前进度值到达 PROGRESS_MAX=100 后,重新设置通知的标题和内容
builder.setContentTitle("start install!!")
.setContentText("installing.....")
.setProgress(0,0,true); //移除进度条
notificationManager.notify(15,builder.build());
try {
//清除通知
Thread.sleep(4000);
notificationManager.cancel(15);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}).start();
}
操作结束时,当前进度 progress 必须等于设定的最大值 max。当完成进度时,可以通过 setProgress(0,0,false) 来移除进度条.
如需显示不定的进度条(不指示完成百分比的进度条),调用 setProgress(0, 0, true)
。器。
显示进度的效果如下所示: