是否有可能在使用Android资源的同时以编程方式改变应用程序的语言?

如果不是,是否可以用特定的语言请求资源?

我想让用户改变应用程序的语言从应用程序。


当前回答

对每应用语言偏好的支持刚刚添加到API 33 (Android 13,提拉米苏目前在开发者预览版)。

要改变应用程序的语言环境,只需从LocaleManager调用setApplicationLocales:

// Set app locale to pt-BR (Portuguese, Brazil)
getSystemService(LocaleManager::class.java)
    .applicationLocales = LocaleList(Locale.forLanguageTag("pt-BR"))

详见https://developer.android.com/about/versions/13/features/app-languages#api-impl

我已经写了一篇关于这个功能的文章https://proandroiddev.com/exploring-the-new-android-13-per-app-language-preferences-8d99b971b578

其他回答

只是多添了一块,把我绊倒了。

而其他的答案,比如“de”,都没问题

String lang = "de";
Locale locale = new Locale(lang); 
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, 
    getBaseContext().getResources().getDisplayMetrics());

上面不会工作,例如“fr_BE”地区,所以它将使用values-fr-rBE文件夹或类似的。

需要以下轻微更改工作与“fr_BE”

String lang = "fr";

//create a string for country
String country = "BE";
//use constructor with country
Locale locale = new Locale(lang, country);

Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, 
    getBaseContext().getResources().getDisplayMetrics());

对每应用语言偏好的支持刚刚添加到API 33 (Android 13,提拉米苏目前在开发者预览版)。

要改变应用程序的语言环境,只需从LocaleManager调用setApplicationLocales:

// Set app locale to pt-BR (Portuguese, Brazil)
getSystemService(LocaleManager::class.java)
    .applicationLocales = LocaleList(Locale.forLanguageTag("pt-BR"))

详见https://developer.android.com/about/versions/13/features/app-languages#api-impl

我已经写了一篇关于这个功能的文章https://proandroiddev.com/exploring-the-new-android-13-per-app-language-preferences-8d99b971b578

这段代码真的可以工作:

fa = 波斯语,en = 英语

注意:语言代码不能有“-”,必须是2个小写字母

在languageToLoad变量中输入您的语言代码:

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;

public class Main extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String languageToLoad  = "fa"; // your language
    Locale locale = new Locale(languageToLoad); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    getBaseContext().getResources().updateConfiguration(config, 
      getBaseContext().getResources().getDisplayMetrics());
    this.setContentView(R.layout.main);
  }
}

2021年6月更新(Kotlin):

class Main : Activity() {
    // Called when the activity is first created.
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        val config = resources.configuration
        val lang = "fa" // your language code
        val locale = Locale(lang)
        Locale.setDefault(locale)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
            config.setLocale(locale)
        else
            config.locale = locale

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
            createConfigurationContext(config)
        resources.updateConfiguration(config, resources.displayMetrics)

        this.setContentView(R.layout.main)
    }
}

根据这篇文章。您需要下载那篇文章中引用的LocaleHelper.java。

Create MyApplication class that will extends Application Override attachBaseContext() to update language. Register this class in manifest. public class MyApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(LocaleHelper.onAttach(base, "en")); } } <application android:name="com.package.MyApplication" .../> Create BaseActivity and override onAttach() to update language. Needed for Android 6+ public class BaseActivity extends Activity { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(LocaleHelper.onAttach(base)); } } Make all activities on your app extends from BaseActivity. public class LocaleHelper { private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language"; public static Context onAttach(Context context) { String lang = getPersistedData(context, Locale.getDefault().getLanguage()); return setLocale(context, lang); } public static Context onAttach(Context context, String defaultLanguage) { String lang = getPersistedData(context, defaultLanguage); return setLocale(context, lang); } public static String getLanguage(Context context) { return getPersistedData(context, Locale.getDefault().getLanguage()); } public static Context setLocale(Context context, String language) { persist(context, language); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { return updateResources(context, language); } return updateResourcesLegacy(context, language); } private static String getPersistedData(Context context, String defaultLanguage) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); return preferences.getString(SELECTED_LANGUAGE, defaultLanguage); } private static void persist(Context context, String language) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor editor = preferences.edit(); editor.putString(SELECTED_LANGUAGE, language); editor.apply(); } @TargetApi(Build.VERSION_CODES.N) private static Context updateResources(Context context, String language) { Locale locale = new Locale(language); Locale.setDefault(locale); Configuration configuration = context.getResources().getConfiguration(); configuration.setLocale(locale); configuration.setLayoutDirection(locale); return context.createConfigurationContext(configuration); } @SuppressWarnings("deprecation") private static Context updateResourcesLegacy(Context context, String language) { Locale locale = new Locale(language); Locale.setDefault(locale); Resources resources = context.getResources(); Configuration configuration = resources.getConfiguration(); configuration.locale = locale; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { configuration.setLayoutDirection(locale); } resources.updateConfiguration(configuration, resources.getDisplayMetrics()); return context; } }

我正在寻找一种以编程方式改变系统语言的方法。 虽然我完全理解一个正常的应用程序不应该这样做,而是:

用户应该(通过一个意图)指向系统设置手动更改它 应用程序应该自己处理本地化,就像Alex的回答中描述的那样

有必要从程序上真正改变系统的语言。

这是没有文档的API,因此不应该用于市场/最终用户应用程序!

不管怎样,这是我找到的解决方案:

  Locale locale = new Locale(targetLocaleAsString);

  Class amnClass = Class.forName("android.app.ActivityManagerNative");
  Object amn = null;
  Configuration config = null;

  // amn = ActivityManagerNative.getDefault();
  Method methodGetDefault = amnClass.getMethod("getDefault");
  methodGetDefault.setAccessible(true);
  amn = methodGetDefault.invoke(amnClass);

  // config = amn.getConfiguration();
  Method methodGetConfiguration = amnClass.getMethod("getConfiguration");
  methodGetConfiguration.setAccessible(true);
  config = (Configuration) methodGetConfiguration.invoke(amn);

  // config.userSetLocale = true;
  Class configClass = config.getClass();
  Field f = configClass.getField("userSetLocale");
  f.setBoolean(config, true);

  // set the locale to the new value
  config.locale = locale;

  // amn.updateConfiguration(config);
  Method methodUpdateConfiguration = amnClass.getMethod("updateConfiguration", Configuration.class);
  methodUpdateConfiguration.setAccessible(true);
  methodUpdateConfiguration.invoke(amn, config);