昨天一天只写了两篇文章,效率超低。追其原因呢,其实我一直在研究notification的实现方式,今天研究完了给大家分享一下。本来想写个工具类来封装一下代码的,但是我发现notification的个性化元素太多了,做成一个方法的话参数又多的要死,于是我就将比较常见的方法做了封装,写了个不是很规整的工具类,至于内部的逻辑啊,点击跳转的事件啊,大家下载demo后看看代码应该就能明白了,最重要的是根据自己的需要选择好的方法。还有一点需要建议的是,如果你发的通知都是用同一个ID的话可能会出现通知叠加的情况,这点需要注意一下。还是那句话根据实际需要吧,如果我的通知类型都是一样的,用同一个ID叠加就让他叠加吧。好啦,下面我们来看代码。

首先还是布局文件,这里用的全是button,在布局界面直接绑定了监听器。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.kale.notification.MainActivity" android:orientation="vertical"><Buttonandroid:id="@+id/normal_button_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="普通的通知" android:onClick="buttonListener"/><Buttonandroid:id="@+id/view_button_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="较为特别的通知" android:onClick="buttonListener"/><Buttonandroid:id="@+id/private_button_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="自定义布局的通知" android:onClick="buttonListener"/><Buttonandroid:id="@+id/big_button_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="可以显示多行信息的通知" android:onClick="buttonListener"/><Buttonandroid:id="@+id/progress_button_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="有进度条的通知" android:onClick="buttonListener"/><Buttonandroid:id="@+id/pic_button_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="有大图片的通知" android:onClick="buttonListener"/><Buttonandroid:id="@+id/btn_button_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="有两个按钮的通知" android:onClick="buttonListener"/><Buttonandroid:id="@+id/clear_button_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="40dp"android:text="清除所有的通知" android:onClick="buttonListener"/></LinearLayout>

自定义的通知布局

notification.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" android:background="#000000"><ImageViewandroid:id="@+id/image"android:layout_width="45dp"android:layout_height="45dp"android:layout_alignParentLeft="true"android:layout_marginTop="8dp"android:layout_marginBottom="8dp"android:layout_marginLeft="8.0dip"android:layout_marginRight="10dp" android:src="@drawable/ic_launcher"/><TextViewandroid:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/title"android:layout_marginTop="3.0dip"android:layout_toLeftOf="@+id/button"android:layout_toRightOf="@id/image"android:text="This is the text"android:textColor="#ffffff"android:textSize="16sp" /><TextViewandroid:id="@+id/title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignLeft="@+id/text"android:layout_alignTop="@+id/image"android:textStyle="bold"android:text="title"android:textColor="#ffffff"android:textSize="16sp" /><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignBottom="@+id/image"android:layout_alignParentRight="true"android:gravity="center_vertical"android:text="跳转"android:textColor="#ffffff" /></RelativeLayout>

点击通知信息,跳转的activity界面

other.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="0.50"android:layout_gravity="center"android:gravity="center_horizontal"android:text="用PendingIntent跳转到的界面"android:textAppearance="?android:attr/textAppearanceLarge" /></LinearLayout>

这个界面对应的activity就是个空的activity——OtherActivity.java,代码就不贴了。

主界面

MainAcitivity.java

package com.kale.notification;import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.RemoteViews;public class MainActivity extends Activity {NotificationAdmain admain;static int NOTIFICATION_ID = 13565400;Intent intent;int smallIcon = R.drawable.ic_launcher;String ticker = "来了条新的通知";int LargeIcon = R.drawable.kale;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 设置点击后启动的activityintent = new Intent(MainActivity.this, OtherActivity.class);admain = new NotificationAdmain(this,NOTIFICATION_ID);}public void buttonListener(View v) {switch (v.getId()) {case R.id.normal_button_id:admain.normal_notification(intent, smallIcon, ticker, "普通的通知","采用默认配置,这里的文字只能显示一行,会将多余的字影藏");break;case R.id.view_button_id:admain.special_notification(intent, smallIcon, ticker, LargeIcon,"特殊的通知", "这里面大小图标同时存在,并且有数字");break;case R.id.private_button_id://设置自定义布局中按钮的跳转界面Intent btnIntent = new Intent(MainActivity.this,OtherActivity.class);btnIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);//如果是启动activity,那么就用PendingIntent.getActivity,如果是启动服务,那么是getServicePendingIntent Pintent = PendingIntent.getActivity(this,(int) SystemClock.uptimeMillis(), btnIntent, PendingIntent.FLAG_UPDATE_CURRENT); // 自定义布局RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.notification);remoteViews.setImageViewResource(R.id.image, R.drawable.kale);remoteViews.setTextViewText(R.id.title, "自定义通知视图");remoteViews.setTextViewText(R.id.text, "这个自定义通知栏只能这么高了,不能有再多的内容了");remoteViews.setOnClickPendingIntent(R.id.button, Pintent);//定义按钮点击后的动作
            admain.view_notification(remoteViews, intent, smallIcon, ticker);break;case R.id.big_button_id:admain.big_notification(intent, smallIcon, ticker, "可以随内容变长的通知","《天之界线》是Jack.Tony在2009年3月开始动笔的一本小说。"+ "其内容包涵了悬疑,穿越,魔法,冒险等元素。 Jack.Tony于2009年秋季完成了"+ "《天之界线》的序章——沉睡的容器。");break;case R.id.progress_button_id:admain.progress_notification(intent, smallIcon, ticker, "有进度条的通知信息","正在下载中……");break;case R.id.pic_button_id:admain.pic_notification(intent, smallIcon, ticker, "有大图片的通知信息", LargeIcon);break;case R.id.btn_button_id:admain.btn_notification(intent,smallIcon, ticker, "有按钮的通知", "下面的按钮可点击");break;case R.id.clear_button_id:admain.clear();break;default:break;}}}

好,现在重头戏来了。

NotificationAdmain.java

package com.kale.notification;import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.widget.RemoteViews;public class NotificationAdmain {private static int NOTIFICATION_ID;private NotificationManager nm;private Notification notification;private NotificationCompat.Builder cBuilder;private Notification.Builder nBuilder;private Context mContext;int requestCode = (int) SystemClock.uptimeMillis();private static final int FLAG = Notification.FLAG_INSISTENT;public NotificationAdmain(Context context, int ID) {this.NOTIFICATION_ID = ID;mContext = context;// 获取系统服务来初始化对象nm = (NotificationManager) mContext.getSystemService(Activity.NOTIFICATION_SERVICE);cBuilder = new NotificationCompat.Builder(mContext);}/*** 设置在顶部通知栏中的各种信息* * @param intent* @param smallIcon* @param ticker*/private void setCompatBuilder(Intent intent, int smallIcon, String ticker,String title, String msg) {// 如果当前Activity启动在前台,则不开启新的Activity。
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);// 当设置下面PendingIntent.FLAG_UPDATE_CURRENT这个参数的时候,常常使得点击通知栏没效果,你需要给notification设置一个独一无二的requestCode// 将Intent封装进PendingIntent中,点击通知的消息后,就会启动对应的程序PendingIntent pIntent = PendingIntent.getActivity(mContext,requestCode, intent, FLAG);cBuilder.setContentIntent(pIntent);// 该通知要启动的Intent
cBuilder.setSmallIcon(smallIcon);// 设置顶部状态栏的小图标cBuilder.setTicker(ticker);// 在顶部状态栏中的提示信息
cBuilder.setContentTitle(title);// 设置通知中心的标题cBuilder.setContentText(msg);// 设置通知中心中的内容
        cBuilder.setWhen(System.currentTimeMillis());/** 将AutoCancel设为true后,当你点击通知栏的notification后,它会自动被取消消失,* 不设置的话点击消息后也不清除,但可以滑动删除*/cBuilder.setAutoCancel(true);// 将Ongoing设为true 那么notification将不能滑动删除// notifyBuilder.setOngoing(true);/** 从Android4.1开始,可以通过以下方法,设置notification的优先级,* 优先级越高的,通知排的越靠前,优先级低的,不会在手机最顶部的状态栏显示图标*/cBuilder.setPriority(NotificationCompat.PRIORITY_MAX);/** Notification.DEFAULT_ALL:铃声、闪光、震动均系统默认。* Notification.DEFAULT_SOUND:系统默认铃声。* Notification.DEFAULT_VIBRATE:系统默认震动。* Notification.DEFAULT_LIGHTS:系统默认闪光。* notifyBuilder.setDefaults(Notification.DEFAULT_ALL);*/cBuilder.setDefaults(Notification.DEFAULT_ALL);}/*** 设置builder的信息,在用大文本时会用到这个* * @param intent* @param smallIcon* @param ticker*/private void setBuilder(Intent intent, int smallIcon, String ticker) {nBuilder = new Notification.Builder(mContext);// 如果当前Activity启动在前台,则不开启新的Activity。
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);PendingIntent pIntent = PendingIntent.getActivity(mContext,requestCode, intent, FLAG);nBuilder.setContentIntent(pIntent);nBuilder.setSmallIcon(smallIcon);nBuilder.setTicker(ticker);nBuilder.setWhen(System.currentTimeMillis());nBuilder.setPriority(NotificationCompat.PRIORITY_MAX);nBuilder.setDefaults(Notification.DEFAULT_ALL);}/*** 普通的通知* * @param intent* @param smallIcon* @param ticker* @param title* @param msg*/public void normal_notification(Intent intent, int smallIcon,String ticker, String title, String msg) {setCompatBuilder(intent, smallIcon, ticker, title, msg);sent();}/*** 进行多项设置的通知(在小米上似乎不能设置大图标,系统默认大图标为应用图标)* * @param intent* @param smallIcon* @param ticker* @param LargeIcon* @param title* @param msg*/public void special_notification(Intent intent, int smallIcon,String ticker, int LargeIcon, String title, String msg) {setCompatBuilder(intent, smallIcon, ticker, title, msg);// 如果不设置LargeIcon,那么系统会默认将上面的SmallIcon作为主要图标,显示在通知选项的最左侧,右下角的小图标将不再显示Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),LargeIcon);cBuilder.setLargeIcon(bitmap);// 将Ongoing设为true 那么notification将不能滑动删除cBuilder.setOngoing(true);// 删除时Intent deleteIntent = new Intent(mContext, DeleteService.class);int deleteCode = (int) SystemClock.uptimeMillis();// 删除时开启一个服务PendingIntent deletePendingIntent = PendingIntent.getService(mContext,deleteCode, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT);cBuilder.setDeleteIntent(deletePendingIntent);cBuilder.setDefaults(Notification.DEFAULT_SOUND | // 设置使用默认的声音Notification.DEFAULT_LIGHTS);// 设置使用默认的LEDcBuilder.setVibrate(new long[] { 0, 100, 200, 300 });// 设置自定义的振动cBuilder.setAutoCancel(true);// builder.setSound(Uri.parse("file:///sdcard/click.mp3"));// 设置通知样式为收件箱样式,在通知中心中两指往外拉动,就能出线更多内容,但是很少见cBuilder.setNumber(3);cBuilder.setStyle(new NotificationCompat.InboxStyle().addLine("M.Lynn 你好,我是kale").addLine("M.Lynn 已收到,保证完成任务").addLine("M.Lynn 哈哈,明白了~").setSummaryText("+3 more")); // 设置在细节区域底端添加一行文本
        sent();}/*** 自定义视图的通知* * @param remoteViews* @param intent* @param smallIcon* @param ticker*/public void view_notification(RemoteViews remoteViews, Intent intent,int smallIcon, String ticker) {setCompatBuilder(intent, smallIcon, ticker, null, null);notification = cBuilder.build();notification.contentView = remoteViews;// 发送该通知
        nm.notify(NOTIFICATION_ID, notification);}/*** 可以容纳多行提示文本的通知信息 (因为在高版本的系统中才支持,所以要进行判断)* * @param intent* @param smallIcon* @param ticker* @param title* @param msg*/public void big_notification(Intent intent, int smallIcon, String ticker,String title, String msg) {final int sdk = android.os.Build.VERSION.SDK_INT;if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {normal_notification(intent, smallIcon, ticker, title, msg);} else {setBuilder(intent, smallIcon, ticker);nBuilder.setContentTitle(title);nBuilder.setPriority(Notification.PRIORITY_HIGH);notification = new Notification.BigTextStyle(nBuilder).bigText(msg).build();// 发送该通知
            nm.notify(NOTIFICATION_ID, notification);}}/*** 有进度条的通知,可以设置为模糊进度或者精确进度* * @param intent* @param smallIcon* @param ticker* @param title* @param msg*/public void progress_notification(Intent intent, int smallIcon,String ticker, String title, String msg) {setCompatBuilder(intent, smallIcon, ticker, title, msg);/** 因为进度条要实时更新通知栏也就说要不断的发送新的提示,所以这里不建议开启通知声音。* 这里是作为范例,给大家讲解下原理。所以发送通知后会听到多次的通知声音。*/new Thread(new Runnable() {@Overridepublic void run() {int incr;for (incr = 0; incr <= 100; incr += 10) {// 参数:1.最大进度, 2.当前进度, 3.是否有准确的进度显示cBuilder.setProgress(100, incr, false);// cBuilder.setProgress(0, 0, true);
                    sent();try {Thread.sleep(1 * 500);} catch (InterruptedException e) {e.printStackTrace();}}// 进度满了后,设置提示信息cBuilder.setContentText("下载完成~").setProgress(0, 0, false);sent();}}).start();}/*** 容纳大图片的通知* * @param intent* @param smallIcon* @param ticker* @param title* @param bigPic*/public void pic_notification(Intent intent, int smallIcon, String ticker,String title, int bigPic) {setCompatBuilder(intent, smallIcon, ticker, title, null);NotificationCompat.BigPictureStyle picStyle = new NotificationCompat.BigPictureStyle();Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),bigPic);picStyle.bigPicture(bitmap);cBuilder.setStyle(picStyle);sent();}/*** 里面有两个按钮的通知* * @param intent* @param smallIcon* @param ticker* @param title* @param msg*/public void btn_notification(Intent intent, int smallIcon, String ticker,String title, String msg) {Intent notifyIntent = new Intent(mContext, OtherActivity.class);int requestCode = (int) SystemClock.uptimeMillis();PendingIntent pendIntent = PendingIntent.getActivity(mContext,requestCode, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);setCompatBuilder(intent, smallIcon, ticker, title, msg);cBuilder.addAction(android.R.drawable.ic_media_previous,mContext.getString(R.string.previous), pendIntent);cBuilder.addAction(android.R.drawable.ic_media_next,mContext.getString(R.string.next), pendIntent);sent();}/*** 发送通知*/private void sent() {notification = cBuilder.build();// 发送该通知
        nm.notify(NOTIFICATION_ID, notification);}/*** 根据id清除通知*/public void clear() {// 取消通知
        nm.cancelAll();}
}

点击通知,或者是删除通知的时候都可以用intent触发一个service或者是activity,这里是删除时候触发的service

DeleteService

package com.kale.notification;import android.app.IntentService;
import android.content.Intent;
import android.util.Log;public class DeleteService extends IntentService{public DeleteService() {super("");// TODO Auto-generated constructor stub
    }@Overrideprotected void onHandleIntent(Intent intent) {Log.i("LOG", "===========deleteService");}}

最后,记得注册activity和service,把需要的权限也写上

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.kale.notification"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="18" /><!-- 闪光灯的权限 --><uses-permission android:name="android.permission.FLASHLIGHT"/><!-- 振动的权限 --><uses-permission android:name="android.permission.VIBRATE"/><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name=".MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activity android:name="com.kale.notification.OtherActivity"/><service android:name="com.example.notificationtest.DeleteService" /></application></manifest>

参考的文章:http://www.cnblogs.com/dyllove98/archive/2013/06/08/3127580.html

我还参考了一个demo,也十分优秀:http://download.csdn.net/detail/pringlee2011/6960743

源码下载:http://download.csdn.net/detail/shark0017/7668783

Notification详解(含工具类)相关推荐

  1. XmlMapper详解及工具类封装

    一.XmlMapper说明 1.依赖包引入 <dependency><groupId>com.fasterxml.jackson.dataformat</groupId& ...

  2. 【文件压缩解压工具类-含密码】

    文件压缩解压工具类-含密码 一.zip4j简介 二.zip4j工具类使用步骤 1.添加maven依赖 2.工具类代码 3.调用测试 三.结语 一.zip4j简介 zip4j功能比较强大,支持加密.解密 ...

  3. jQuery数组处理详解(含实例演示)

    jQuery的数组处理,便捷,功能齐全. 最近的项目中用到的比较多,深感实用,一步到位的封装了很多原生js数组不能企及的功能. 最近时间紧迫,今天抽了些时间回过头来看 jQuery中文文档 中对数组的 ...

  4. linux 进程间通信 dbus-glib【实例】详解三 数据类型和dteeth(类型签名type域)(层级结构:服务Service --> Node(对象、object) 等 )(附代码)

    linux 进程间通信 dbus-glib[实例]详解一(附代码)(d-feet工具使用) linux 进程间通信 dbus-glib[实例]详解二(上) 消息和消息总线(附代码) linux 进程间 ...

  5. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

  6. 【java】详解Java的类文件(class文件)结构

    1.概述 转载:详解Java的类文件(class文件)结构 大家好,我是二哥呀,今天我拿了一把小刀,准备解剖一下 Java 的 class 文件. CS 的世界里流行着这么一句话,"计算机科 ...

  7. 详解 QT 主要类 QWidget

    QWidget类是所有用户界面对象的基类,每一个窗口部件都是矩形,并且它们按Z轴顺序排列的.一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分. 先来看内容. AD: 2013云计算架构师 ...

  8. pytorch教程之nn.Module类详解——使用Module类来自定义网络层

    前言:前面介绍了如何自定义一个模型--通过继承nn.Module类来实现,在__init__构造函数中申明各个层的定义,在forward中实现层之间的连接关系,实际上就是前向传播的过程. 事实上,在p ...

  9. Zabbix+MatrixDB大规模监控与分析解决方案详解(含PPT)

    首先,谢谢原作者:(此文为转载的文章,现将原地址贴出如下:以下文章来源于yMatrix,作者MatrixDB团队Zabbix+MatrixDB大规模监控与分析解决方案详解(含PPT)) 更多精彩Zab ...

  10. pytorch教程之nn.Module类详解——使用Module类来自定义模型

    pytorch教程之nn.Module类详解--使用Module类来自定义模型_MIss-Y的博客-CSDN博客_nn是什么意思前言:pytorch中对于一般的序列模型,直接使用torch.nn.Se ...

最新文章

  1. (转)互斥对象锁和临界区锁性能比较 .
  2. 一条关于互联网创业公司健康与否的判断法则
  3. js中使用template.js插件
  4. c语言87,C语言程序设计87300.doc
  5. python timeit class Timer()类 timeit(string, string) repeat(string, string) default_timer() 耗时检测 执行速度
  6. 计算机减法英语,英语加减乘除的表达
  7. 前端学习(3121):react-hello-react的总结state
  8. tensorrt基础知识+torch版lenet转c++ trt
  9. 大数据概论ppt_解读 | 货拉拉搬家大数据报告(30页PPT干货)
  10. webbrowser 检测ajax,控制台获取网页AJAX的返回数据,用的WebBroWser
  11. “SecureCRT遇到一个致命的错误且必须关闭”处理办法
  12. 《电磁学》学习笔记4——磁场高斯定理、安培环路定理、电动势
  13. java外卖系统源码_java外卖订餐系统小项目
  14. 《机关单位办公自动化应用指南 (基于国产信息技术应用创新终端)》
  15. 运维工程师使用的运维平台和工具表
  16. android 设置字体大小不随系统大小变化,App字体大小不随系统改变而改变
  17. python_matplotlib改变横坐标和纵坐标上的刻度(ticks)
  18. 对话南科大沈平:在人工智能开源中,高校能扮演什么角色?
  19. 在线答题小程序关于完形填空题的设计
  20. gem mysql_ruby gem 本地安装方法以及在windows下添加mysql.gem

热门文章

  1. python后端和爬虫_【后端开发】python爬虫难学吗
  2. qt mdi 子窗口关闭再打开_QT 信号的使用方法
  3. java实现调查问卷_jsp70516调查问卷自动生成与分析系统 双数据库 mysql版
  4. 想去机器学习初创公司做数据科学家?这些问题值得你三思!
  5. 利用图片指纹检测高相似度图片--相似图片搜索的原理
  6. Python的中文处理
  7. Gibbs 采样完整解析与理解
  8. 【POJ 2104】【主席树模板题】K-th Number
  9. python学习笔记之其它
  10. [MySQL]触发器