当前位置: 首页 > news >正文

android开发 更改系统默认时区和默认语言

android开发 更改系统默认时区和默认语言

frameworks\base\services\java\com\android\server#run()

// Set the device's time zone (a system property) if it is not set or is invalid.SystemTimeZone.initializeTimeZoneSettingsIfRequired();/*If the system has "persist.sys.language" and friends set, replace them with "persist.sys.locale". Note that the default locale at this point is calculated using the "-Duser.locale" command line flag. That flag is usually populated by AndroidRuntime using the same set of system properties, but only the system_server and system apps are allowed to set them.NOTE: Most changes made here will need an equivalent change to core/jni/AndroidRuntime.cpp*/
// Set the device's time zone (a system property) if it is not set or is invalid.
if(!SystemProperties.get("persist.sys.language").isEmpty()){final String languageTag=Locale.getDefault().toLanguageTag();SystemProperties.set("persist.sys.locale",languageTag);SystemProperties.set("persist.sys.language","");SystemProperties.set("persist.sys.country","");SystemProperties.set("persist.sys.localevar","");}

1. 时区初始化

SystemTimeZone.initializeTimeZoneSettingsIfRequired();
  • 目的:确保设备时区正确设置。
  • 逻辑
    • 检查系统属性中的时区设置(如persist.sys.timezone)。
    • 如果未设置或无效(如时区文件不存在),则根据默认规则(如从网络或GPS获取)初始化时区。
    • 典型场景:新设备首次启动、时区文件被误删或损坏时触发初始化。
  • 重要性:时区影响系统时间、日志时间戳、定时任务等核心功能。

2. 语言设置迁移

if (!SystemProperties.get("persist.sys.language").isEmpty()) {final String languageTag = Locale.getDefault().toLanguageTag();SystemProperties.set("persist.sys.locale", languageTag);SystemProperties.set("persist.sys.language", "");SystemProperties.set("persist.sys.country", "");SystemProperties.set("persist.sys.localevar", "");
}
背景

旧版Android使用分散属性存储区域设置:

  • persist.sys.language:语言代码(如en
  • persist.sys.country:国家代码(如US
  • persist.sys.localevar:区域变体(如POSIX

新版改为单一标准属性
persist.sys.locale(格式为BCP 47语言标签,如en-US)。

迁移逻辑
  1. 条件检测
    !SystemProperties.get("persist.sys.language").isEmpty()
    检查旧属性是否被设置过(非空值表示设备是从旧版本升级或残留旧配置)。

  2. 生成新语言标签
    Locale.getDefault().toLanguageTag()

    • 获取当前默认区域设置(由-Duser.locale命令行参数初始化,通常来自ro.product.locale等只读属性)。
    • 转换为标准格式(如zh-CN)。
  3. 更新系统属性

    SystemProperties.set("persist.sys.locale", languageTag); // 设置新属性
    SystemProperties.set("persist.sys.language", "");        // 清空旧属性
    SystemProperties.set("persist.sys.country", "");
    SystemProperties.set("persist.sys.localevar", "");
    
    • 迁移完成:后续系统将只依赖persist.sys.locale
    • 清空旧属性:避免下次启动再次迁移。

3.关键设计分析

为什么需要迁移?
  • 统一标准:BCP 47语言标签(如de-AT)比分散属性更规范,支持复杂区域(方言、脚本)。
  • 简化逻辑:应用只需读取单个属性persist.sys.locale,无需拼接多个值。
  • 兼容性:确保旧设备升级后无缝过渡到新格式。
区域设置的初始化来源
  • 默认区域由-Duser.locale参数决定,该参数在Android启动阶段(如AndroidRuntime.cpp)通过以下优先级生成:
    1. 已存在的persist.sys.locale
    2. 旧属性组合(persist.sys.language + persist.sys.country
    3. 设备出厂设置(ro.product.locale等)
  • 关键约束:只有system_server和系统应用有权修改这些属性。
同步需求
  • 注释强调需同步修改core/jni/AndroidRuntime.cpp
    • 因Android启动过程涉及Java层与Native层(Zygote初始化)。
    • 必须确保两端的区域设置逻辑一致,否则可能导致区域不一致的BUG。
初始化读取系统属性流程图:

在这里插入图片描述

4.用户手动更改了系统默认语言,系统属性值不一致未跟随变化

核心原因:区域设置服务(LocaleService)覆盖了系统属性

Android系统的实际区域由 LocaleService 管理(位于system_server进程),而非直接读取系统属性。其工作流程如下:
在这里插入图片描述

具体解释:

启动阶段的优先级应用
  • 系统启动时确实按优先级读取persist.sys.locale=en-US
  • 初始设置Locale.getDefault()为英语(美国)
区域设置服务的介入
  • 系统服务完全启动后,LocaleService开始工作
  • 该服务会检查用户显式设置过的区域
  • 如果检测到用户曾经手动更改过语言(即使后来属性被修改),会覆盖系统属性
关键存储位置
  • 用户真实的区域设置存储在:

    /data/system/users/<user_id>/settings_system.xml

  • 包含:

    <setting id="0" name="system_locales" value="zh-CN" />

属性与服务的同步问题
  • 当用户通过设置应用更改语言时:
// 在LocaleService中
public void setSystemLocales(List<Locale> locales) {// 1. 更新内存状态mSystemLocales = locales; // 2. 写入用户配置文件(非系统属性)Settings.System.putStringForUser(..., "zh-CN", userId);// 3. 异步更新persist.sys.locale(可能延迟或失败)
}
  • 如果第三步更新persist.sys.locale失败(如系统崩溃),就会出现属性与服务状态不一致

解决方案

要恢复一致状态,需同步更新服务和属性:

# 1. 更新LocaleService状态
adb shell settings put system system_locales en-USadb shell settings get system system_locales# 2. 更新系统属性
adb shell setprop persist.sys.locale en-US
adb shell getprop persist.sys.locale
# 3. 重启
adb shell reboot

注意:在Android 13+中,直接修改settings_system.xml需要WRITE_SETTINGS权限

5.总结

在这里插入图片描述

出现不一致是因为:

  1. 用户层设置(settings_system.xml) 优先级最高
  2. LocaleService的内存状态 是系统实际使用的值
  3. 系统属性(persist.sys.locale) 只是初始化输入源之一

这种设计确保了即使用户在设备使用过程中修改语言设置,系统也能快速响应,而无需每次读写系统属性。

http://www.xdnf.cn/news/1245151.html

相关文章:

  • 笔试——Day29
  • C语言线程同步详解(互斥锁、信号量、条件变量和读写锁)
  • 【web应用】前后端分离项目基本框架组成:Vue + Spring Boot 最佳实践指南
  • 《C++初阶之STL》【模板参数 + 模板特化 + 分离编译】
  • tc 介绍
  • RHCA04--系统模块管理与资源限制
  • 26-数据仓库与Apache Hive
  • Dubbo-Go调Bug记录-泛化调用调不通
  • uniapp基础(五)调试与错误
  • Python 基础语法(二):流程控制语句详解
  • HPE磁盘阵列管理01——MSA和SMU
  • 「PromptPilot 大模型智能提示词平台」—— PromptPilot × 豆包大模型 1.6:客户投诉邮件高效回复智能提示词解决方案
  • Vlog音效大升级!用Audition环境音效打造沉浸式体验
  • 【C++】Stack and Queue and Functor
  • 【原创】基于gemini-2.5-flash-preview-05-20多模态模型实现短视频的自动化二创
  • 将普通用户添加到 Docker 用户组
  • promise类方法
  • 阿里云百炼平台创建智能体-上传文档
  • Java学习第一百零六部分——Lucene
  • 2.4 组件通信
  • deepseek、GPT与claude在MATLAB编程上的准确性对比——以卡尔曼滤波调试为例
  • 大模型之后,机器人正在等待它的“GPT-1 时刻”
  • 本机部署K8S集群
  • 力扣:2246. 相邻字符不同的最长路径
  • ESP-idf框架下的HTTP服务器\HTML 485温湿度采集并长传
  • 14.Home-新鲜好物和人气推荐实现
  • 编程算法:技术创新与业务增长的核心引擎
  • Linux操作系统从入门到实战(十三)版本控制器Git基础概念讲解
  • 深入浅出 RabbitMQ-路由模式详解
  • 自由学习记录(77)