注:为了给许多各类不一样的平台提供最好的notification支持,应该使用NotificationCompat以及它的子类,特别是NotificationCompat.Builder,因此如下通知均引用版本 4 支持库中的 NotificationCompat.Builder 类。java
通知建立步骤:
android
经过NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)得到一个通知的Builder对象;并发
调用mBuilder的方法设置通知属性,如setSmallIcon(int drawable)、satContentTitle(CharSquence title)等为通知设置小图标、内容标题;app
经过mBuilder.build()方法得到一个Notification对象;ide
得到一个通知管理器NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE),经过nm.notify(int id, Notification notification)方法发送通知,至此,通知便已经发送出去布局
建立一个通知时,必须包含一下几项内容:动画
小图标:由 setSmallIcon() 设置ui
标题:由 setContentTitle() 设置this
详细文本:由 setContentText() 设置spa
建立通知时,虽然能够选择为通知设置操做与否,可是通常来讲,至少应该为通知设定一个操做。最多见的通知操做即是由该通知跳转至指定的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);
效果图以下:
有时,设定一个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的默认任务:
<!-- 设置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" /
在代码中创建并发布notification
注意:须要调用Intent的setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK)来确保Activity在一个新的空task中启动
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是当通知超出一条时的样子,右下角的数字表示的是已发送的同类型通知数目,还能够进一步设置当通知超出一条时,能够点击该通知展开显示通知详情):
通常来讲,通知都是以上面所展现的普通视图样式呈现,但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中能够包含一个动画进度指示器,用于指示用户正在进行的操做的进度。该进度指示器有两种类型: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()); }
效果图以下: