安卓 Notification-通知总结
通知的常见应用模式
A1.普通通知的发送流程
// 获取通知服务对象NotificationManager NotificationManager notiManager = (NotificationManager) getSystemService(mContext.NOTIFICATION_SERVICE); // 创建Notification对象 NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext); builder.setTicker("Ticker"); // 通知弹出时状态栏的提示文本 builder.setContentInfo("Info..."); // builder.setContentTitle("Title") // 通知标题 .setContentText("Content") // 通知内容 .setSmallIcon(R.drawable.logo_dzone_strawberry); // 通知小图标 builder.setDefaults(Notification.DEFAULT_SOUND); // 设置声音/震动等 Notification notification = builder.build(); // 设置通知的点击行为:自动取消/跳转等 builder.setAutoCancel(true); // 通过NotificationManager发送通知 notiManager.notify(1003, notification);
A2.携带意图的通知
… // 与普通通知相同 // 获取通知服务对象NotificationManager Intent intent = new Intent(this, ModxExam2Activity.class); intent.putExtra("msg", "我发送了一个通知"); // 携带内容 //getIntent().getStringExtra("msg"); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, //请求码 intent, //意图对象 PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(pendingIntent); … // 与普通通知相同
A3.大视图通知
BigPictureStyle创建大视图样式,可以通过Builder.addAction()添加确认按钮。
… // 与普通通知相同 // 获取通知服务对象NotificationManager NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle(builder); bigPictureStyle.setSummaryText("SummaryText"); // 大图模式显示内容,取代小图 bigPictureStyle.setBigContentTitle("BigContentTitle"); // 大图模式标题,取代小图 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo_dzone_strawberry); bigPictureStyle.bigLargeIcon(bitmap); bigPictureStyle.bigPicture(bitmap); // 大图bitmap notiManager.notify(1005, bigPictureStyle.build()); … // 与普通通知相同
A4.进度条通知
… // 与普通通知相同 // 获取通知服务对象NotificationManager builder.setProgress(100, progress, false); … // 与普通通知相同
A5.自定义通知
notiManager = (NotificationManager) getSystemService(mContext.NOTIFICATION_SERVICE); NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext); // 使用RemoteViews创建view RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notify_layout_type1); remoteViews.setTextViewText(R.id.textView1, "setTextViewText"); remoteViews.setTextColor(R.id.textView1, Color.BLUE); remoteViews.setImageViewResource(R.id.imageView1, R.drawable.logo_dzone_strawberry); builder.setContent(remoteViews); builder.setSmallIcon(R.drawable.logo_dzone_strawberry); notiManager.notify(1008, builder.build());
通知总结
S1.通知的更新@link
要想更新通知,需要利用 NotificationManager.notify() 的 id 参数,该 id 在应用内需要唯一。要想更新特定 id 的通知,只需要创建新的 Notification,并发出与之前所用 id 相同的 Notification。如果之前的通知仍然可见,则系统会根据新的 Notification 对象的内容更新该通知。相反,如果之前的通知已被清除,系统则会创建一个新通知。
S2.删除通知@link
删除通知可以有多种方式:
1. 通过 NotificationCompat.Builder 设置 setAutoCancel(true),这样当用户点击通知后,通知自动删除;
2. 通过 NotificationManager.cancel(id) 方法,删除指定 id 的通知;
3. 通过 NotificationManager.cancelAll() 方法,删除该应用的所有通知;
S3.意图跳转@link
PendingIntent可以看做是对Intent的包装,通过名称可以看出PendingIntent用于处理即将发生的意图,而Intent用来用来处理马上发生的意图。而对于通知来说,它是一系统级的全局通知,并不确定这个意图被执行的时间。当在应用外部执行PendingIntent时,因为它保存了触发应用的Context,使得外部应用可以如在当前应用中一样,执行PendingIntent里的Intent,就算执行的时候响应通知的应用已经被销毁了,也可以通过存在PendingIntent里的Context照常执行它,并且还可以处理Intent说带来的额外信息。
PendingIntent提供了多个静态的getXxx()方法,用于获得适用于不同场景的PendingIntent对象。一般需要传递的几个参数都很常规,只介绍一个flag参数,用于标识PendingIntent的构造选择:
FLAG_CANCEL_CURRENT:如果构建的PendingIntent已经存在,则取消前一个,重新构建一个。
FLAG_NO_CREATE:如果前一个PendingIntent已经不存在了,将不再构建它。
FLAG_ONE_SHOT:表明这里构建的PendingIntent只能使用一次。
FLAG_UPDATE_CURRENT:如果构建的PendingIntent已经存在,则替换它,常用。
扩展内容
E1.浮动通知
E2.锁屏上展示
E3.闪光灯设置/自定义声音
E4.设置时间
实用方案
P1.自定义通知
参考:
参考:
官方API
Notifications google
Android 通知栏Notification的整合 全面学习 详细(E4)(CSDN)
Android 开发之 Notification 详解 全面(E1/E2)
Android--通知之Notification 全面(承香墨影)
全面了解Android Notification 全()简书
大视图
Android官方开发文档Training系列课程中文版:通知用户之大视图通知
demo代码
public void onClick(View view) { switch (view.getId()) { case R.id.button1: notifyNormalType1(); break; case R.id.button2: notifyWithIntentType2(); break; case R.id.button3: notifyBigPicType3(); break; case R.id.button4: newThreadProgress(); break; case R.id.button5: notifyCustomType5(); break; } }
NotificationManager notiManager; /** * 发送普通通知 * SS1.创建Builder对象(NotificationCompat.Builder) * SS2.添加通知设置内容 * SS3.创建通知对象通过Builder.build()构造返回 * SS4.获取通知管理器 * SS5.发出通知(通知ID,通知对象) */ private void notifyNormalType1() { // 获取通知服务对象NotificationManager notiManager = (NotificationManager) getSystemService(mContext.NOTIFICATION_SERVICE); // 创建Notification对象 NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext); builder.setTicker("Ticker"); // 通知弹出时状态栏的提示文本 builder.setContentInfo("Info..."); // builder.setContentTitle("Title") // 通知标题 .setContentText("Content") // 通知内容 .setSmallIcon(R.drawable.logo_dzone_strawberry); // 通知小图标 builder.setDefaults(Notification.DEFAULT_SOUND); // 设置声音/震动等 // builder.setDefaults(Notification.DEFAULT_ALL); // 设置声音+震动 Notification notification = builder.build(); // 设置通知的点击行为:自动取消/跳转等 builder.setAutoCancel(true); // 单独设置未跳转? // 通过NotificationManager发送通知 notiManager.notify(1003, notification); } /** * 发送携带意图的通知 * SS1.创建Builder对象(NotificationCompat.Builder) * SS2.添加通知设置内容 * SS+.在Builder中加入一个意图过滤器builder.setContentIntent(PendingIntent) * 给PendingIntent的Intent参数添加跳转的目标Activity * SS3.创建通知对象通过Builder.build()构造返回 * SS4.获取通知管理器 * SS5.发出通知(请求码,通知对象) */ private void notifyWithIntentType2() { notiManager = (NotificationManager) getSystemService(ModxExam1Activity.NOTIFICATION_SERVICE); NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext); builder.setTicker("弹出时提示..."); builder.setContentInfo("内容:带意图的通知"); builder.setContentTitle("通知标题") .setContentText("通知下面的文本") .setSmallIcon(R.drawable.logo_dzone_strawberry); builder.setDefaults(Notification.DEFAULT_SOUND); Intent intent = new Intent(this, ModxExam2Activity.class); intent.putExtra("msg", "我发送了一个通知"); //getIntent().getStringExtra("msg"); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, //请求码 intent, //意图对象 PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(pendingIntent); builder.setAutoCancel(true); //点击自动取消通知 Notification notification = builder.build(); notiManager.notify(1003, notification); } /** * 发送大视图通知 * SS1.创建Builder对象(NotificationCompat.Builder) * SS2.添加通知设置内容 * SS+.创建BigPictureStyle传入builder,并设置BigPictureStyle属性 * SS3.创建通知对象通过BigPictureStyle.build()构造返回 * SS4.获取通知管理器 * SS5.发出通知(请求码,通知对象) * mark * 大视图通知的特点: * 1.必须设置setSmallIcon,设置小图标,已收到通知小图标会在状态栏显示, * 用户下拉获得通知的时候,小图会显示在大图标的右下角 * 2.大图通知的标题内容设置会覆盖原来的小图通知的设置 * 3.bigPicture方法设置的图片会在一个比较大的视图中显示 * 兼容性问题?honor6plus 6.0 */ private void notifyBigPicType3() { notiManager = (NotificationManager) getSystemService(ModxExam1Activity.NOTIFICATION_SERVICE); Intent intent = new Intent(this, ModxExam2Activity.class); intent.putExtra("msg", "我发送了一个通知"); //getIntent().getStringExtra("msg"); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, //请求码 intent, //意图对象 PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext); builder.setTicker("Ticker"); builder.setContentInfo("Info"); builder.setContentTitle("Title") .setContentText("Content") .setSmallIcon(R.drawable.logo_dzone_strawberry); builder.setDefaults(Notification.DEFAULT_SOUND); /** * 在大视图通知中设置一个按钮 * 点击无法取消? * http://blog.csdn.net/sahadev_/article/details/51714799 */ builder.setStyle(new NotificationCompat.BigTextStyle() .bigText("msg...")) .addAction (R.drawable.logo_dzone_strawberry, "123", pendingIntent) .addAction (R.drawable.logo_dzone_strawberry, "456", pendingIntent); builder.setContentIntent(pendingIntent); builder.setAutoCancel(true); NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle(builder); bigPictureStyle.setSummaryText("SummaryText"); // 大图模式显示内容,取代小图 bigPictureStyle.setBigContentTitle("BigContentTitle"); // 大图模式标题,取代小图 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo_dzone_strawberry); bigPictureStyle.bigLargeIcon(bitmap); bigPictureStyle.bigPicture(bitmap); // 大图bitmap notiManager.notify(1005, bigPictureStyle.build()); } /** * 进度通知处理 * SS1. */ private int i; private final int CODE_START = 1001; // 开始 private final int CODE_RUN = 1002; // 下载中 private final int CODE_END = 1003; // 下载完成 private final int NOF_MSG_CODE = 10086; // notification code Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case CODE_START: notifyProgressType4(0, CODE_START); break; case CODE_RUN: notifyProgressType4(msg.arg1, CODE_RUN); break; case CODE_END: notifyProgressType4(0, CODE_END); break; } } }; NotificationCompat.Builder builder; /** * 发送进度通知 * @param progress 进度 * @param code 识别码 */ private void notifyProgressType4(int progress, int code) { notiManager = (NotificationManager) getSystemService(mContext.NOTIFICATION_SERVICE); if (builder == null) { builder = new NotificationCompat.Builder(mContext); builder.setTicker("Ticker"); builder.setContentInfo("info"); builder.setContentTitle("变形金刚2.avi") .setContentText("default content...") .setSmallIcon(R.drawable.logo_dzone_strawberry); //必须设置 } if (code == CODE_RUN) { // 参数三设置为true/false 是否允许使用不确定模式,在不确定模式下,进度条动画无限循环 builder.setProgress(100, progress, false); builder.setContentText("loading..."); } else if (code == CODE_START) { builder.setContentText("ready to download"); } else if (code == CODE_END) { builder.setProgress(0, 0, false); builder.setContentText("download finished,would you open it?"); Intent intent = new Intent(this, ModxExam2Activity.class); intent.putExtra("msg", "我发送了一个通知"); //getIntent().getStringExtra("msg"); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, // 请求码 intent, //意图对象 PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(pendingIntent); builder.setDefaults(Notification.DEFAULT_SOUND); builder.setAutoCancel(true); } Notification notification = builder.build(); notiManager.notify(NOF_MSG_CODE, notification); } Message message; NotificationManager notifyManager; /** * 模拟下载线程 */ private void newThreadProgress() { new Thread(new Runnable() { @Override public void run() { try { notifyManager = (NotificationManager) getSystemService(mContext.NOTIFICATION_SERVICE); message = new Message(); // 每次都要NEW一个message??? message.what = CODE_START; // 开始 handler.sendMessage(message); for (i = 0; i <= 100; i++) { Thread.sleep(200); // SystemClock.sleep(200); LogUtil.infoE("" + i); notifyManager.cancel(NOF_MSG_CODE); message = new Message(); message.what = CODE_RUN; // 正在运行 message.arg1 = i; handler.sendMessage(message); } notifyManager.cancel(CODE_RUN); message = new Message(); message.what = CODE_END; // 结束了 handler.sendMessage(message); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } /** * 自定义通知 * 必须设置setSmallIcon */ private void notifyCustomType5() { notiManager = (NotificationManager) getSystemService(mContext.NOTIFICATION_SERVICE); NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext); // 使用RemoteViews创建view RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notify_layout_type1); remoteViews.setTextViewText(R.id.textView1, "setTextViewText"); remoteViews.setTextColor(R.id.textView1, Color.BLUE); remoteViews.setImageViewResource(R.id.imageView1, R.drawable.logo_dzone_strawberry); builder.setContent(remoteViews); builder.setSmallIcon(R.drawable.logo_dzone_strawberry); notiManager.notify(1008, builder.build()); ToastUtil.showS(this, "Type5"); }