相关文档:
Android基础——Notification使用浅析(一)
1. 设置优先级
优先级 | 描述 |
---|---|
Notification.PRIORITY_MAX | 重要而紧急的通知,通知用户这个事件是时间上紧迫的或者需要立即处理的。 |
Notification.PRIORITY_HIGH | 高优先级用于重要的通信内容,例如短消息或者聊天,这些都是对用户来说比较有兴趣的 |
Notification.PRIORITY_DEFAULT | 默认优先级用于没有特殊优先级分类的通知 |
Notification.PRIORITY_LOW | 低优先级可以通知用户但又不是很紧急的事件。只显示状态栏图标 |
Notification.PRIORITY_MIN | 用于后台消息 (例如天气或者位置信息)。只有用户下拉通知抽屉才能看到内容 |
builder.setPriority(Notification.PRIORITY_HIGH);
2. 事件
提供了 铃声/振动/呼吸灯 三种提醒方式,可以使用一种或同时使用多种
FLAG | 描述 |
---|---|
Notification.DEFAULT_SOUND | 添加默认声音提醒 |
Notification.DEFAULT_VIBRATE | 添加默认震动提醒 |
Notification.DEFAULT_LIGHTS | 添加默认呼吸灯提醒 |
Notification.DEFAULT_ALL | 时添加以上三种默认提醒 |
// 添加默认声音提醒
builder.setDefaults(Notification.DEFAULT_SOUND);
// 添加默认呼吸灯提醒,自动添加FLAG_SHOW_LIGHTS
builder.setDefaults(Notification.DEFAULT_LIGHTS);
添加自定义提醒:
/ 添加自定义声音提醒
builder.setSound(Uri.parse("path/to/sound"));
// 添加自定义震动提醒
// 延迟200ms后震动300ms,再延迟400ms后震动500ms
long[] pattern = new long[]{200,300,400,500};
builder.setVibrate(pattern);
// 添加自定义呼吸灯提醒,自动添加FLAG_SHOW_LIGHTS
int argb = 0xffff0000; // led灯光颜色
int onMs = 300; // led亮灯持续时间
int offMs = 100; // led熄灯持续时间
builder.setLights(argb, onMs, offMs);
响应紧急事件(全屏通知事件,比如来电)
Intent intent = new Intent(ACTION);
intent.putExtra("op", op);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, 0);
builder.setFullScreenIntent(pi, true);
3. 带下载进度条的Notification
通知可能包括动画形式的进度指示器,向用户显示正在进行的操作状态。 如果可以估计操作所需的时间以及任意时刻的完成进度,则使用“限定”形式的指示器(进度栏)。 如果无法估计操作的时长,则使用“非限定”形式的指示器(Activity 指示器)
要在 Android 4.0 及更高版本的平台上使用进度指示器,需调用 setProgress()
要显示限定形式的进度栏,需要通过调用 setProgress(max, progress, false)
将进度栏添加到通知,然后发出通知。随着操作的进行,递增 progress 并更新通知
int id = 1;
...
mNotifyManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_notification);
// Start a lengthy operation in a background thread
new Thread(
new Runnable() {
@Override
public void run() {
int incr;
for (incr = 0; incr <= 100; incr+=5) {
mBuilder.setProgress(100, incr, false);
mNotifyManager.notify(id, mBuilder.build());
try {
// Sleep for 5 seconds
Thread.sleep(5*1000);
} catch (InterruptedException e) {
Log.d(TAG, "sleep failure");
}
}
mBuilder.setContentText("Download complete")//下载完成
.setProgress(0,0,false); //移除进度条
mNotifyManager.notify(id, mBuilder.build());
}
}
).start();
对于不确定进度的进度条,使用setProgress(0,0,true)
来表示进度不明确的进度条。
4. 保留Activity返回栈
默认情况下,从通知启动一个Activity,按返回键会回到主屏幕。 但某些时候有按返回键仍然留在当前应用的需求,这就要用到TaskStackBuilder
了。
基本步骤:
- 创建Intent设置目标Activity
- 通过调用
TaskStackBuilder.create()
创建堆栈生成器 - 通过调用
addParentStack()
将返回栈添加到堆栈生成器。对于在清单文件中所定义层次结构内的每个Activity,返回站均包含可启动Activity的Intent对象。此方法还会添加一些可在全新任务中启动堆栈的标志。 - 尽管
addParentStack()
的参数是对已启动 Activity 的引用,但是方法调用不会添加可启动 Activity 的 Intent,而是留待下一步进行处理 - 通过调用
addNextIntent()
,添加可从通知中启动Activity的Intent。将在第一步中创建的Intent作为addNextIntent()
的参数传递 - 如需,请通过调用
TaskStackBuilder.editIntentAt()
向堆栈中的 Intent 对象添加参数。有时,需要确保目标 Activity 在用户使用“返回”导航回它时会显示有意义的数据 - 通过调用
getPendingIntent()
获得此返回栈的 PendingIntent。 然后,可以使用此 PendingIntent 作为setContentIntent()
的参数
<activity android:name=".SecondActivity"
android:parentActivityName=".MainActivity"></activity>
Intent resultIntent = new Intent(this, SecondActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(SecondActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
5. 锁定屏幕通知
Android 5.0(API 21)开始,通知可显示在锁定屏幕上。
可使用此功能提供媒体播放控件以及其他常用操作。
用户可以通过“设置”选择是否将通知显示在锁定屏幕上。提供的方法是setVisibility()
设置可见性:
VISIBILITY_PUBLIC
显示通知的完整内容。VISIBILITY_SECRET
不会在锁定屏幕上显示此通知的任何部分。VISIBILITY_PRIVATE
显示通知图标和内容标题等基本信息,但是隐藏通知的完整内容。
设置 VISIBILITY_PRIVATE 后,还可以通过 setPublicVersion()
提供其中隐藏了某些详细信息的替换版本通知内容。
6. 折叠式与悬挂式Notification
折叠式Notification
是一种自定义视图的Notification,用来显示长文本和一些自定义布局的场景,有两种状态,一种是普通状态下的视图,一种是展开状态下的视图。与普通Notification不同的是,我们需要自定义的视图和我们创建视图的进程不在一个进程,需要使用RemoteViews
public void fold_notification(View view) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.mrsorrow.xin")), PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("折叠通知")
.setContentText("这是折叠通知内容")
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_VIBRATE)
.build();
notification.bigContentView = new RemoteViews(getPackageName(), R.layout.notification_fold);
manager.notify(2, notification);
}
悬挂式Notification
是android5.0新增加的方式,和前两种显示方式不同的是,前两种需要下拉通知栏才能看到通知,而 悬挂式Notification不需要下拉通知栏就直接显示出来悬挂在屏幕上方并且焦点不变仍在用户操作的界面因此不会打断用户的操作,过几秒就会自动消失。
需要调用setFullScreenIntent()
来将Notification变为悬挂式Notification
public void hang_notification(View view) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.mrsorrow.xin")), PendingIntent.FLAG_CANCEL_CURRENT);
Intent hangIntent = new Intent();
hangIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
hangIntent.setClass(this, MainActivity.class);
PendingIntent hangPendingIntent = PendingIntent.getActivity(this, 0, hangIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("悬挂通知")
.setContentText("这是悬挂通知内容")
.setContentIntent(intent)
.setAutoCancel(true)
.setLights(0x7788aa, 3000, 3000)
.setFullScreenIntent(hangPendingIntent, true)
.build();
manager.notify(2, notification);
}
7. 扩展布局,多文本等
在需要对通知内容进行简单操作的时候,比如短信的‘标记为已读’,‘删除’。我们可以对按钮设置图标、标题以及设置 PendingIntent 以便响应动作。这种按钮最多可以添加三个,按添加的顺序从左往右依次排列。 api 23 之后图标不显示
Intent intent2 = new Intent("NotificationAction");
intent2.putExtra("A", "Action button1 clicked");
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(this, 3, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Action.Builder actionBuilder = new Notification.Action.Builder(Icon.createWithResource(getApplicationContext(), R.drawable.ic_launcher_background), "Action1", pendingIntent1);
builder.addAction(actionBuilder.build());
结果如图,点击Action1按钮发出一条广播
超长内容的Notification,各种style
超长内容的 Notification,比如内容为文字很多,或者一个大图片,一个自定义的 View,通过 builder.setStyle(Style style)
这个方法设置。设置 style 之后,之前的 setContent 设置的内容将会失效。各种 style 的高度最大为 256 dp。
BigTextStyle
文本
Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle().bigText(
"This is big text notification. This is big text notification. " +
"This is big text notification. This is big text notification. " +
"This is big text notification. This is big text notification. " +
"This is big text notification. This is big text notification. " +
"This is big text notification. This is big text notification. " +
"This is big text notification. This is big text notification. " +
"This is big text notification. This is big text notification. " +
"This is big text notification. This is big text notification. " +
"This is big text notification. This is big text notification. ");
builder.setStyle(bigTextStyle);
InboxStyle
列表
inboxstyle 显示为一个文字列表,显示addline
的顺序的文字。
Notification.InboxStyle inboxStyle = new Notification.InboxStyle();
// 添加行
inboxStyle.addLine("First line.");
inboxStyle.addLine("Second line");
inboxStyle.addLine("Third line");
inboxStyle.addLine("Last line");
// 设置标题
inboxStyle.setBigContentTitle("ContentTitle");
builder.setStyle(inboxStyle);
BigPictureStyle
大图片
// 构建一个 Style
Notification.BigPictureStyle bigPictureStyle =
new Notification.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.big));
// 设置标题
bigPictureStyle.setBigContentTitle("ContentTitle");
// 设置副标题,简介文字
bigPictureStyle.setSummaryText("SummaryText");
// 设置大图标
bigPictureStyle.bigLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.big));
builder.setStyle(bigPictureStyle);
8. Notification归类
一个APP可能短时间之内会推送很多条消息过来,比如新闻类的APP,对一些突发的热点事件需要的比较高同步性,就有可能一下子推送N多条信息给用户,结果消息都堆在一起了,大大降低了用户的体验。
一个治标的方法就是过滤此App的通知消息。在Android N(API 24)版本中,关于通知栏有一个比较重要的改变:允许同一个应用程序将所有通知集成在一个归类群组里面,只要你设置了同样的一个id,就可以将消息归类。
关于Notification归类的基本思路:发送通知,给通知设置一个groupKey
并发送;之后去检查是否有同样的groupKey的通知,如果有,就在发送一个整理-归类的通知,让系统帮我们归类具有相同groupKey的通知成一个二级菜单列表。
//use constant ID for notification used as group summary
int SUMMARY_ID = 0;
String GROUP_KEY_WORK_EMAIL = "com.android.example.WORK_EMAIL";
Notification newMessageNotification1 =
new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notify_email_status)
.setContentTitle(emailObject1.getSummary())
.setContentText("You will not believe...")
.setGroup(GROUP_KEY_WORK_EMAIL)
.build();
Notification newMessageNotification2 =
new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notify_email_status)
.setContentTitle(emailObject2.getSummary())
.setContentText("Please join us to celebrate the...")
.setGroup(GROUP_KEY_WORK_EMAIL)
.build();
Notification summaryNotification =
new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID)
.setContentTitle(emailObject.getSummary())
//set content text to support devices running API level < 24
.setContentText("Two new messages")
.setSmallIcon(R.drawable.ic_notify_summary_status)
//build summary info into InboxStyle template
.setStyle(new NotificationCompat.InboxStyle()
.addLine("Alex Faarborg Check this out")
.addLine("Jeff Chang Launch Party")
.setBigContentTitle("2 new messages")
.setSummaryText("janedoe@example.com"))
//specify which group this notification belongs to
.setGroup(GROUP_KEY_WORK_EMAIL)
//set this notification as the summary for the group
.setGroupSummary(true)
.build();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(emailNotificationId1, newMessageNotification1);
notificationManager.notify(emailNotificationId2, newMessageNotification2);
notificationManager.notify(SUMMARY_ID, summaryNotification);