通知 (以下分析基于Android N)
通知是您可以在应用的常规 UI 外部向用户显示的消息。当您告知系统发出通知时,它将先以图标的形式显示在通知区域中。用户可以打开抽屉式通知栏查看通知的详细信息。 通知区域和抽屉式通知栏均是由系统控制的区域,用户可以随时查看。
- 应用图标:通过setSmallIcon(MEIOS上无效,因为我们引入主题机制被系统强行替换)
- 应用名称:应用的名称系统自动获取并显示的
- 标题文本(可选):用于显示一些辅助信息,通过setSubText()来设置
- 时间戳(可选):默认不会显示setWhen(),setShowWhen()一起控制,或者setShowWhen()直接显示当前时间
- 展开通知按钮:用于控制可展开通知的折叠与展开状态
- 通知标题:通过setContentTitle()来设置
- 通知内容:通过setContentText()来设置
- 设置大图标:通过setLargeIcon()来设置
通知按钮的区域:当通知展开时就会显示出来(MEIOS无效)
通知Android官方规范链接
一、如何创建通知呢?
您可以在 NotificationCompat.Builder 对象中为通知指定 UI 信息和操作。要创建通知,请调用 NotificationCompat.Builder.build()(Notification.Builder.build()),它将返回包含您的具体规范的 Notification 对象。要发出通知,请通过调用 NotificationManager.notify() 将 Notification 对象传递给系统。
二、通知必须包含如下内容(不然会直接报异常)
Notification 对象必须包含以下内容:
- 小图标,由 setSmallIcon() 设置
- 标题,由 setContentTitle() 设置
- 详细文本,由 setContentText() 设置(这个好像在实际情况中可以不用强制)
三、可选通知内容和设置
- 快捷按钮,通过addAction()设置
- 添加带额外参数,通过addExtras()设置
- 带通知相关的联系人,通过addPersion()设置(正常用户用不到)
- 设置用户点击通知自动消失,通过setAutoCancel()设置
- 设置通知类别,通过setCategory()(总共有15中类别:CATEGORY_ALARM,CATEGORY_CALL,CATEGORY_EMAIL等等)
- 设置smallCollIcon的背景色,通过setColor设置
- 设置自定义通知布局,通过setContent()设置建议通过setCustomContentView()设置
- 在通知的右下角设置文本描述,通过setContentInfo()设置(Android N 以上被setSubText替换,因此该方法只有在Android N以下才会生效)
- 设置通知的点击事件,通过setContentIntent()设置
- 设置展开的自定义通知,通过setCustomBigContentView()设置
- setCustomHeadsUpContentView():设置自定义的横幅通知布局
- setDefaults():设置通知的默认提醒方式(包括: DEFAULT_SOUND, DEFAULT_VIBRATE, DEFAULT_LIGHTS,DEFAULT_ALL)
- setDeleteIntent():当通知被用户从通知栏删除时会发送一个Intent。
- setExtras():设置额外参数
- setFullScreenIntent():设置一个代替全屏的Intent,比如进行弹窗,启动一个Activity等
- setGroup():将此通知设置为共享同一密钥的通知组的一部分。
- setGroupSummary():将此通知设置为组通知的摘要 (待验证)
- setLargeIcon():设置一个大的图标在通知的右边
- setLights():设置LED显示
- setLocalOnly(): 设置该通知与当前设备相关联的(有些通知可以桥接到其他设备进行远程显示。 这个提示可以设置为推荐这个通知不被桥接。)
- setOngoing():设置通知是否是常驻通知
- setOnlyAlertOnce():更新Notification而不触发任何关联的闪灯、音频或者振动,也就是说只会提醒一次!
- setPriority():设置通知优先级
- setProgress():设置进度条
- setPublicVersion():设置开启隐藏通知内容时发出来的通知
- setRemoteInputHistory():设置通知输入的历史内容
- setShowWhen():设置通知的上时间撮是否显示
- setSortKey(): 设置通知组内的通知排序规则,如果有设置了优先级,那么可能导致这个值无效
- setSound():设置通知铃声
- setSubText():设置通知辅助内容,可以与setProgress一起使用用于显示进度百分比等
- setStyle(): 可以设置各种样式的通知(BigPictureStyle,BigTextStyle,DecoratedCustomViewStyle,InboxStyle,MediaStyle,MessagingStyle)
- setTicker(): 设置无障碍服务的Ticker文本。在Android L之前,设置通知首次到达时在状态栏中显示文本内容。
- setUsesChronometer():设置是否显示一个倒计时根据setWhen的值来进行倒计时
- setVibrate(): 设置震动
- setVisibility(): 设置通知在各种模式下的显示(VISIBILITY_SECRET:不在设置了密码的锁屏上显示,VISIBILITY_PUBLIC:在所有锁屏上全部显示此通知。 VISIBILITY_PRIVATE:在所有锁屏上显示此通知,但在安全锁屏上隐藏敏感或隐私信息。)
- setWhen():设置时间具体值与setShowWhen关联,默认是不显示时间戳。
三、创建基础通知
如下例子创建了一个最基础的通知其中设置了通知1、小图标。2、通知标题。3、通知内容。4、通知小图标背景色。5、通知右下角的大图标。等等功能。
final NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(getApplicationContext());
builder.setSmallIcon(R.drawable.ic_launcher_background);
builder.setContentTitle("这是一个简单通知的标题");
builder.setContentText("这是一个简单通知的内容");
builder.setColor(Color.RED);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.meitu_ic_bug_report));
builder.setOnlyAlertOnce(true);
builder.setSubText("这是SubText");
builder.setWhen(System.currentTimeMillis());
Intent intent = new Intent(MainActivity.this, MainActivity.class);
builder.setContentIntent(PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
builder.setShowWhen(true);
builder.setAutoCancel(true);
builder.setVibrate(new long[]{0, 300, 500, 700});
builder.setDeleteIntent(PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent("aaa"),0));
manager.notify(1, builder.build());
四、如何创建带扩展布局于通知
- InboxStyle类型通知(收件箱通知类型)
Notification.Builder builder = new Notification.Builder(getApplicationContext());
builder.setSmallIcon(R.drawable.ic_launcher_background);
builder.setContentTitle("这是一个简单通知的标题");
builder.setContentText("这是一个简单通知的内容");
Notification.InboxStyle inboxStyle = new Notification.InboxStyle();
String[] events = new String[6];
// 设置展开时候的标题
inboxStyle.setBigContentTitle("Event tracker details:");
for (int i = 0;i
- BigPicture类型通知:可以携带大图片的通知
Notification.Builder builder = new Notification.Builder(getApplicationContext());
builder.setSmallIcon(R.drawable.ic_launcher_background);
builder.setContentTitle("这是一个简单通知的标题");
builder.setContentText("这是一个简单通知的内容");
Notification.BigPictureStyle bigPictureStyle = new Notification.BigPictureStyle();
bigPictureStyle.bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.bigpicture));
builder.setStyle(bigPictureStyle);
manager.notify(1, builder.build());
- BigText类型通知:大文本内容的通知
Notification.Builder builder = new Notification.Builder(getApplicationContext());
builder.setSmallIcon(R.drawable.ic_launcher_background);
builder.setContentTitle("这是一个简单通知的标题");
builder.setContentText("这是一个简单通知的内容");
Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle();
bigTextStyle.bigText("这是一个BitTextStyle这是一个BitTextStyle这是一个BitTextStyle这是一个BitTextStyle" +
"这是一个BitTextStyle这是一个BitTextStyle这是一个BitTextStyle");
builder.setStyle(bigTextStyle);
manager.notify(1, builder.build());
- Messaging类型通知:
Notification.Builder builder = new Notification.Builder(getApplicationContext());
builder.setSmallIcon(R.drawable.ic_launcher_background);
builder.setContentTitle("这是一个简单通知的标题");
builder.setContentText("这是一个简单通知的内容");
Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("Me");
messagingStyle.setConversationTitle("Team lunch");
messagingStyle.addMessage("Hi", System.currentTimeMillis(), null)
.addMessage("What's up?", System.currentTimeMillis(), "Coworker")
.addMessage("Not much", System.currentTimeMillis(), null)
.addMessage("How about lunch?", System.currentTimeMillis(), "Coworker");
builder.setStyle(messagingStyle);
manager.notify(1, builder.build());
- Media类型通知: 添加的按钮数量最多只能3个在折叠状态,如果是在展开大布局状态那么就允许显示5个
Notification.Builder builder = new Notification.Builder(getApplicationContext());
builder.setSmallIcon(R.drawable.ic_launcher_background);
builder.setContentTitle("这是一个简单通知的标题");
builder.setContentText("这是一个简单通知的内容");
Notification.MediaStyle mediaStyle = new Notification.MediaStyle();
mediaStyle.setMediaSession(new MediaSession(MainActivity.this,"test").getSessionToken());
builder.addAction(new Notification.Action(R.drawable.ic_launcher_background, "test1", null));
builder.addAction(new Notification.Action(R.drawable.meitu_ic_bug_report, "test2", null));
int[] actions = new int[2];
mediaStyle.setShowActionsInCompactView(actions);
builder.setStyle(mediaStyle);
manager.notify(1, builder.build());
- DecoratedCustomView样式通知:装饰自定义通知布局达到与原生的样式一致
Notification.Builder builder = new Notification.Builder(getApplicationContext());
builder.setSmallIcon(R.drawable.ic_launcher_background);
builder.setContentTitle("这是一个简单通知的标题");
builder.setContentText("这是一个简单通知的内容");
RemoteViews contentView = new RemoteViews(MainActivity.this.getPackageName(), R.layout.notification_show);
contentView.setChronometer(R.id.chronometer, 10000, "%s", true);
builder.setCustomContentView(contentView);
builder.setStyle(new Notification.DecoratedCustomViewStyle());
manager.notify(1, builder.build());
- 发送可直接回复通知:可回复通知分为两个部分:1、发送部分。2、接收部分
a. 发送部分:
private static final String KEY_TEXT_REPLY = "key_text_reply";
public static String REPLY_ACTION = "com.meitu.directreply.REPLY";
public static String REQUEST_CODE = "request_code";
//获取一个NotificationManager
mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
// 创建一个可添加到通知操作的RemoteInput对象,这个对象指定了这个notification的标题和一个key。发送通知者可以通过这个key来检索并获得用户输入的文本
mRemoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel("This is a reply label").build();
// 创建一个Action对象 可以指定用户一个友好的输入提示,或者跳转等等
mIntent = new Intent(REPLY_ACTION)
.setAction(REPLY_ACTION)
.putExtra(REQUEST_CODE, requestCode);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, requestCode, mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Action action = new Notification.Action.
Builder(R.drawable.ic_volume_alarm,"请在此输入内容", pendingIntent)
.addRemoteInput(mRemoteInput)
.build();
// 创建一个Notification对象(这个就是正常的通知)
Notification notification = new Notification.Builder(MainActivity.this)
.setSmallIcon(R.drawable.ic_volume_alarm)
.setContentTitle("Title")
.setContentText("Text")
.addAction(action)
.build();
// 发送通知
mNotificationManager.notify(1,notification);
b. 接收部分:
// 由于本例中是使用发送广播的形式来的,因此此处我注册了一个广播接收器
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(REPLY_ACTION)){
mTextView.setText(getMessageText(intent));
// 1、App接收到了数据需要更新下(或者取消)通知不然会导致通知栏那边滚动条一直在滚动
// Notification repliedNotification = new Notification.Builder(MainActivity.this)
// .setSmallIcon(R.drawable.ic_volume_alarm)
// .setContentText("回复了").build();
// mNotificationManager.cancel(1,repliedNotification);
// 2、App可以在用户输入完内容并接收到的时候取消该通知,避免通知栏滚动条一直在滚动
mNotificationManager.cancel(1);
// 3、等
}
}
};
// 通过传递通知操作的Intent作为参数,调用RemoteInput的getResultFromIntent()获取用户输入的内容。该方法返回包含有回复的Bundle,Key就是指定给RemoteInput中的Key“KEY_TEXT_REPLY”。
private String getMessageText(Intent intent){
Bundle bundle = RemoteInput.getResultsFromIntent(intent);
if(bundle != null){
return bundle.getString(KEY_TEXT_REPLY);
}
return null;
}
常见的问题
参考链接
1、Android N 新特性
2、通知
3、Notifications Designs