最近遇到一个问题,就是本来是彩色的图标,结果在5.x的设备商status bar上面notification icon的颜色是黑白的,而在4.x上面是彩色的。
在SO上面找到这篇文章,http://stackoverflow.com/questions/28387602/notification-bar-icon-turns-white-in-android-5-lollipop。大意就是这个是5.x(api 21)的新行为,如果AndroidManfifext.XML中的android:targetSdkVersion设置为21,那么在5.x的系统上,就是这种行为。如果一定要显示彩色,像4.x那样,就设置android:targetSdkVersion为老的api号,例如20。
正好研究了下targetSdkVersion生效的机制。对于这个例子而言,可以参看BaseStatusBar的实现代码:
if (entry.targetSdk >= Build.VERSION_CODES.LOLLIPOP) { entry.icon.setColorFilter(mContext.getResources().getColor(android.R.color.white)); } else { entry.icon.setColorFilter(null); }
他会根据entry.targetSdk判断是否使用黑白模式。
这里的targetSdk就是在android:targetSdkVersion。如果看这段代码的调用关系,就会发现entry.targetSdk的值是通过:
ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0); entry.targetSdk = info.targetSdkVersion;
赋值的,即ApplicaitonInfo.targetSdkVersion。
所以如果是在5.x的系统(sdk version是21/22)上运行应用,如果指定了targetsdkversion为21/22,那就会生效黑白模式;如果指定了targetSdkVersion为20或更低的值,则这段新的原色过滤的逻辑不生效,还是使用原有系统的行为。于是如果我们想在新的系统上仍然让应用保持旧系统的行文,就可以通过设置该属性为旧api版本来实现。
如果设置了targetSdkVersion为21,但运行在旧的4.x系统上(例如api 19),那因为实际的sdk runtime根本没有处理这么高targetSdkVersion的代码,所以自然也不会生效。而且sdk的代码一般采用>=某个版本号的方式来判断,所以保证了写21和写19的效果在19的机器上是完全一样的。