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

鸿蒙中 系统语言和区域的获取与监听

本文同步发表于我的微信公众号,微信搜索程语新视界即可关注,每个工作日都有文章更新

系统语言和区域的处理是国际化(i18n)的基础。鸿蒙系统提供了完善的API来获取和监听系统语言、地区、区域的变化。

语言列表与系统语言

在系统的"设置 > 语言和地区"中,用户可以添加多种语言,这些语言按添加顺序形成语言列表

  • 语言列表:用户添加的所有语言的集合

  • 系统语言:语言列表中的第一个语言

例如:用户添加了"中文"、"English"、"日本語",则语言列表为[中文, English, 日本語],系统语言为"中文"。

系统区域

系统区域是依据区域ID划分的特定地区,用于确定日期格式、数字格式、货币符号等本地化规则。

例如:

  • 区域"zh-CN":中国

  • 区域"en-US":美国

  • 区域"ja-JP":日本

扩展参数的自动管理

特性:切换系统语言时,系统会自动检查扩展参数与系统语言是否匹配。

扩展参数:语言相关的特殊设置,如数字系统、日历类型等。

扩展参数自动匹配示例
系统语言扩展参数说明
阿拉伯语(ar)数字系统:arab使用阿拉伯数字
切换到马来西亚语(my)数字系统:mymr自动切换为缅甸数字
切换到中文(zh)移除扩展参数中文默认使用阿拉伯数字

原理

  1. 系统语言设置为阿拉伯语"ar"时,本地数字参数为"arab"

  2. 切换到马来西亚语"my"时,系统自动将数字参数更新为"mymr"

  3. 切换到中文时,因中文不支持设置本地数字,系统自动移除该扩展参数

二、获取系统语言与区域

2.1 导入模块

import { i18n } from '@kit.LocalizationKit'; import { BusinessError, commonEventManager } from '@kit.BasicServicesKit';

2.2 获取系统语言

// 获取当前系统语言 let systemLanguage = i18n.System.getSystemLanguage(); console.info(`当前系统语言: ${systemLanguage}`); // 输出示例:'zh'(中文)、'en'(英文)、'ja'(日文)

2.3 获取系统地区

// 获取当前系统地区 let systemRegion = i18n.System.getSystemRegion(); console.info(`当前系统地区: ${systemRegion}`); // 输出示例:'CN'(中国)、'US'(美国)、'JP'(日本)

2.4 获取系统区域

// 获取当前系统区域对象 let systemLocale: Intl.Locale = i18n.System.getSystemLocaleInstance(); console.info(`当前系统区域: ${systemLocale}`); // 输出示例:'zh-CN'、'en-US'、'ja-JP'

三、监听语言/区域变化

3.1 使用公共事件监听

系统提供了COMMON_EVENT_LOCALE_CHANGED公共事件,当系统语言、系统地区或系统区域发生变化时,会触发该事件。

let subscriber: commonEventManager.CommonEventSubscriber; // 保存订阅者对象 // 1. 定义订阅信息 let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = { events: [commonEventManager.Support.COMMON_EVENT_LOCALE_CHANGED] }; // 2. 创建订阅者 commonEventManager.createSubscriber(subscribeInfo) .then((commonEventSubscriber: commonEventManager.CommonEventSubscriber) => { console.info('创建订阅者成功'); subscriber = commonEventSubscriber; // 3. 订阅事件 commonEventManager.subscribe(subscriber, (err, data) => { if (err) { console.error(`订阅失败, code: ${err.code}, message: ${err.message}`); return; } // 语言/区域变化时执行 console.info('系统语言或区域已变化'); // 可以在这里重新获取最新的语言和区域 let newLanguage = i18n.System.getSystemLanguage(); let newRegion = i18n.System.getSystemRegion(); console.info(`新语言: ${newLanguage}, 新区域: ${newRegion}`); // 更新UI或重新加载资源 this.updateUIForLocale(); }); }) .catch((err: BusinessError) => { console.error(`创建订阅者失败, code: ${err.code}, message: ${err.message}`); });

3.2 监听示例

// LanguagePreferenceSetting.ets import { i18n } from '@kit.LocalizationKit'; import { BusinessError, commonEventManager } from '@kit.BasicServicesKit'; @Entry @Component struct LanguageSetting { @State currentLanguage: string = ''; @State currentRegion: string = ''; private subscriber: commonEventManager.CommonEventSubscriber | null = null; aboutToAppear() { // 获取初始语言和区域 this.currentLanguage = i18n.System.getSystemLanguage(); this.currentRegion = i18n.System.getSystemRegion(); // 监听变化 this.subscribeLocaleChange(); } aboutToDisappear() { // 取消订阅 this.unsubscribeLocaleChange(); } subscribeLocaleChange() { let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = { events: [commonEventManager.Support.COMMON_EVENT_LOCALE_CHANGED] }; commonEventManager.createSubscriber(subscribeInfo) .then((subscriber) => { this.subscriber = subscriber; commonEventManager.subscribe(subscriber, (err, data) => { if (err) { console.error(`订阅失败: ${err.message}`); return; } // 语言变化,更新UI this.currentLanguage = i18n.System.getSystemLanguage(); this.currentRegion = i18n.System.getSystemRegion(); }); }) .catch((err: BusinessError) => { console.error(`创建订阅者失败: ${err.message}`); }); } unsubscribeLocaleChange() { if (this.subscriber) { commonEventManager.unsubscribe(this.subscriber, (err) => { if (err) { console.error(`取消订阅失败: ${err.message}`); } else { console.info('取消订阅成功'); } }); } } updateUIForLocale() { // 根据新语言更新UI // 例如:重新加载资源、刷新文本显示等 } build() { Column() { Text(`当前系统语言: ${this.currentLanguage}`) .fontSize(16) .margin(10) Text(`当前系统地区: ${this.currentRegion}`) .fontSize(16) .margin(10) Text(`当前系统区域: ${this.currentLanguage}-${this.currentRegion}`) .fontSize(16) .margin(10) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) } }

也可以封装一个工具类:

// I18nManager.ets import { i18n } from '@kit.LocalizationKit'; import { BusinessError, commonEventManager } from '@kit.BasicServicesKit'; export class I18nManager { private static instance: I18nManager; private subscriber: commonEventManager.CommonEventSubscriber | null = null; private listeners: Array<(lang: string, region: string) => void> = []; private constructor() { this.initListener(); } static getInstance(): I18nManager { if (!I18nManager.instance) { I18nManager.instance = new I18nManager(); } return I18nManager.instance; } // 获取当前语言 getCurrentLanguage(): string { return i18n.System.getSystemLanguage(); } // 获取当前地区 getCurrentRegion(): string { return i18n.System.getSystemRegion(); } // 获取当前区域 getCurrentLocale(): string { return `${this.getCurrentLanguage()}-${this.getCurrentRegion()}`; } // 初始化监听 private initListener() { let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = { events: [commonEventManager.Support.COMMON_EVENT_LOCALE_CHANGED] }; commonEventManager.createSubscriber(subscribeInfo) .then((subscriber) => { this.subscriber = subscriber; commonEventManager.subscribe(subscriber, (err) => { if (!err) { // 通知所有监听器 this.notifyListeners(); } }); }) .catch((err: BusinessError) => { console.error(`初始化语言监听失败: ${err.message}`); }); } // 添加监听器 addListener(callback: (lang: string, region: string) => void) { this.listeners.push(callback); } // 移除监听器 removeListener(callback: (lang: string, region: string) => void) { const index = this.listeners.indexOf(callback); if (index >= 0) { this.listeners.splice(index, 1); } } private notifyListeners() { const lang = this.getCurrentLanguage(); const region = this.getCurrentRegion(); this.listeners.forEach(callback => { try { callback(lang, region); } catch (error) { console.error('执行监听器失败', error); } }); } // 清理资源 destroy() { if (this.subscriber) { commonEventManager.unsubscribe(this.subscriber, () => {}); this.subscriber = null; } this.listeners = []; } }
http://www.jsqmd.com/news/459304/

相关文章:

  • 计算机毕业设计springboot单亲家庭帮扶管理系统 基于SpringBoot的单身父母家庭综合支持与服务系统 特殊结构家庭社会救助与资源对接数字化平台
  • Pscad仿真-三机九节点系统,储能替换一台同步机,对比是否加入调频策略 三机系统改成50hz
  • Adobe Photoshop
  • SpringBoot3快速集成SMS4J,10分钟搞定短信+OA双渠道消息发送
  • 02计算机组成原理-流水线冒险(上)
  • 06.Python 中数字:整数、浮点数完全指南
  • 新手避坑指南:惯性器件参数表里的‘零偏稳定性‘可能骗了你
  • 电力负荷聚类分析:从数据到典型场景
  • 基于PFC6.0的单轴拉伸实验:二维与三维探索及声发射振铃计数解析
  • 锂电池SOC估算:EKF估计SOC仿真与扩展卡尔曼滤波
  • 基于YOLOv8的钢材表面缺陷检测系统【附源码+可远程安装部署】
  • VC维与PAC学习:如何量化你的模型复杂度?
  • 用广义神经网络GRNN实现多特征输入单因变量输出的拟合预测
  • 【小龙虾】OpenClaw 3.8继续炸场!龙虾不睡觉,全球程序员连夜赶工
  • 基于MotorCAD的永磁电机退磁仿真及电流波形自定义探索
  • 车载以太网TC8测试实战:SOME/IP协议在SOA架构下的完整测试流程(含Vector工具链配置)
  • OEE提升15%的机械加工厂的数字化
  • RTKLIB实战:5分钟搞定标准单点定位(SPP)完整流程(附避坑指南)
  • 基于YOLOv8的花卉识别系统【附源码+可远程安装部署】
  • SecureCRT新手必看:10个高效命令让你远程操作飞起(附常用快捷键)
  • FastestDet:超越业界轻量级目标检测算法的五大特性
  • winform PictureBox 显示大图片带垂直滚动条
  • iReport 5.6.0实战:手把手教你用List组件搞定学生名单报表(附避坑指南)
  • 氚云 vs 宜搭:表单控件全对比,哪个更适合你的业务场景?
  • 基于RK3588J的AI检测设备实战解析
  • 为什么你的Ubuntu实时内核编译失败了?PREEMPT_RT补丁常见问题解析
  • 用Anki高效啃透华工通信原理:自制考点卡片模板分享(含HDB3编码/匹配滤波器真题)
  • 提示工程架构师实战:Agentic AI生态影响研究的样本选择策略
  • mfc140u.dll丢失的解决方法-mfc140u.dll文件下载
  • 【Python环境安装及配置】