【直接拿来用のandroid公共代码模块解析与分享】の Notification和NotificationManager

本文源代码托管在https://github.com/ASCE1885/asce-common,欢迎fork

Android项目做得多了。会发现原来非常多基础的东西都是能够复用,这个系列介绍一些自己项目中经常使用到的公共模块代码(当然仅仅谈技术不谈业务),一来整理好了自己以后能够直接用,二来也分享给大家,希望能略微降低大家的加班时间,提高些许效率。

Android Notification的原理和作用这里就不作说明了,相信是个android开发人员都用过不止一次了,下面仅仅介绍怎样封装成公共的模块。以供整个项目使用。

基于不同的目的。Notification的外观区别非常大,相应到代码上就是布局的差异,因此。我们首先须要有一个接口供使用者来创建不同布局的Notification,接口在Java中当然是以Interface的形式存在。如代码清单IMyNotificationBuilder.java所看到的。

/**
 * Notification接口
 *
 * @author asce1885
 * @date 2014-06-09
 *
 */
public interface IMyNotificationBuilder {

	public static final String NOTIFICATION_ID = IMyNotificationBuilder.class.getSimpleName();

	Notification buildNotification(String title, String content);

}

看到这里,熟悉设计模式的同学应该知道我们使用的是Builder模式来构建不同的Notification,依照惯例,一般会有一个默认的Builder实现,我们将之命名为BasicNotificationBuilder.java。它使用的是Android系统默认的通知栏布局。

/**
 * 默认Notification构造器
 *
 * @author asce1885
 * @date 2014-06-09
 *
 */
public class BasicNotificationBuilder implements IMyNotificationBuilder {

	private Context mContext;
	private PendingIntent mPendingIntent;

	public int mIconDrawableId;

	public BasicNotificationBuilder(Context context, PendingIntent pendingIntent) {
		mContext = context;
		mPendingIntent = pendingIntent;
		mIconDrawableId = PackageUtils.getAppInfo(context).icon;
	}

	public BasicNotificationBuilder(Context context, PendingIntent pendingIntent, int iconDrawableId) {
		mContext = context;
		mPendingIntent = pendingIntent;
		mIconDrawableId = iconDrawableId;
	}

	@SuppressWarnings("deprecation")
	@Override
	public Notification buildNotification(String title, String content) {
		Notification basicNotification = new Notification(mIconDrawableId, title,
				System.currentTimeMillis());
		basicNotification.setLatestEventInfo(mContext, title, content, mPendingIntent);
		basicNotification.flags |= Notification.FLAG_AUTO_CANCEL;
		basicNotification.defaults = Notification.DEFAULT_SOUND;
		basicNotification.contentIntent = mPendingIntent;

		return basicNotification;
	}

}

对于其它须要自己定义布局的通知栏形式。我们另外实现一个类。布局文件由使用者自己定义,见代码清单CustomNotificationBuilder.java。

/**
 * 自己定义样式Notification构造器
 *
 * @author asce1885
 * @date 2014-06-09
 *
 */
public class CustomNotificationBuilder implements IMyNotificationBuilder {

	private Context mContext;
	private int mCustomeLayout;
	private int mLayoutSubjectId;
	private int mLayoutMessageId;
	private int mLayoutIconId;
	private int mStatusBarIconDrawableId;
	private Uri mSoundUri;
	private PendingIntent mPendingIntent;

	public CustomNotificationBuilder(Context context, int customeLayout, int layoutSubjectId, int layoutMessageId, int layoutIconId, int statusBarIconDrawableId, Uri soundUri, PendingIntent pendingIntent) {
		mContext = context;
		mCustomeLayout = customeLayout;
		mLayoutSubjectId = layoutSubjectId;
		mLayoutMessageId = layoutMessageId;
		mLayoutIconId = layoutIconId;
		mStatusBarIconDrawableId = statusBarIconDrawableId;
		mSoundUri = soundUri;
		mPendingIntent = pendingIntent;
	}

	@SuppressWarnings("deprecation")
	@Override
	public Notification buildNotification(String title, String content) {
		if (TextUtils.isEmpty(content)) {
			return null;
		}

		PreFroyoNotificationStyleDiscover.getInstance().discoverStyle(mContext);

		Notification customerNotification = new Notification(mStatusBarIconDrawableId, title,
				System.currentTimeMillis());
		RemoteViews customerRemoteView = new RemoteViews(mContext.getPackageName(), mCustomeLayout);
		customerRemoteView.setTextViewText(mLayoutSubjectId, PackageUtils.getAppName(mContext));
		customerRemoteView.setTextViewText(mLayoutMessageId, content);
		customerRemoteView.setImageViewResource(mLayoutIconId, mStatusBarIconDrawableId);
		customerNotification.flags |= Notification.FLAG_AUTO_CANCEL;

		if (mSoundUri != null) {
			customerNotification.sound = mSoundUri;
		} else {
			customerNotification.defaults = Notification.DEFAULT_SOUND;
		}
		customerNotification.contentIntent = mPendingIntent;

		// Some SAMSUNG devices status bar cant't show two lines with the size,
		// so need to verify it, maybe increase the height or decrease the font size

		customerRemoteView.setFloat(mLayoutSubjectId, "setTextSize",
				PreFroyoNotificationStyleDiscover.getInstance().getTitleSize());
		customerRemoteView.setTextColor(mLayoutSubjectId, PreFroyoNotificationStyleDiscover
				.getInstance().getTitleColor());

		customerRemoteView.setFloat(mLayoutMessageId, "setTextSize",
				PreFroyoNotificationStyleDiscover.getInstance().getTextSize());
		customerRemoteView.setTextColor(mLayoutMessageId, PreFroyoNotificationStyleDiscover
				.getInstance().getTextColor());

		customerNotification.contentView = customerRemoteView;

		return customerNotification;
	}

	/**
	 * A class for discovering Android Notification styles on Pre-Froyo (2.3) devices
	 */
	private static class PreFroyoNotificationStyleDiscover {

		private Integer mNotifyTextColor = null;
		private float mNotifyTextSize = 11;
		private Integer mNotifyTitleColor = null;
		private float mNotifyTitleSize = 12;
		private final String TEXT_SEARCH_TEXT = "SearchForText";
		private final String TEXT_SEARCH_TITLE = "SearchForTitle";

		private static Context mContext;

		private static class LazyHolder {
			private static final PreFroyoNotificationStyleDiscover sInstance = new PreFroyoNotificationStyleDiscover();
		}

		public static PreFroyoNotificationStyleDiscover getInstance() {
			return LazyHolder.sInstance;
		}

		private PreFroyoNotificationStyleDiscover() {

		}

		public int getTextColor() {
			return mNotifyTextColor.intValue();
		}

		public float getTextSize() {
			return mNotifyTextSize;
		}

		public int getTitleColor() {
			return mNotifyTitleColor;
		}

		public float getTitleSize() {
			return mNotifyTitleSize;
		}

		private void discoverStyle(Context context) {
			mContext = context;
			// Already done
			if (null != mNotifyTextColor) {
				return;
			}

			try {
				Notification notify = new Notification();
				notify.setLatestEventInfo(mContext, TEXT_SEARCH_TITLE, TEXT_SEARCH_TEXT, null);
				LinearLayout group = new LinearLayout(mContext);
				ViewGroup event = (ViewGroup) notify.contentView.apply(mContext, group);
				recurseGroup(event);
				group.removeAllViews();
			} catch (Exception e) {
				// Default to something
				mNotifyTextColor = android.R.color.black;
				mNotifyTitleColor = android.R.color.black;
			}
		}

		private boolean recurseGroup(ViewGroup group) {
			final int count = group.getChildCount();

			for (int i = 0; i < count; ++i) {
				if (group.getChildAt(i) instanceof TextView) {
					final TextView tv = (TextView) group.getChildAt(i);
					final String text = tv.getText().toString();
					if (text.startsWith("SearchFor")) {
						DisplayMetrics metrics = new DisplayMetrics();
						WindowManager wm = (WindowManager) mContext
								.getSystemService(Context.WINDOW_SERVICE);
						wm.getDefaultDisplay().getMetrics(metrics);

						if (TEXT_SEARCH_TEXT == text) {
							mNotifyTextColor = tv.getTextColors().getDefaultColor();
							mNotifyTextSize = tv.getTextSize();
							mNotifyTextSize /= metrics.scaledDensity;
						} else {
							mNotifyTitleColor = tv.getTextColors().getDefaultColor();
							mNotifyTitleSize = tv.getTextSize();
							mNotifyTitleSize /= metrics.scaledDensity;
						}

						if (null != mNotifyTitleColor && mNotifyTextColor != null) {
							return true;
						}
					}
				} else if (group.getChildAt(i) instanceof ViewGroup) {
					if (recurseGroup((ViewGroup) group.getChildAt(i))) {
						return true;
					}
				}
			}
			return false;
		}
	}

}

Notification的构建代码至此结束。而要发出Notification,使用的是NotificationManager,我们将它封装成代码清单MyNotificationManager.java。

/**
 * Notification管理器
 *
 * @author asce1885
 * @date 2014-06-09
 *
 */
public class MyNotificationManager {

	private IMyNotificationBuilder mMyNotificationBuilder;

	private static final int START_ID = 1000;
	private static final int RANGE = 50;
	private int mCurrentId = START_ID;

	private MyNotificationManager() {

	}

	private static class LazyHolder {
		private static final MyNotificationManager sInstance = new MyNotificationManager();
	}

	public static MyNotificationManager getInstance() {
		return LazyHolder.sInstance;
	}

	public IMyNotificationBuilder getMyNotificationBuilder() {
		return mMyNotificationBuilder;
	}

	public void setMyNotificationBuilder(IMyNotificationBuilder builder) {
		mMyNotificationBuilder = builder;
	}

	public void deliverNotification(Context context, String title, String content) {
		buildAndDisplayNotification(context, title, content);
	}

	private void buildAndDisplayNotification(Context context, String title, String content) {
		if (null != mMyNotificationBuilder) {
			Notification notification = mMyNotificationBuilder.buildNotification(title, content);
			if (null != notification) {
				notification.flags |= Notification.FLAG_AUTO_CANCEL;
				NotificationManager notificationManager = (NotificationManager) context
						.getSystemService(Context.NOTIFICATION_SERVICE);
				notificationManager.notify(generateNotification(), notification);
			}
		}
	}

	private int generateNotification() {
		mCurrentId++;
		if (mCurrentId >= START_ID + RANGE) {
			mCurrentId = START_ID;
		}
		return mCurrentId;
	}
}

最后给下使用的演示样例代码例如以下所看到的,仅仅作为參考。里面的部分变量不用深究。

				Intent intent = new Intent(getApplicationContext(), MainActivity.class);
				intent.putExtra(BundleConstant.KEY_NOTIFICATION_TYPE, action);
				intent.putExtra(BundleConstant.KEY_WEBVIEW_TITLE, notice.webview_title);
				intent.putExtra(BundleConstant.KEY_WEBVIEW_URL, notice.webview_url);
				PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), (int) notice.nid, intent, PendingIntent.FLAG_UPDATE_CURRENT);

				builder = new BasicNotificationBuilder(getApplicationContext(), pendingIntent);
				MyNotificationManager.getInstance().setMyNotificationBuilder(builder);
				MyNotificationManager.getInstance().deliverNotification(getApplicationContext(), notice.notification_title, notice.notification_content);

——欢迎转载。请注明出处 http://blog.csdn.net/asce1885 ,未经本人允许请勿用于商业用途。谢谢——

时间: 2024-10-19 13:55:10

【直接拿来用のandroid公共代码模块解析与分享】の Notification和NotificationManager的相关文章

android 应用升级模块解析

一共就用到一个类:   假定当前为第1版,通过对后台的请求,收到第2版的更新通知.代码如: package com.example.ex_templete; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedU

系统管理模块_部门管理_改进_抽取添加与修改JSP页面中的公共代码_在显示层抽取BaseAction_合并Service层与Dao层

系统管理模块_部门管理_改进1:抽取添加与修改JSP页面中的公共代码 commons.jspf <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <meta http-equiv="Conten

Android 开源项目android-open-project工具库解析之(一) 依赖注入,图片缓存,网络相关,数据库orm工具包,Android公共库

一.依赖注入DI 通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作 AndroidAnnotations(Code Diet) android快速开发框架 项目地址:https://github.com/excilys/androidannotations 文档介绍:https://github.com/excilys/androidannotations/wiki 官网网址:http://androidannotations.org/ 特点:(1) 依赖注入:包括view

160多个android开源代码汇总

第一部分 个性化控件(View) 主要介绍那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.ProgressBar.TextView.ScrollView.TimeView.TipView.FlipView.ColorPickView.GraphView.UI Style等等..其他 一.ListView android-pulltorefresh一个强大的拉动刷新开源项目,支持各种控件下拉刷新

Android开源代码汇总

第一部分 个性化控件(View) 主要介绍那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.ProgressBar.TextView.ScrollView.TimeView.TipView.FlipView.ColorPickView.GraphView.UI Style等等. .其他 一.ListView Android-pulltorefresh 一个强大的拉动刷新开源项目,支持各种控件下拉

(通用)Android App代码混淆终极解决方案【转】

App虽然没有那么的高大上,但是代码的混淆是代表了程序员对App的责任心, 也是对App安全的一点点保证.今天我会将自己做Android混淆的过程和体会分享给大家,也避免大家少走弯路,少跳坑. 本篇博客混淆基于Android Studio的IDE开发环境. 其实在android Studio中做混淆,基本就是对Proguard-rules.pro文件的操作.混淆的过程也是有规律可循的.下面我将分几个部分来分别介绍混淆过程. (1)如何开启混淆. (2)混淆的公共部分. (3)需要我们不混淆的代码

Android Studio代码着色插件

Android Studio代码着色插件 前言:半个多月没写博客了,放了个假期,这人才缓过来神,懒的啥都不想干,可算是明白一句话的意思了:玩物丧志啊!好在公司项目赶的紧,不想干活都不行,强行撸上正轨-- 正因为夜以继日的Coding赶模块,最近感觉眼睛干涩,眼圈红肿,看着那些颜色一层不变的abc,心里莫名的冒火,故有了本篇博文.还是建议大家敲一会abc后,起来走动走动,眼睛看看远处,让眼圈周围血液循环循环.不要像本屌,昨天回家路上买瓶水,付账时老板娘女儿问,你是不是搞IT的 ?!  ---- 此

Android bluetooth介绍(二): android 蓝牙代码架构及其uart 到rfcomm流程

关键词:蓝牙blueZ  UART  HCI_UART H4  HCI  L2CAP RFCOMM  版本:基于android4.2之前版本 bluez内核:linux/linux3.08系统:android/android4.1.3.4作者:xubin341719(欢迎转载,请注明作者,请尊重版权谢谢)欢迎指正错误,共同学习.共同进步!!一.Android Bluetooth Architecture蓝牙代码架构部分(google 官方蓝牙框架) Android的蓝牙系统,自下而上包括以下一些

Eclipse中Android公共库的正确建立及调用方法(转)

转自http://www.cnblogs.com/SkyD/archive/2011/09/01/2161502.html 引言 之前一直头痛于没有办法在多个程序中共享资源,用作公共类库的方法也是使用的导出jar再导入的办法,现在终于初步搞明白了,可算解脱了~,分享出来. 建立公共库 首先建立公共库的Android项目,名为MyCoreLib: 完成后在左侧包浏览器里右键点选我们新建的这个项目,选择Properties项: 左侧选择Android分类,右侧勾选Is Library选项: 完成后在