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 ,未经本人同意请勿用于商业用途,谢谢——
【直接拿来用のandroid公共代码模块解析与分享】の Notification和NotificationManager,布布扣,bubuko.com
【直接拿来用のandroid公共代码模块解析与分享】の Notification和NotificationManager