Android5.0通知变化浅析-最近在Android5.1设备上发现一个问题:通知图标变成了白色的

目前在Android中通知的使用仍是很常见的,为了作版本兼容,经常使用兼容包NotificationCompat.Builder和 Notification.Builder。html

  • NotificationCompat.Builder位于v4扩展包内(version 4 Support Library)java

  • Notification.Builder在Android 3.0 开始引入(API level 11).android

最近在Android5.0设备上发现一个问题:通知图标忽然变成了白色的方块而不是代码中设置的icon。程序员

问题缘由

细读开发者文档其实也能够发现一些线索,虽然笔者是直接查的源码发现的问题缘由。http://developer.android.com/design/patterns/notifications.html 一文的Use distinct icons部分介绍了几点关于通知的建议,其中的有两点是建议开发者不要作的行为。api

Don't
Place any additional alpha (dimming or fading) into your small icons and action icons; they can have anti-aliased edges, but because Android uses these icons as masks (that is, only the alpha channel is used), the image should generally be drawn at full opacity.

Don't
Use color to distinguish your app from others. Notification icons should only be a white-on-transparent background image.

简单的说就是5.0后Android官方建议不要为通知的图标添加任何额外的透明度,渐变色,不要企图用颜色将通知图标与其余应用,好比系统应用,应用的通知图标只能是在透明的背景上有白色的图案。
至于缘由,文档并无细说,只是提到5.0系统将会在底层处理图标,想知怎么处理的能够参考Android SDK API level 21后的Notificaiton源码,里面写的较详细。
Project Structure
Project Structureapp

结合文档提供的图片示例,应该能够理解。
若是不遵循建议那么有很大概率是会出上文提到问题的,为何不是别然出问题呢?
这还依赖于代码编译的版本,根据尝试,目前api 21之后编译会出问题,20及之前的版本编译不会出问题。因此解决问题比较简单粗暴的方案是用20及更早的版本编译代码。可是要测底解决问题,仍是得遵循文档指导,及重新设计通知的图标以符合要求。ide

源码分析

下面看一下到底21的Android源码里面作了什么操做会致使通知的图标通通变白色。
Notification.java源码分析

private RemoteViews applyStandardTemplate(int resId, boolean hasProgress) {	//...
	if (mLargeIcon != null) {
         contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
         processLargeLegacyIcon(mLargeIcon, contentView);
         contentView.setImageViewResource(R.id.right_icon, mSmallIcon);
         contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
         processSmallRightIcon(mSmallIcon, contentView);
     } else { // small icon at left
         contentView.setImageViewResource(R.id.icon, mSmallIcon);
         contentView.setViewVisibility(R.id.icon, View.VISIBLE);
         processSmallIconAsLarge(mSmallIcon, contentView);
    }    //...}
        /**
         * Recolor small icons when used in the R.id.right_icon slot.
         */
        private void processSmallRightIcon(int smallIconDrawableId,
                RemoteViews contentView) {            if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, smallIconDrawableId)) {
                contentView.setDrawableParameters(R.id.right_icon, false, -1,                        0xFFFFFFFF,
                        PorterDuff.Mode.SRC_ATOP, -1);

                contentView.setInt(R.id.right_icon,                        "setBackgroundResource",
                        R.drawable.notification_icon_legacy_bg);

                contentView.setDrawableParameters(
                        R.id.right_icon,                        true,
                        -1,
                        resolveColor(),
                        PorterDuff.Mode.SRC_ATOP,
                        -1);
            }
        }

这里我截取了两段比较关键的代码,在用NotificationCompat.Builder实例化咱们的通知后,最终须要将各类图标,参数配置,应用到通知视图上面。能够看到若是咱们只设置smallIcon而不设置largeIcon也是能够的,此时直接将small做为大图标设置给左侧的id为R.id.icon的ImageView。要注意的事通常状况下都不能够不设置smallIcon,不然通知没法正常显示出来。
processSmallIconAsLarge方法里面负责将咱们设置的smallIcon二次处理,也就是这里会改变咱们最终看到的通知图标,包括顶部状态栏和下拉显示的小图标。测试

 

///////////////////////////////////2018-5-9 第二次编辑///////////////////////////////////////////////////ui

对于通知栏的使用,Android各个版本其实都有比较大的调整,包括即将发布的Android 7.0版本,通知栏功能上又要有大动做。那么新版本的通知栏API没法兼容老系统这就会是一个很头疼的问题。

为此Android在appcompat-v7库中提供了一个NotificationCompat类来处理新老版本的兼容问题,咱们在编写通知功能时都使用NotificationCompat这个类来实现,appcompat-v7库就会自动帮咱们作好全部系统版本的兼容性处理了。一段基本的触发通知代码以下所示:

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
Notification notification = builder
.setContentTitle("这是通知标题")
.setContentText("这是通知内容")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.build();
manager.notify(1, notification);

能够看到,这里只是把咱们平时使用的Notification.Builder改为了NotificationCompat.Builder而已,其余用法都是如出一辙的,这样咱们的通知就具有各类Android版本的兼容性了。

注意看一下咱们给通知设置的图标,一个小图标、一个大图标,都是使用的R.mipmap.ic_launcher这张图。其实不少app都使用的这种作法,即直接拿应用程序的icon来做为通知的图标,好像这样看上去也挺合理的。

如今我使用Android 6.0系统的Nexus 5手机运行这个程序,并触发上面那段通知逻辑,效果如图下图所示:

能够看到,通知栏上弹出了一个通知图标。而后咱们将通知栏下拉展开,效果以下图所示:


效果好像还不错的样子。但实际上,我如今是将项目的targetSdkVersion指定成了21如下,即低于5.0系统。若是将targetSdkVersion指定成21或者更高的话,结果可能就不乐观了:

defaultConfig {
    ....
    targetSdkVersion 23
}

这里咱们将targetSdkVersion指定成了23,而后从新运行程序并触发图标逻辑,效果以下图所示:


恩?这是什么鬼,怎么通知图标变成白白的一个圆了。下拉以后的大图效果以下:


好像下拉以后的大图还算正常,不过大图的右下角也有一个白白的圆。
这究竟是为何呢?实际上,Android从5.0系统开始,对于通知栏图标的设计进行了修改。如今Google要求,全部应用程序的通知栏图标,应该只使用alpha图层来进行绘制,而不该该包括RGB图层。

说的好像很玄乎,什么叫做只使用alpha图层来进行绘制呢?其实通俗点来说,就是让咱们的通知栏图标不要带颜色就能够了。

恩?不带颜色!那图标还怎么设计?但这就不是咱们程序员应该考虑的问题了,而是应该交给项目的UI设计师来想办法,但咱们须要将这个设计需求清楚地告诉设计师,由于他们一般并不知道Google的各类标准和要求。

那么咱们来参考一下别的程序都是怎么设计通知栏图标的,这是支付宝的通知栏图标:

图片描述


下拉通知以后的效果是这样的:

图片描述
而后再看一下网易新闻的通知栏图标:

图片描述
下拉通知以后的效果是这样的:

图片描述


能够看出,它们的通知栏小图都是没有RGB色的,图标是只有白色一种颜色,而后借助alpha图层来绘制出一个logo的样式。
所以,按着这种设计要求,我将项目的通知栏图标改为了这个样子:

图片描述

这张图只用于替换通知的小图部分,大图仍然仍是用原来的那样图就能够了。如今从新运行一下程序,效果以下图所示:

图片描述
这样看上去效果就好多了吧?而后下拉通知栏以后的效果以下图所示:

图片描述
这里咱们来仔细观察一下这个下拉后的大图,其实前面你们应该也已经注意到了,只不过一直没提,在大图标的右下角,还有一个比较小的圆圈,在这个圆圈中嵌套着咱们设置的小图标。

这个功能是系统自动附加的一个功能,并不须要咱们进行任何的代码设置,能够观察一下,支付宝、网易新闻也都是有这个功能的。可是若是咱们再看仔细一点,你会发现网易的图标更好看一些,由于系统给右下角的这个小圆圈默认是设置成灰色的,和咱们的总体色调并不搭配,而网易则将这个小圆圈改为了红色,所以整体视觉效果更好。

那么怎样修改这个小圆圈的颜色呢?其实很是简单,只须要在NotificationCompat.Builder中再多连缀一个setColor()方法就能够了,以下所示:

Notification notification = builder
        ......
        .setColor(Color.parseColor("#EAA935"))
        .build();

如今从新运行一下程序,通知栏大图的具体效果以下图所示:

图片描述
怎么样,如今的效果是否是更棒了?可是这里我还要给你们提个醒,上面的功能我使用Nexus手机和三星手机都测试过,结果都是正常的,可是使用小米手机测试就比较无语了,MIUI系统直接无视咱们设置的大图和小图,一概使用应用程序的icon来做为通知栏图标,因此若是你是使用的小米手机,就测试不出来上述的各类效果了。其余手机的兼容性我尚未试过,不过无论怎么样,咱们的代码都是要这么写的,至于那些定制过的系统该如何去解析展现,那是这些第三方厂商的事情,毕竟咱们程序员也是控制不了的。

固然,若是你手上只有小米手机的话,也不要绝望,仍是可使用Android模拟器来测试这个功能的。
本文出自郭霖的博客


做者: 郭霖 
连接:http://www.imooc.com/article/8175
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合做

参考

  1. http://developer.android.com/design/patterns/notifications.html

  2. http://developer.android.com/guide/topics/ui/notifiers/notifications.html

做者:小文字

出处:http://www.cnblogs.com/avenwu/

相关文章
相关标签/搜索