一、Android中通知的创建流程
注:为了给许多各种不同的平台提供最好的notification支持,应该使用NotificationCompat以及它的子类,特别是NotificationCompat.Builder,所以以下通知均引用版本 4 支持库中的 NotificationCompat.Builder 类。
通知创建步骤:
通过NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)获得一个通知的Builder对象;
调用mBuilder的方法设置通知属性,如setSmallIcon(int drawable)、satContentTitle(CharSquence title)等为通知设置小图标、内容标题;
通过mBuilder.build()方法获得一个Notification对象;
获得一个通知管理器NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE),通过nm.notify(int id, Notification notification)方法发送通知,至此,通知便已经发送出去
二、注意事项
创建一个通知时,必须包含一下几项内容:
小图标:由 setSmallIcon() 设置
标题:由 setContentTitle() 设置
详细文本:由 setContentText() 设置
创建通知时,虽然可以选择为通知设置操作与否,但是一般来说,至少应该为通知设定一个操作。最常见的通知操作便是由该通知跳转至指定的Activity,在该Activity中,有用户需要查看的消息或者是用户需要进行的操作
三、创建一个简单的通知
//创建一个用于通知操作的Intent
Intent intent = new Intent();
intent.setClass(mContext, IconifyActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//创建一个NotificationCompat.Builder对象,通过该对象为通知设置属性,并构建一个具体地通知
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
Notification simpleNotice = builder.setContentTitle("Simple notice").setContentText("Example for simple notice").setSmallIcon(R.drawable.ic_notice_1).setContentIntent(pendingIntent)
.setAutoCancel(true).setDefaults(Notification.DEFAULT_ALL).setPriority(Notification.PRIORITY_HIGH)
.build();
//获得一个通知管理器,通过该管理器发送通知
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, simpleNotice);
效果图如下:
四、创建一个进入特定Activity的通知
有时,设定一个Notification是为了保持应用的导航性,用户点击通知时会进入含有具体操作的Activity。通常,Activity分为两类,常规的Activity和特定的Activity。
常规Activity是你的应用工作流中的一部分,而一个特定的Activity并不位于你的应用工作流中,一般位于一个新的任务栈中,只能通过notification来启动。
上述示例就是通过notification导航进入一个常规Activity,不过通常还应该为跳转至常规Activity的通知设定一个返回栈,用于将该Activity导航回上一级Activity。下述步骤介绍如何发送一个跳转至另一任务栈的Activity的通知。
在manifest.xml文件中为该Activity设置如下属性android:taskAffinity="",该属性用于标志该activity需要进入的任务栈,结合代码中设置的FLAG_ACTIVITY_NEW_TASK标识, 确保这个Activity不会进入application的默认任务:
在代码中建立并发布notification
注意:需要调用Intent的setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK)来确保Activity在一个新的空task中启动
<!-- 设置NewTaskActivity处于一个新的task中,从而不会进入应用程序默认的task -->
<!-- taskAffinity是一个task标志,标志该activity应该进入的task -->
<!-- excludeFromRecents属性用于将新任务从最近列表中删除,目的是为了防止用户不小心返回到它 -->
<activity
android:name="com.activity.NewTaskActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:taskAffinity="" />
<activity android:name="com.activity.IconifyActivity" /
Intent intent = new Intent();
intent.setClass(this, NewTaskActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification simpleNotice = builder.setContentTitle("New task notice").setContentText("Example for new task notice").setSmallIcon(R.drawable.ic_notice_2).setContentIntent(pendingIntent).build();
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(0, simpleNotice);
效果如下(图一是通知视图,图二是点击通知后,长按Home键可以看到的目前的任务列表)由图二可以看出,由该通知跳转至的Activity位于一个新的任务栈中:
五、管理通知
更新通知:更新通知是指发布一条通知后,对刚发布的这条通知进行修改;当使用notify(int id, Notification notification)方法发布一条通知时,参数id表示的是当前发布的通知的唯一id,所以当需要对该同志进行更新时,只需要再发布一条同一id号的新通知即可。如:
将同一类通知进行统一管理:当应用中需要发送同一类型的通知时,可将这些通知合并为一条摘要通知,而不是每次都新建一条通知。具体的应用场景有如短信、即时消息等,如:
//发布id=0的通知,具体通知内容为notification1
nm.notify(0, notification1);
//更新id=0的通知,具体通知内容为notification2
nm.notify(0, notification2);
具体的代码如下:
/**
* 发送一条摘要通知,当同类型通知超出一条时,以摘要通知的形式展示
* @param count:已发出的该类通知数目
*/
public void sendSummaryNotice(int count) {
Intent summaryIntent = new Intent(mContext, IconifyActivity.class);
PendingIntent summaryPI = PendingIntent.getActivity(mContext, 0, summaryIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder summaryBuilder = new NotificationCompat.Builder(mContext);
summaryBuilder.setContentIntent(summaryPI);
if (count > 1) {
summaryBuilder.setTicker("New summary msg").setSmallIcon(R.drawable.ic_summary_notice_1)
.setContentTitle("Summary message").setContentText("You have received " + count + " message!")
.setNumber(count);
} else {
summaryBuilder.setTicker("New message").setSmallIcon(R.drawable.ic_summary_notice_1)
.setContentTitle("Msg " + count).setContentText("This is message " + count);
}
nm.notify(0, summaryBuilder.build());
}
效果图如下(图1是当该类通知只有一条时的样子,图2是当通知超出一条时的样子,右下角的数字表示的是已发送的同类型通知数目,还可以进一步设置当通知超出一条时,可以点击该通知展开显示通知详情):
六、使用BigView型通知
一般来说,通知都是以上面所展示的普通视图样式呈现,但Android系统中还提供一种Big View样式的通知。Big view样式的通知只有当Notification在Notification抽屉的最上方或者用户点击Notification时才会展现。同时,该样式是在Android4.1才被引进的,所以它不支持老版本设备,在实现big view 样式的通知时,要确保在Big view样式中能完成的功能,通过普通视图样式的通知也能够完成(可以在普通视图跳转至的Activity中提供此类功能)。
下图是我实现的一个Big view样式的通知:
代码如下:
/**
* 发送一个大视图样式的通知
*/
public void sendaBigViewNotice() {
//点击通知的操作Intent
Intent intent = new Intent(mContext, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(mContext, 6, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//构造一个NotificationCompat.Builder,为通知设置属性值
NotificationCompat.Builder bigViewbuilder = new NotificationCompat.Builder(mContext)
.setContentTitle("Big view notice")
.setContentText("This is a big view notice")
.setSmallIcon(R.drawable.ic_notice_6)
.setContentIntent(pi)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL);
//定义大视图通知中自定义的两个按钮的操作
PendingIntent cameraPi = PendingIntent.getActivity(mContext, 101, new Intent(mContext, MainActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent refreshPi = PendingIntent.getActivity(mContext, 102, new Intent(mContext, IconifyActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
//通过setStyle(Style style)方法设置通知的样式为BigTextStyle
//通过addAction(int icon, CharSequence title, PendingIntent intent)方法为通知添加动作
//参数一:动作图标资源;参数二:动作名称; 参数三:动作所对应的操作的PendingIntent
bigViewbuilder
.setStyle(new NotificationCompat.BigTextStyle().bigText("Big text").setSummaryText("This is a summary"))
.addAction(R.drawable.ic_camera, "Camera", cameraPi)
.addAction(R.drawable.ic_camera_alt, "Refresh", refreshPi);
//发送通知
NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(100, bigViewbuilder.build());
}
七、显示Notification的进度
Notification中可以包含一个动画进度指示器,用于指示用户正在进行的操作的进度。该进度指示器有两种类型:determinate(确定的) 和 indeterminate(不确定的)。一般来说,若一个操作的具体完成时间已知,且当前已完成的部分所花的时间已知时,使用确定性进度指示器;否则使用不确定性进度指示器。
通知的进度指示器是用ProgressBar平台实现类来显示,用 setProgress(int max, int progress, boolean indeterminate)方法来设置的。该方法有三个参数:
max:进度条的最大值;
progress:当前已完成的进度值,一般来说,当操作完成时,progress应等于max,通常将max值设为100,然后将progress值设为当前完成值占max的百分比;
indeterminate:一个boolean类型值,表示当前的进度条是为indeterminate(true)还是determinate(false);
注意:操作完成时,可以选择继续显示或移除进度条,但是必须的提供相应的文字说明,提示用户操作已完成,移除进度条,只需使用setProgress(0, 0, false))方法即可
/**
* 发送一个含有进度条的通知
* @param indeterminate:是否为不确定性进度条,true:不确定性
false:确定性
*/
public void sendProgressNotice(final boolean indeterminate) {
//点击通知的操作
Intent intent = new Intent(mContext, IconifyActivity.class);
final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 10, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
final NotificationCompat.Builder progressBuilder = new NotificationCompat.Builder(mContext)
.setSmallIcon(R.drawable.ic_notice_6).setContentTitle("Progress notice")
.setContentText("This is a progress notice").setTicker("Here is a new msg");
//新建一个线程,用于控制操作进度
new Thread(new Runnable() {
@Override
public void run() {
//不确定性进度指示器
if (indeterminate) {
for (int inch = 0; inch <= 100; inch += 5) {
progressBuilder.setProgress(0, 0, true);
nm.notify(103, progressBuilder.build());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
progressBuilder.setProgress(0, 0, false).setContentText("Finished the progress")
.setContentIntent(pendingIntent);
nm.notify(103, progressBuilder.build());
} else { //确定性进度指示器
for (int inch = 0; inch < 100; inch += 5) {
progressBuilder.setProgress(100, inch, false);
nm.notify(104, progressBuilder.build());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//操作完成时,取消进度指示器,并设置提示文本
progressBuilder.setProgress(0, 0, false).setContentText("Finished the progress")
.setContentIntent(pendingIntent);
nm.notify(104, progressBuilder.build());
}
}
}).start();
}
效果图如下(图一:不确定性进度条; 图二:确定性进度条; 图三:操作完成后的状态):
八、自定义布局的通知
自定义布局通知的使用步骤:
创建一个通知布局文件(xml)
通过实例化一个RemoteViews对象加载该布局文件
通过setContent(RemoteViews views)方法设置通知内容视图为一个该RemoteViews视图
发布该通知
效果图如下:
public void sendCustomViewNotice() {
//通过一个RemoteViews来加载通知布局文件
RemoteViews remoteView = new RemoteViews(mContext.getPackageName(), R.layout.custom_notification);
NotificationCompat.Builder customBuilder = new NotificationCompat.Builder(mContext);
customBuilder.setSmallIcon(R.drawable.ic_notice_6);
//通过setContent(RemoteViews views)方法设置通知内容视图为一个RemoteViews视图
customBuilder.setContent(remoteView);
Intent intent = new Intent();
intent.setClass(mContext, IconifyActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
customBuilder.setContentIntent(pendingIntent);
nm.notify(0, customBuilder.build());
}
来源:oschina
链接:https://my.oschina.net/u/2621851/blog/632789