1. 创建基本通知
(1) 创建基本通知
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() 添加样式模板,以启用可展开的通知。后面会介绍.
(2) 创建渠道并设置重要性
先将 NotificationChannel 的实例传递给 createNotificationChannel(),在系统中注册应用的通知渠道,然后才能在 Android 8.0 及更高版本上发送通知.
NotificationChannel
构造函数需要一个 importance
,它使用 NotificationManager 类中的一个常量。此参数确定对于属于此渠道的任何通知,如何干扰用户。将优先级设置为 setPriority()
,以支持 Android 7.1 及更低版本,如上例所示。
private void createNotificationChannel() {// Android 8.0 及更高版本上发送通知,需要创建NotificationChannelif (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);}
}
(3) 设置通知的点按操作
如需显示通知,请调用 NotificaitonManagerCompat.notify() , 并向其传递通知的唯一 ID 和 NotificationCompat.Builder.build() 的结果。具体可见以下示例:
int NOTIFICATION_ID = 10 ; //唯一标识该通知,在更新和清除通知时需要notificationManager.notify(NOTIFICATION_ID, builder.build());
注意: 从 Android 8.1(API 级别 27)开始,应用每秒最多只能发出一次通知提示音。如果应用在一秒内发布了多条通知,这些通知都会按预期显示,但每秒中只有第一条通知会发出声音。
2 . 创建大文本通知 : BigTextStyle
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());}
3 . 创建大图片通知 : BigpictureStyle
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());}
4 . 创建带操作按钮的通知
通知最多可以提供三个操作按钮,以便用户快速响应,例如暂停提醒或回复短信。但这些操作按钮不能重复用户在 点按通知 时执行的操作。添加操作按钮,通过 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() 选择停用系统生成的回复和操作。
5. 创建带直接回复的通知
Android 7.0(API 级别 24)中引入的直接回复操作,可在通知中输入文本。然后,文本会传递给应用,而不会打开 activity。例如,您可以使用直接回复操作,让用户从通知中回复短信.
void createResultNotification() {//1.定义回复的操作Intent replyIntent = new Intent();replyIntent.setAction("reply"); //定义广播的ActionreplyIntent.setClass(MainActivity.this, NotificationReceiver.class);//如需要接收广播,请自行实现NotificationReceiver.classPendingIntent 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());}
当用户触发通知操作时,系统会提示用户输入回复,效果如下图:
(1) 从回复中检索用户输入
如需从通知的回复界面接收用户输入,调用 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 中定义的.
6. 创建带进度条的通知
通知可以包含动画形式的进度指示器,向用户显示正在进行的操作的状态。如下所示:
通过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() {@Overridepublic 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)
。器。
显示进度的效果如下所示: