信息提醒之Notification,兼容全部SDK-更新中
概述
Notification与对话框、Toast无论从外观上还是从使用方法上有本质的区别。
Notification是Android中很理想的提示方法,Notification可以在Android桌面上最上方的状态栏显示提示信息,还可以显示图像,甚至可以将控件加载到上面,而且只要用户不清空,这些信息可以永久的保留在状态栏,除了这些还有其他更吸引人的特性,让我们一起发掘下吧。
本篇博文中使用的创建Notification 是通过一个兼容全部SDK的工具类创建的,因为setLatestEventInfo方法在API11中不建议使用了,而且谷歌在API23 (Android6.0)中彻底废弃了该方法。
所以本篇博文中会提供一个创建Notification的工具类,来兼容所有额SDK版本~
NotificationUtils.java
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.os.Build;import com.apkfuns.logutils.LogUtils;import java.lang.reflect.Method;/*** 兼容所有SDK的NotificationUtil** @author Mr.Yang on 2016-02-18 20:34.* @version 1.0* @desc*/
public class NotificationUtil {public static Notification createNotification(Context context, PendingIntent pendingIntent, String title, String text, int iconId) {Notification notification;if (isNotificationBuilderSupported()) {LogUtils.d("isNotificationBuilderSupported");notification = buildNotificationWithBuilder(context, pendingIntent, title, text, iconId);} else {// 低于API 11 HoneycombLogUtils.d("buildNotificationPreHoneycomb");notification = buildNotificationPreHoneycomb(context, pendingIntent, title, text, iconId);}return notification;}public static boolean isNotificationBuilderSupported() {try {return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) && Class.forName("android.app.Notification.Builder") != null;} catch (ClassNotFoundException e) {return false;}}@SuppressWarnings("deprecation")private static Notification buildNotificationPreHoneycomb(Context context, PendingIntent pendingIntent, String title, String text, int iconId) {Notification notification = new Notification(iconId, "", System.currentTimeMillis());try {// try to call "setLatestEventInfo" if availableMethod m = notification.getClass().getMethod("setLatestEventInfo", Context.class, CharSequence.class, CharSequence.class, PendingIntent.class);m.invoke(notification, context, title, text, pendingIntent);} catch (Exception e) {// do nothing}return notification;}@TargetApi(Build.VERSION_CODES.HONEYCOMB)@SuppressWarnings("deprecation")private static Notification buildNotificationWithBuilder(Context context, PendingIntent pendingIntent, String title, String text, int iconId) {android.app.Notification.Builder builder = new android.app.Notification.Builder(context).setContentTitle(title).setContentText(text).setContentIntent(pendingIntent).setSmallIcon(iconId);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {return builder.build();} else {return builder.getNotification();}}}
在状态栏上显示通知信息
Notification需要使用NotificationManager来管理,一般来讲创建并显示Notification需要以下5个步骤:
- 通过getSystemService方法获取一个NotificationManager对象
- 创建一个Notification对象,在这里我们使用兼容较好的NotificationUtils类来创建
- 由于Notification可以与应用程序脱离,也就是说,即使应用程序被关闭,Notification仍然会显示在状态栏中,当应用程序再此启动后,又可以重新控制这些Notification,如清除或者替换他们。因此,需要创建一个PendingIntent对象。该对象由Android系统负责维护,因此在应用程序关闭后,该对象仍然不会被释放。
- 使用Notification类的setLatestEventInfo方法设置详细信息(改方法已经在6.0废弃,可使用提供的工具类来代替)
- 使用NotificationManager类的notify方法显示Notification。再这一步需要指定标识Notification的唯一ID,改ID必须相对于同一个NotificationManager对象是唯一的,否则就会覆盖相同ID的Notification。
/*** 全部兼容* http://blog.csdn.net/yangshangwei/article/details/50688221*/private void showNotification() {notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, getIntent(), 0);// 工具类判断版本,通过不同的方式获取NotificationNotification notification = NotificationUtil.createNotification(this, pendingIntent, "您有新消息", "消息内容", R.drawable.flag_mark_blue);notification.tickerText = "我是提示通知时的文字内容";notification.when = System.currentTimeMillis();// 使用默认的声音notification.defaults = Notification.DEFAULT_SOUND;// 使用默认的震动 需要添加uses-permission android.permission.VIBRATEnotification.defaults = Notification.DEFAULT_VIBRATE;// 使用默认的Lightnotification.defaults = Notification.DEFAULT_LIGHTS;// 所有的都是用默认值notification.defaults = Notification.DEFAULT_ALL;notificationManager.notify(R.drawable.flag_mark_blue, notification);// 5S后,执行取消的方法,即5S后 自动清除该通知栏 ,根据需求考虑是否需要这样
// Handler handler = new Handler();
// handler.postDelayed(new Runnable() {// @Override
// public void run() {// notificationManager.cancel(R.drawable.flag_mark_blue);
// }
// },5*1000);}
上述代码中的
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, getIntent(), 0);
返回一个PendingIntent对象,这个对象与一个Activity对象关联,这个案例中与当前的Activity关联。将Android状态栏滑下来后,单击Notification,就会显示关联的这个Activity。如果Activity已经显示,仍然会显示一个新的Activity,并覆盖当前显示的Activity。不过这些显示的Activity都是一样的,除了getActivity方法之外,还可以getBroacast和getService方法。 这两个方法用于单击Notification后发出一条广播或者启动一个服务。
设置默认发声、震动、Light效果
// 使用默认的声音notification.defaults = Notification.DEFAULT_SOUND;// 使用默认的震动 需要添加uses-permission android.permission.VIBRATEnotification.defaults = Notification.DEFAULT_VIBRATE;// 使用默认的Lightnotification.defaults = Notification.DEFAULT_LIGHTS;// 所有的都是用默认值notification.defaults = Notification.DEFAULT_ALL;
注意事项:
- defaults属性必须在调用notify方法之前调用,否则不起作用
- 设置震动效果需要在AndroidManifest.xml中添加权限
<uses-permission android:name="android.permission.VIBRATE" />
清除指定的Notification
如果要清除某个消息可以使用NotificationManager.cancel方法,该方法只有一个参数,表示要清除的Notification的ID。
case 1:// 清除指定的Notification-cancel(id)cancelNotification(R.drawable.flag_mark_blue);
/*** 清除某个消息,** @param id Notification的id*/private void cancelNotification(int id) {notificationManager.cancel(id);}
清除全部的Notification
使用cancelAll()可以清除当前NotificationManager对象中的所有的Notification。
清除Notification后触发的善后工作
当我们将状态栏下拉下来之后都会看到在屏幕的右上角有一个“清除“按钮或者图标,单击该按钮可以清除所有的Notification, 那么在清除后,往往需要做一些善后的工作,这个就需要通过Notification.deleteIntent来完成。
deleteIntent也需要设置一个PendingIntent类型的变量,由于在清除所有的Notification时调用,可以将这个动作和Activity、Broadcast、Service关联。
private void notificationDeleteIntent() {// 通过getSystemservice获取NotificationManagernotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);// PendingIntent --getAct ,getBrc ,getSev等等PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity_.class), 0);// NotificationNotification notification = NotificationUtil.createNotification(this, pendingIntent, "Title", "text", R.drawable.tag_blue);notification.when = System.currentTimeMillis();notification.tickerText = "清除Notificaiton的善后工作";// 清除通知,触发的操作,这里将清除Notification触发的deleteIntent设置为跳转到ToastDemoListAct,当然了也可以启动广播 服务等等PendingIntent deleteIntent = PendingIntent.getActivity(this, 0, new Intent(this, ToastDemoListAct.class), 0);notification.deleteIntent = deleteIntent;notificationManager.notify(R.drawable.tag_blue, notification);}
如果想响应删除动作的Activity传递数据,可以利用被PendingIntent封装的intent。例如
......
Intent intent = new Intent(this,Main.class);
//传递数据
intent.putExtra("msg","what r u doing ?");PendingIntent pendingIntent = PendingIntent.getActivity(this,0.intent,0);
.......
这样在Activity中(一般在onCreate方法中)接收解即可
String msg = getIntent().getStringExtra("msg");
.........
永久存在的Notification
我们发现单击”清除“按钮,有些Notification并没有被清除掉,这样无法被清除的Notification被称为永久Notification,这些Notification只能通过他们的程序 来清除。
实现这样的效果很简单,只需要设置Notification.flag即可。
/*** FLAG_SHOW_LIGHTS //控制闪光* <p/>* FLAG_ONGOING_EVENT //显示在”正在运行的“一栏中* <p/>* FLAG_INSISTENT //重复发出声音,直到用户响应此通知* <p/>* FLAG_ONLY_ALERT_ONCE //标记声音或者震动一次* <p/>* FLAG_AUTO_CANCEL //在通知栏上点击此通知后自动清除此通知* <p/>* FLAG_NO_CLEAR //将flag设置为这个属性那么通知栏的那个清楚按钮就不会出现* <p/>* FLAG_FOREGROUND_SERVICE//前台服务标记* <p/>* https://developer.android.com/intl/zh-cn/reference/android/app/Notification.html#FLAG_GROUP_SUMMARY* <p/>* FLAG_GROUP_SUMMARY* <p/>* FLAG_LOCAL_ONLY*/private void permanentNotification() {// 通过getSystemService获取NotificationManagernotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);// PendingIntentPendingIntent pendingIntent = PendingIntent.getActivity(this, 0, getIntent(), 0);// NotificationNotification notification = NotificationUtil.createNotification(this, pendingIntent, "Title", "Content", R.drawable.face);notification.tickerText = "清除不掉的Notification";notification.when = System.currentTimeMillis();notification.flags = Notification.FLAG_NO_CLEAR;// 展示NotificationnotificationManager.notify(R.drawable.face, notification);}
自定义Notification
我们可以通过Notification.contentView 来自定义Notification。
contentView 并不是一个View,而是RemoteViews类型。
RemoteView只支持有限的几个控件和布局,如下所示
RemoteView支持的布局
- FrameLayout
- LinearLayout
- RelativeLayout
RemoteView支持的控件
- AnalogClock
- Button
- Chronometer
- ImageButton
- ImageView
- ProgressBar
- TextView
如果使用其他控件,会抛出异常。
实现步骤
activity_custom_notification.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"><TextView
android:id="@+id/textview"android:layout_width="fill_parent"android:layout_height="wrap_content"android:gravity="center"android:text="自定义内容"android:textColor="#F00"android:textSize="20sp" /><ImageView
android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:src="@drawable/tag_green" /></LinearLayout>
private void customNotification() {// 通过getSystemService()获取NotificationManagernotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);//PendingIntentPendingIntent pendingIntent = PendingIntent.getActivity(this,0,getIntent(),0);// NotificationNotification notification = NotificationUtil.createNotification(this,pendingIntent,"Title","text",R.drawable.flag_mark_yellow);// 设置属性...notification.tickerText="自定义Notification";notification.when = System.currentTimeMillis();//自定义Notification布局RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.activity_custom_notification);remoteViews.setTextViewText(R.id.textview,"666666666");notification.contentView = remoteViews ;// notifiynotificationManager.notify(R.drawable.flag_mark_yellow,notification);}
运行效果
大拿总结的,可以参考
信息提醒之Notification,兼容全部SDK-更新中相关推荐
- 根据Spring-Security安全框架搭建问答论坛系统(更新中.....)
论坛问答系统系统设计与实现 什么是Spring安全框架 为什么需要Spring-Security 启动Spring-Security 访问控制器方法 密码加密 Spring-Security的权限管理 ...
- 印象笔记android,印象笔记(Evernote) Android SDK 更新
印象笔记(Evernote) Android SDK 1.0 发布以来, 我们收到了很多开发者的反馈,我们也一直在努力让印象笔记SDK更加简单易用.现在,我们发布了最新版的Android SDK,增强 ...
- Mopub广告 SDK 更新到5.6.0出现 amazon moat-sdk 连接Forbidden问题
Mopub 广告 SDK更新到5.6.0 本次更新与之前的更新差异比较大,主要问题在于本次mopub使用了amazon的依赖,一直下载不成功,查了很多文章以及StackOverflow的很多回答,找到 ...
- 消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法
消除安卓SDK更新时的"https://dl-ssl.google.com refused"异常的方法 消除安卓SDK更新时的"https://dl-ssl.google ...
- 解决安卓SDK更新dl-ssl.google.com无法连接的方法
解决安卓SDK更新dl-ssl.google.com无法连接的方法 参考文章: (1)解决安卓SDK更新dl-ssl.google.com无法连接的方法 (2)https://www.cnblogs. ...
- Android SDK更新的问题
Android SDK更新的问题: 在Android SDK更新的时候出现如下图所示的问题: 解决办法: 1.先备份当前android-sdk-windows下面的tools文件夹: ...
- 设置熄屏_刚买的手机微信收不到信息提醒耽误事情,手机到手一定要这样设置...
手机使用过程中经常会遇到第三方软件接收不到信息提醒的状况,常常因此耽误了很多重要的事情,造成损失.特别是刚换新手机或者手机刚升级系统时发生的最多.一般都觉得是手机问题,其实只是手机的系统设置出现了问题 ...
- android 开发问题集(一):SDK更新后 运行程序报错Location of the Android SDK has not been setup in the preferences
SDK更新后 运行程序报错Location of the Android SDK has not been setup in the preferences 问题描述:android跟新后报错loca ...
- android sdk更新失败 解决方案
更新android sdk版本时出现reason: Connection to http://dl-ssl.google.com refused错误,就是连接不上google的应用更新,但切可以连上g ...
最新文章
- [架构设计]反向(或者后向)插件系统设计
- Thinkphp动态切换主题
- Android异步下载网络图片(其二:AsyncTask)
- 也许90%的人都没有真正搞懂性能优化
- 剑桥大学国际学生事务部网站
- Activiti多人会签例子
- 10个Python编程窍门,不懂就亏了
- Spring Boot war方式打包发布
- 机器学习算法总结之XGBoost(下) 实战与调参
- 常见的网页布局(HTML、CSS)
- jquery刷新iframe页面的方法
- 科来网络分析系统(实用)
- CATIA怎么约束快捷键_CATIA超实用快捷键和技巧
- python——txt文本处理
- 如何在C++里面加快运行速度
- 《零基础学C语言》光盘内容
- Java--定位问题工具
- 滴滴开源小程序框架 Mpx
- firefox 下载文件时处理此文件的方法
- 实验室安全事故读后感