You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android平台platform.device.language切换系统语言后返回值异常

解决Android应用切换系统语言后platform.device.language不更新的问题

我之前也碰到过一模一样的坑!当App启动时系统设为西班牙语,platform.device.language能正常返回正确的ISO编码,但把App切到后台换了德语再切回来,这个接口居然还是返回西班牙语,非得完全重启App才能拿到正确的语言值。

问题根源

这其实是因为应用启动时会缓存初始的系统语言配置,而platform.device.language这类封装的API大概率是直接读取了这个缓存值,不会主动监听系统语言的变化并更新缓存。Android系统默认不会自动通知应用更新语言配置,除非我们主动去监听或者重新获取最新的系统配置。

可行的解决办法

  • 监听系统语言变化广播
    在你的Activity或者Application类里注册Intent.ACTION_LOCALE_CHANGED广播接收器,一旦收到系统语言变化的通知,就主动重新获取最新的语言编码,替换掉之前缓存的旧值。示例代码(Kotlin):

    private val localeChangeReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent?.action == Intent.ACTION_LOCALE_CHANGED) {
                // 获取实时的系统语言编码
                val currentLang = Resources.getSystem().configuration.locales[0].language
                // 这里更新你用来存储语言值的变量,后续就用这个新值
            }
        }
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 注册广播接收器
        registerReceiver(localeChangeReceiver, IntentFilter(Intent.ACTION_LOCALE_CHANGED))
    }
    
    override fun onDestroy() {
        super.onDestroy()
        // 记得取消注册,避免内存泄漏
        unregisterReceiver(localeChangeReceiver)
    }
    
  • 直接读取系统最新配置,绕过缓存
    别再依赖封装好的platform.device.language了,直接从系统的Resources或Configuration里实时获取语言信息,每次调用都会拿到最新的设置:

    // Java 写法
    String currentLang = Resources.getSystem().getConfiguration().getLocales().get(0).getLanguage();
    
    // Kotlin 写法
    val currentLang = Resources.getSystem().configuration.locales[0].language
    
  • 必要时重启Activity刷新界面
    如果你的App界面需要跟着语言变化实时更新,在收到语言变化广播后,可以重启当前Activity(或者主Activity),确保所有界面元素都用上最新的语言配置:

    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action == Intent.ACTION_LOCALE_CHANGED) {
            val restartIntent = Intent(context, MainActivity::class.java)
            restartIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
            context?.startActivity(restartIntent)
        }
    }
    

补充说明

如果你的项目是基于跨平台框架(比如Cordova、React Native,毕竟用到了platform.device.language这类跨平台API),那大概率是框架层面的API没有处理语言变化的逻辑。这时候要么通过原生插件实现实时获取语言的功能,要么在框架层监听原生的语言变化事件,手动更新框架内的语言缓存。

内容的提问来源于stack exchange,提问作者Stavros_S

火山引擎 最新活动