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

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

  • NotificationCompat.Builder位于v4扩展包内(version 4 Support Library)
  • Notification.Builder在Android 3.0 开始引入(API level 11).

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

问题原因

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

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源码,里面写的较详细。

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

源码分析

下面看一下到底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二次处理,也就是这里会改变我们最终看到的通知图标,包括顶部状态栏和下拉显示的小图标。

参考

  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/

时间: 2024-07-30 04:05:00

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

Guice2.0的变化——第一部分 新的特性(上)

http://superleo.iteye.com/blog/314816 Private Modules PrivateModules 用于创建并不需要对外可见的绑定对象.当然,这样会使得封装变得更加简单,还避免了冲突. 作者没有写关于 PrivateModules 的内容,有可能还没有更新完吧.我们就简单看一个例子: Java代码 public class FooBarBazModule extends PrivateModule { protected void configurePriv

Android5.0以上app进程保活的正确姿势

我的原文: http://blog.csdn.net/brycegao321/article/details/52312030 有图有真相,  亲测锤子T2.华为Mate8手机杀掉进程后能自启, 我设置的自启时间间隔为500ms(仅仅是为了测试).     首先要明确保活的概念: 1.非android核心进程(例如com.android.phone)都可以被干掉: 2.保活并不能真正的保证app进程不死,  而是能在被干掉后马上启动: Android系统按照进程的优先级分为: 1. 前台进程(F

小米S2手机刷android5.0

小米2S MIUI6 android5.0系统 想装一个原声的android5.0系统.... 于是,惨痛的一天就开始了.... 一:小米系统自带的系统更新直接安装ROM的zip包 我下载了一个又一个的ROM包..都告诉我不能用!! 无论是直接在系统选择,还是改名成update.zip从recovery中进.... 二:猜测原因需要第三方recovery,官方recovery只能更新MIUI相关的官方ROM 那就换个第三方recovery把,然而..这个万恶的recovery啊!!! 1,刷第三

Android5.0系统的优缺点

Android L(5.0)正式定名为 Lollipop(棒棒糖).安卓已经六岁了,也总算有一次重大改观了.安卓5.0 Lollipop带来了全新的,扁平化的外观,更好的通知中心,重新设计的核心应用,并提升了在安卓设备上的性能表现--增加了一些以前所缺失的重要应用类别. 首先来看一下Android L相比之前的版本有什么新鲜的东西. 原文博客请参考:点击打开链接 一:自定义通知中心 Lollipop为用户带来了对通知中心前所未有的控制性,每一个应用程序都可以在通知中心进行单独的设置,并且只有在用

Android自定义组件系列【14】——Android5.0按钮波纹效果实现

今天任老师发表了一篇关于Android5.0中按钮按下的波纹效果实现<Android L中水波纹点击效果的实现>,出于好奇我下载了源代码看了一下效果,正好手边有一个Nexus手机,我结合实际效果看了一下,发现有一些地方和实际效果稍有不同,参考任老师的博文实现简单实现了一个重写View组件的代码,将全部代码贴出,如果有什么问题或者更好的方式请指出,在此再次感谢任老师的这篇博文. 转载请说明出处:http://blog.csdn.net/dawanganban 顺便在这里拉一下票,如果你觉得这篇文

Android5.0 之一 概述

Android 5更新你的应用程序添加各种新功能,比如在锁屏通知,一个全新的相机API,OpenGL ES 3.1,新材料的设计界面,以及更多. 1 手机发展的过程 2 Linux发展的历史 3 智能手机平台简介 4 Android的诞生 5 Android的优势 手机发展的过程 1G手机--传说中的"大哥大"时代 1983年摩托罗拉推出了首款手机 型号:DynaTAC 8000X 重1公斤多 充电时间10小时,通话时间半小时 研发周期超过了10年 耗资超过1亿美元 摩托罗拉是最早进入

实现Android5.0过渡动画兼容库

Android5.0之后为我们提供了许多炫酷的界面过渡效果,其中共享元素过渡也是很有亮点的一个效果,但这个效果只能在Android5.0之后使用,那今天我们就来将共享元素过渡效果兼容到Android4.0,让5.0之前的手机也可以体验这么炫酷的效果吧. A transition animation compatible Library. 兼容Android5.0之后转场动画至Android4.0. github地址:https://github.com/zhangke3016/Translati

Android5.0开发范例大全 读书笔记(六)

(六)与系统交互 6.1后台通知 1.关于后台通知,下面展示6种样式.值得一提的是,笔者的小米5只能显示基本样式,雷军真是良心厂商啊. 2.首先上布局xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="

一个Activity掌握Android5.0新控件 (转)

原文地址:http://blog.csdn.net/lavor_zl/article/details/51279386 谷歌在推出Android5.0的同时推出了一些新控件,Android5.0中最常用的新控件有下面5种. 1. CardView(卡片视图) CardView顾名思义是卡片视图,它继承FrameLayout.它是一个带圆角的背景和阴影FrameLayout.CardView被包装为一种布局,并且经常在ListView和RecyclerView的Item布局中,作为容器使用. Ca