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

来源:互联网 发布:红米2网络解锁功能 编辑:程序博客网 时间:2024/06/07 17:12

本文源码托管在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")@Overridepublic 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")@Overridepublic 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 sizecustomerRemoteView.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 doneif (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 somethingmNotifyTextColor = 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 ,未经本人同意请勿用于商业用途,谢谢——
0 0
原创粉丝点击