Android 12应用内无法通过代码修改Locale/语言问题咨询
Android 12 应用内切换语言失效问题解决方案
首先明确:Android 12 没有废弃 Locale 或相关支持API,你的代码失效是因为系统新增了应用专属语言配置规则,原有逻辑没有适配新的系统限制。
失效核心原因
- Android 12 开始系统新增了应用级语言设置入口(系统设置-应用-对应应用-语言),系统会优先读取该位置的配置,旧版仅修改 Context 配置的逻辑会被系统默认配置覆盖
- 原有代码仅处理了
attachBaseContext阶段的配置注入,缺少 Android 7+ 要求的多语言列表同步配置,也没有适配配置变更时的持久化逻辑
修复步骤
1. 新增应用语言配置声明
在 AndroidManifest.xml 中添加权限和语言配置声明,告知系统应用支持自主切换语言:
<!-- 配置修改权限 --> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> <application ... <!-- 声明应用支持的语言列表 --> android:localeConfig="@xml/locale_config"> </application>
在 res/xml 目录下创建 locale_config.xml,列出所有应用支持的语言:
<?xml version="1.0" encoding="utf-8"?> <locale-config xmlns:android="http://schemas.android.com/apk/res/android"> <locale android:name="de"/> <locale android:name="zh"/> <locale android:name="en"/> <!-- 按需补充其他支持的语言代码 --> </locale-config>
2. 更新Locale配置逻辑
补全多语言列表配置,新增Android 13及以上的LocaleManager适配:
override fun attachBaseContext(base: Context) { super.attachBaseContext(updateBaseContextLocale(base)) } open fun updateBaseContextLocale(context: Context): Context { // 此处替换为你持久化存储的用户选择的语言代码 val languageCode = "de" val locale = Locale(languageCode) Locale.setDefault(locale) return when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> { // Android 13+ 用系统提供的LocaleManager设置应用语言 val localeManager = context.getSystemService(LocaleManager::class.java) localeManager.applicationLocales = LocaleList(locale) context.createConfigurationContext(context.resources.configuration.apply { setLocale(locale) setLocales(LocaleList(locale)) }) } Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> { updateResourcesLocale(context, locale) } else -> { updateResourcesLocaleLegacy(context, locale) } } } @TargetApi(Build.VERSION_CODES.N) open fun updateResourcesLocale(context: Context, locale: Locale): Context { val configuration: Configuration = context.resources.configuration configuration.setLocale(locale) // 补全多语言列表配置,Android 7+会优先读取该配置 configuration.setLocales(LocaleList(locale)) return context.createConfigurationContext(configuration) } open fun updateResourcesLocaleLegacy(context: Context, locale: Locale): Context { val resources: Resources = context.resources val configuration: Configuration = resources.getConfiguration() configuration.locale = locale resources.updateConfiguration(configuration, resources.getDisplayMetrics()) return context }
3. 补充全局配置变更监听
在自定义Application类中重写onConfigurationChanged,避免系统配置变更(如屏幕旋转、系统语言修改)覆盖应用内设置的语言:
override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) updateBaseContextLocale(this) }
4. 切换语言后触发页面更新
用户在应用内切换语言后,调用当前Activity的recreate()方法重建页面,或者重启应用 activity 栈,确保所有页面资源都更新为对应语言。
内容的提问来源于stack exchange,提问作者Aman Masipeddi
相关产品推荐
相关产品推荐

