今天,接到这么一个需求:
Need to change the notification color on the top right of the icons, right now it is a green blue color, let's change it to #FC3D30 as a red dot.
意思很清楚:当前 Android 8.1.0 版本的系统默认 Notification Badge color 是蓝绿色的,现在客户想把它改成红色(#FFFC3D30 )的。
先看一眼修改之前的颜色(其实我觉得还可以...):
接下来,Change it.
首先找到 IconDrawableFactory.java,所在路径:
Code/frameworks/base/core/java/android/util/IconDrawableFactory.java
在这个类里面,可以看到系统对默认 Notification Badge color 的引用:
// Should have enough colors to cope with UserManagerService.getMaxManagedProfiles()
@VisibleForTesting
public static final int[] CORP_BADGE_COLORS = new int[] {
com.android.internal.R.color.profile_badge_1,
com.android.internal.R.color.profile_badge_2,
com.android.internal.R.color.profile_badge_3
};
哇,我们好厉害,一下就找到了系统源码中对默认 Notification Badge color 的引用!
额,其实不是的,找到这个地方,费了一些时间的...
找到了颜色引用,那在哪里声明的这几个颜色呢?
执行:find .|xargs grep -ri "profile_badge_1",找到:
Code/frameworks/base/core/res/res/values/colors.xml
<!-- Default profile badge colors -->
<color name="profile_badge_1">#ffff6d00</color><!-- Orange -->
<color name="profile_badge_2">#ff000000</color><!-- Black -->
<color name="profile_badge_3">#ff22f033</color><!-- Green -->
发现,现在默认的应用的 Notification Badge color 可不就是绿色(#ff22f033)的嘛,话不多说,在colors.xml 中添加上我们的颜色:
<color name="profile_badge_4">#FFFC3D30</color><!-- Red -->
然后,在 IconDrawableFactory.java 中,修改所有的颜色为 profile_badge_4
@VisibleForTesting
public static final int[] CORP_BADGE_COLORS = new int[] {
com.android.internal.R.color.profile_badge_4,
com.android.internal.R.color.profile_badge_4,
com.android.internal.R.color.profile_badge_4,
com.android.internal.R.color.profile_badge_4
};
记住,这个时候不能只是修改这两个地方,否则会报错:
frameworks/base/core/java/android/util/IconDrawableFactory.java:104: error: cannot find symbol
com.android.internal.R.color.profile_badge_4,
^
symbol: variable profile_badge_4
location: class color
还得在
Code/frameworks/base/core/res/res/values/symbols.xml
中添加:
<java-symbol type="color" name="profile_badge_4" />
这样编译时才认识这个 profile_badge_4 是个什么鬼东西。
修改完这三个地方,编译,刷机,验证。发现:
我擦,什么鬼,这是啥情况,为什么没有修改过来。
一定是逻辑没有捋清楚,再重新看一下这个工厂类。
------------------------------------------- 重新查看 -------------------------------------------
后来在这个工厂类 IconDrawableFactory.java 中添加了日志,发现在执行下面程序时,无论是对于Google 原生应用还是 QQ :
public Drawable getBadgedIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo,
@UserIdInt int userId) {
Log.d(TAG, " --- IconDrawableFactory-- 0000000000000000,itemInfo is: " + itemInfo + " ; appInfo is " + appInfo + " ; userId is " + userId );
Drawable icon = mPm.loadUnbadgedItemIcon(itemInfo, appInfo);
Log.d(TAG, " --- IconDrawableFactory-- 11111111111111,icon is: " + icon);
if (!mEmbedShadow && !needsBadging(appInfo, userId)) {
Log.d(TAG, " --- IconDrawableFactory-- 22222222222222,icon is: " + icon);
return icon;
}
icon = getShadowedIcon(icon);
Log.d(TAG, " --- IconDrawableFactory-- 33333333333333,icon is: " + icon);
if (appInfo.isInstantApp()) {
int badgeColor = Resources.getSystem().getColor(
com.android.internal.R.color.instant_app_badge, null);
icon = mLauncherIcons.getBadgedDrawable(icon,
com.android.internal.R.drawable.ic_instant_icon_badge_bolt,
badgeColor);
Log.d(TAG, " --- IconDrawableFactory-- 444444444444444,icon is: " + icon);
}
if (mUm.isManagedProfile(userId)) {
icon = mLauncherIcons.getBadgedDrawable(icon,
com.android.internal.R.drawable.ic_corp_icon_badge_case,
getUserBadgeColor(mUm, userId));
Log.d(TAG, " --- IconDrawableFactory-- 5555555555555555,icon is: " + icon);
}
Log.d(TAG, " --- IconDrawableFactory-- 666666666666666666,icon is: " + icon);
return icon;
}
只打印出了:
--- IconDrawableFactory-- 111111111111111111
--- IconDrawableFactory-- 3333333333333333
--- IconDrawableFactory-- 6666666666666666
现在好像没什么线索了。但是还有一个思路,用拾色器查看这个小点的颜色值,在系统中查找这个色值(后来事实证明,发现截屏之后,截图中 Notification dot 的颜色会发生变化,所以使用拾色器进行颜色定位的方式不可取)。但是,无论是 #2BE8B9 还是 #2CE8B9 都在系统中没找到。。。
那。。这个资源是不是定义到了 Launcher3 的资源文件中了?查看 Launcher3 的colors.xml 文件,果然发现:
<!-- Popup container -->
<color name="notification_icon_default_color">#757575</color> <!-- Gray 600 -->
<color name="badge_color">#1DE9B6</color> <!-- Teal A400 -->
<color name="folder_badge_color">#1DE9B6</color> <!-- Teal A400 -->
这个地方就是我们需要修改的,改为下面:
<!-- Change the default notification badge color from #1DE9B6 to #FC3D30. -->
<color name="badge_color">#FC3D30</color>
<color name="folder_badge_color">#FC3D30</color>
好了,编译Launcher3.apk ,并且编译 rom 进行刷机,安装第三方应用查看效果,前后对比图如下:
至此,成功的完成了在 Android 8.1.0 版本的系统中把默认 Notification Badge color 从蓝绿色改成红色。
另外,稍后补上 IconDrawableFactory.java 中,设置Notification dot 的流程是啥。