You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android语言文件(Locale)在真实设备及App Bundle中不生效问题

多语言切换问题排查与解决方案

问题背景

  • 已创建多份语言资源文件(如strings-de.xml、strings-en.xml、strings-hy.xml等)
  • 使用以下Kotlin代码尝试切换Locale加载对应语言内容:
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setAppLocale("hy")
        val actionBar: androidx.appcompat.app.ActionBar? = supportActionBar
        actionBar?.hide()
        setContentView(R.layout.activity_main)
        .....
    }
    
    fun Context.setAppLocale(language: String): Context {
        val locale = Locale(language)
        Locale.setDefault(locale)
        val config = resources.configuration
        config.setLocale(locale)
        config.setLayoutDirection(locale)
        return createConfigurationContext(config)
    }
    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(ContextWrapper(newBase.setAppLocale("hy")))
    }
}

依赖配置

implementation 'androidx.appcompat:appcompat:1.4.0'

问题现象

  • 模拟器上可正常加载目标语言文件(如strings-hy.xml)内容
  • 真实设备上无法加载对应语言文件,但检测显示Locale已切换
  • 更换多种语言切换代码后问题仍存在
  • 后续排查确认:仅Google Play分发的Android App Bundle包中代码不生效

需求更新

  • 求可正常生效的Java/Kotlin语言切换代码

解决方案

核心原因

Google Play App Bundle默认开启按需语言功能,只会下载用户系统语言对应的资源包。当应用内切换到非系统语言时,对应语言的资源未被下载,因此无法加载。

解决步骤

1. 禁用按需语言下载(适合需全语言支持的应用)

在app/build.gradle(或build.gradle.kts)中添加配置,强制打包所有语言资源:

android {
    bundle {
        language {
            // 禁用按需语言拆分,打包所有语言资源
            enableSplit = false
        }
    }
}

注意:此方法会增大安装包体积,适合语言资源占比较小的应用。

2. 动态下载缺失语言资源(推荐,兼顾包体积与多语言支持)

使用Play Core Library的动态交付功能,在用户切换语言时下载对应资源包:

  • 先添加Play Core依赖:
    implementation 'com.google.android.play:core:1.10.3'
    
  • 实现语言资源下载逻辑:
    private fun downloadLanguage(languageCode: String) {
        val splitInstallManager = SplitInstallManagerFactory.create(this)
        val request = SplitInstallRequest.newBuilder()
            .addLanguage(Locale.forLanguageTag(languageCode))
            .build()
    
        splitInstallManager.startInstall(request)
            .addOnSuccessListener {
                // 下载成功后重启Activity加载新语言
                recreate()
            }
            .addOnFailureListener { exception ->
                // 处理下载失败逻辑,如提示用户重试
            }
    }
    

3. 修正语言切换代码(确保配置生效)

优化原有逻辑,兼容不同Android版本,确保Locale配置正确应用:

Kotlin版本
import android.content.Context
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import java.util.Locale

class MainActivity : AppCompatActivity() {
    override fun attachBaseContext(newBase: Context) {
        val selectedLanguage = "hy" // 替换为用户保存的语言选择
        super.attachBaseContext(updateLocale(newBase, selectedLanguage))
    }

    private fun updateLocale(context: Context, languageCode: String): Context {
        val locale = Locale(languageCode)
        Locale.setDefault(locale)

        val resources = context.resources
        val configuration = Configuration(resources.configuration)
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            configuration.setLocale(locale)
            configuration.setLayoutDirection(locale)
            return context.createConfigurationContext(configuration)
        } else {
            configuration.locale = locale
            resources.updateConfiguration(configuration, resources.displayMetrics)
            return context
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        supportActionBar?.hide()
        setContentView(R.layout.activity_main)
        // 其他初始化逻辑
    }
}
Java版本
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void attachBaseContext(Context newBase) {
        String selectedLanguage = "hy"; // 替换为用户保存的语言选择
        super.attachBaseContext(updateLocale(newBase, selectedLanguage));
    }

    private Context updateLocale(Context context, String languageCode) {
        Locale locale = new Locale(languageCode);
        Locale.setDefault(locale);

        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            configuration.setLocale(locale);
            configuration.setLayoutDirection(locale);
            return context.createConfigurationContext(configuration);
        } else {
            configuration.locale = locale;
            resources.updateConfiguration(configuration, resources.getDisplayMetrics());
            return context;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.hide();
        }
        setContentView(R.layout.activity_main);
        // 其他初始化逻辑
    }
}

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 11:01:00