前言:Android O中墨西哥的订单反馈切换成西班牙语 之后,设置-声音-“勿扰”偏好设置中的自动规则对应的字符串显示英文。
Go to Do not disturb option
- More settings
- Auomatic Rules
- Weekend change to Fin de semana
Weeknight change to Semana nocturna
Event change to Evento
- Weekend change to Fin de semana
- Auomatic Rules
在西班牙的环境之下重新编译了systemimage,开机验证,居然已经翻译正确(已经确定了这个界面读取的字符串id)。但是,当再次切换成其他的语言依然显示的是西班牙语,给人一种感觉就是它不会随着系统切换语言而改变。经过再三实验,发现这个bug是:不论设置成什么语言,它需要关机/重启之后才会生效!
“find -name "*.java" | xargs grep --color "zen_mode_default_events_name" 查找到它读取资源id的java类在ZenModeHelper.java中(path: frameworks/base/core/java/android/service/notification/ZenModeConfig.java)
public ZenMoHelper(Context context, Looper looper, ConditionProviders conditionProviders) {
Log,d("swx","构造函数调用的次数:"+ x++);
mDefaultConfig = new ZenModeConfig();
mDefaultRuleWeeknightsName = mContext.getResources()
.getString(R.string.zen_mode_default_weeknights_name);
mDefaultRuleWeekendsName = mContext.getResources()
.getString(R.string.zen_mode_default_weekends_name);
mDefaultRuleEventsName = mContext.getResources()
.getString(R.string.zen_mode_default_events_name);
}
从上面的源码中可以看出来,它是在构造函数中加载资源的。然而,ZenMoHelper.java是在NotificationManagerService( extends SystemService)中初始化的。也就是关机/重启系统的服务启动之后,它初始化ZenMoHelper.java时只会调用一次构造函数,所以,也就是上述三个字符串只能显示的语言是第一次开机时的系统语言。(参考自这篇文章:https://blog.csdn.net/ranger0220/article/details/51479488)
解决方案:将 ZenMoHelper.java类中的
protected String mDefaultRuleWeeknightsName;
protected String mDefaultRuleEventsName;
protected String mDefaultRuleWeekendsName;
例如:
mDefaultRuleWeeknightsName = mContext.getResources().getString(R.string.zen_mode_default_weeknights_name);
rule1.name = mDefaultRuleWeeknightsName; 把原先的mDefaultRuleWeeknightsName定义在构造函数的代码去掉,把它放在对应的方法中实现就好。虽然实例对象不变化,但是下面获取资源的方法的时候,它都还是会去重新加载资源文件。(即改成:将rule1.name = mContext.getResources().getString(R.string.zen_mode_default_weeknights_name);去掉mDefaultRuleWeeknightsName在构造函数中的声明)
完美解决了勿扰模式中无法切换语言的BUG!