最近做android9.0系统相关的定制工作,用户反馈时间设置中的自动使用24小时制没效果,亲自试了下确实时间显示的格式没变,于是一脸蒙逼。网上查了有人问相同的问题,不过也没有确切的答案,可能是android9.0刚刚出来没多久,国内使用的还不多的原因吧。于是找到了相关的源码如下:
控制的相关类主要是在AutoTimeFormatPreferenceController.java和TimeFormatPreferenceController.java中:
AutoTimeFormatPreferenceController.java
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!(preference instanceof TwoStatePreference)
|| !TextUtils.equals(KEY_AUTO_24_HOUR, preference.getKey())) {
return false;
}
boolean auto24HourEnabled = ((SwitchPreference) preference).isChecked();
Boolean is24Hour;
if (auto24HourEnabled) {
is24Hour = null;
} else {
is24Hour = is24HourLocale(mContext.getResources().getConfiguration().locale);
}
TimeFormatPreferenceController.update24HourFormat(mContext, is24Hour);
return true;
}
boolean is24HourLocale(Locale locale) {
return DateFormat.is24HourLocale(locale);
}
TimeFormatPreferenceController.java
static void update24HourFormat(Context context, Boolean is24Hour) {
set24Hour(context, is24Hour);
timeUpdated(context, is24Hour);
}
static void timeUpdated(Context context, Boolean is24Hour) {
Intent timeChanged = new Intent(Intent.ACTION_TIME_CHANGED);
timeChanged.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
int timeFormatPreference;
if (is24Hour == null) {
timeFormatPreference = Intent.EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT;
} else {
timeFormatPreference = is24Hour ? Intent.EXTRA_TIME_PREF_VALUE_USE_24_HOUR
: Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR;
}
timeChanged.putExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, timeFormatPreference);
context.sendBroadcast(timeChanged);
}
static void set24Hour(Context context, Boolean is24Hour) {
String value = is24Hour == null ? null :
is24Hour ? HOURS_24 : HOURS_12;
Settings.System.putString(context.getContentResolver(),
Settings.System.TIME_12_24, value);
}
从代码中很容易看到 当auto24HourEnabled 为 TRUE时,is24Hour = null,因此timeUpdated(…)时,timeFormatPreference = Intent.EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT; set4Hour(…)这时保存了一个null,紧接着查找EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT,只有一点点让人模棱两可的注释
/**
* Optional int extra for {@link #ACTION_TIME_CHANGED} that indicates the
* user has set their time format preference. See {@link #EXTRA_TIME_PREF_VALUE_USE_12_HOUR},
* {@link #EXTRA_TIME_PREF_VALUE_USE_24_HOUR} and
* {@link #EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT}. The value must not be negative.
*
* @hide for internal use only.
*/
public static final String EXTRA_TIME_PREF_24_HOUR_FORMAT =
"android.intent.extra.TIME_PREF_24_HOUR_FORMAT";
/** @hide */
public static final int EXTRA_TIME_PREF_VALUE_USE_12_HOUR = 0;
/** @hide */
public static final int EXTRA_TIME_PREF_VALUE_USE_24_HOUR = 1;
/** @hide */
public static final int EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT = 2;
至此,只能看出这个值是算作用户设置的,大概是跟用户设置的语言有关系的,跟着用户设置的语言变化的,于是试了下切换语言(当时试了美国,English(United States),发现竟然都没什么变化,感觉不死心,又随机点了几个语言,发现依然没有变化,于是猜想归于猜想。
今天看官网,看到android7.0以后添加了一个多语言区域支持的功能,
Android 7.0 现在允许用户在设置中选择多个语言区域,以更好地支持双语用例。应用可以使用新的 API 获取用户选择的语言区域,然后为多区域设置用户提供更成熟的用户体验 — 如以多个语言显示搜索结果,并且不会以用户了解的语言翻译网页。
除多语言区域支持外,Android 7.0 还扩展了用户可用的语言范围。它针对常用语言提供超过 25 种的变体,如英语、西班牙语、法语和阿拉伯语。它还针对 100 多种新语言添加了部分支持。
应用可以通过调用 LocaleList.GetDefault() 获取用户设置的语言区域列表。为支持扩展的语言区域数量,Android 7.0 正在改变其解析资源的方式。请务必使用新的资源解析逻辑测试和验证您的应用是否能如期运行。
要了解新资源解析行为和应遵循的最佳做法,请参阅多语言支持。
于是联想到用户默认语言设置,于是拿手机试了下,操作是这样的,进入语言设置偏好,添加了
English(United Kingdom),添加简体中文(中国),把 United Kingdom,拖拽到第一个,也即设置为默认的语言,如果你事先把事件调节到下午,或者正好是下午,你就可以发现,当该开关打开时,当切换United Kingdom 为默认语言,显示24小时进制;当该开关关闭,一样的切换是没效果的。于是之前的猜想得到验证。