在Android中以编程方式更改语言

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

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

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

这是可能的。 您可以设置区域设置。 不过,我不会推荐的。 我们已经在早期阶段尝试过,基本上是和系统打交道。

我们对改变语言有相同的要求,但决定解决这个事实,即UI应该与电话UI相同。 这是通过设置区域设置工作,但太多了。 每次你从我的经验中进入活动(每个活动),你必须设置它。 这里是一个代码,如果你仍然需要这个(再次,我不build议)

Resources res = context.getResources(); // Change locale settings in the app. DisplayMetrics dm = res.getDisplayMetrics(); android.content.res.Configuration conf = res.getConfiguration(); conf.setLocale(new Locale(language_code.toLowerCase())); // API 17+ only. // Use conf.locale = new Locale(...) if targeting lower versions res.updateConfiguration(conf, dm); 

如果您有语言特定的内容 – 您可以更改该设置的基础。

这真的很有用… fa = Persian … en = English …
在languageToLoad中input您的语言代码:

 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); } } 

你可以在这里find一个例子

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

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

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

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

无论如何,inheritance人的解决scheme,我发现:

  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); 

如果你想要修改所有你的应用程序的语言,你必须做两件事情。

首先,创build一个基本的活动,并使所有的活动延伸:

 public class BaseActivity extends AppCompatActivity { private Locale mCurrentLocale; @Override protected void onStart() { super.onStart(); mCurrentLocale = getResources().getConfiguration().locale; } @Override protected void onRestart() { super.onRestart(); Locale locale = getLocale(this); if (!locale.equals(mCurrentLocale)) { mCurrentLocale = locale; recreate(); } } public static Locale getLocale(Context context){ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); String lang = sharedPreferences.getString("language", "en"); switch (lang) { case "English": lang = "en"; break; case "Spanish": lang = "es"; break; } return new Locale(lang); } } 

请注意,我将这个新语言保存在一个sharedPreference中。

其次,像这样创build应用程序的扩展:

  public class App extends Application { @Override public void onCreate() { super.onCreate(); setLocale(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); setLocale(); } private void setLocale() { final Resources resources = getResources(); final Configuration configuration = resources.getConfiguration(); final Locale locale = getLocale(this); if (!configuration.locale.equals(locale)) { configuration.setLocale(locale); resources.updateConfiguration(configuration, null); } } } 

请注意,getLocale()与上面的一样。

就这样! 我希望这可以帮助别人。

我改变德语为我的应用程序启动本身。

这是我的正确的代码。 任何人都想使用这个相同的我..(如何更改语言在android编程)

我的代码:

 Configuration config ; // variable declaration in globally // this part is given inside onCreate Method starting and before setContentView() public void onCreate(Bundle icic) { super.onCreate(icic); config = new Configuration(getResources().getConfiguration()); config.locale = Locale.GERMAN ; getResources().updateConfiguration(config,getResources().getDisplayMetrics()); setContentView(R.layout.newdesign); } 

只是增加一个绊倒我的额外的一块。

而其他答案正常工作与“德”例如

 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()); 

我知道这是回答迟了,但我在这里find这篇文章 。 这就解释了整个过程,并为您提供了一个结构良好的代码。

语言环境助手类:

 import android.annotation.TargetApi; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Configuration; import android.content.res.Resources; import android.os.Build; import android.preference.PreferenceManager; import java.util.Locale; /** * This class is used to change your application locale and persist this change for the next time * that your app is going to be used. * <p/> * You can also change the locale of your application on the fly by using the setLocale method. * <p/> * Created by gunhansancar on 07/10/15. */ 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; } } 

您需要重写attachBaseContext并调用LocaleHelper.onAttach()来初始化应用程序中的区域设置。

 import android.app.Application; import android.content.Context; import com.gunhansancar.changelanguageexample.helper.LocaleHelper; public class MainApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(LocaleHelper.onAttach(base, "en")); } } 

所有你需要做的就是添加

 LocaleHelper.onCreate(this, "en"); 

无论你想改变语言环境。

如果你写

 android:configChanges="locale" 

在每一次活动中都不需要每次进入活动都要设置它

创build一个类扩展“Application”并创build一个静态方法。 然后你可以在“setContentView”之前的所有活动中调用这个方法。

  public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); } public static void setLocaleFa (Context context){ Locale locale = new Locale("fa"); Locale.setDefault(locale); Configuration config = new Configuration(); config.locale = locale; context.getApplicationContext().getResources().updateConfiguration(config, null); } public static void setLocaleEn (Context context){ Locale locale = new Locale("en_US"); Locale.setDefault(locale); Configuration config = new Configuration(); config.locale = locale; context.getApplicationContext().getResources().updateConfiguration(config, null); } 

}

活动中的用法:

  @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyApp.setLocaleFa(MainActivity.this); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); 

}

唯一完全适合我的解决scheme是Alex Volovoy的代码与应用程序重启机制的结合:

 void restartApplication() { Intent i = new Intent(MainTabActivity.context, MagicAppRestart.class); i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); MainTabActivity.context.startActivity(i); } /** This activity shows nothing; instead, it restarts the android process */ public class MagicAppRestart extends Activity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); finish(); } protected void onResume() { super.onResume(); startActivityForResult(new Intent(this, MainTabActivity.class), 0); } } 

对于Android 7.0牛轧糖(和更低)请按照这篇文章:

在Android中以编程方式更改语言

老答案
这包括RTL / LTR支持:

 public static void changeLocale(Context context, Locale locale) { Configuration conf = context.getResources().getConfiguration(); conf.locale = locale; Locale.setDefault(locale); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { conf.setLayoutDirection(conf.locale); } context.getResources().updateConfiguration(conf, context.getResources().getDisplayMetrics()); } 

我面临同样的问题。 在GitHub上,我find了Android-LocalizationActivity库 。

这个库使得在运行时更改应用程序的语言变得非常简单,如下面的代码示例所示。 包括下面的示例代码和更多信息的示例项目可以在github页面find。

LocalizationActivity扩展了AppCompatActivity,所以你也可以在使用Fragments的时候使用它。

 public class MainActivity extends LocalizationActivity implements View.OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_simple); findViewById(R.id.btn_th).setOnClickListener(this); findViewById(R.id.btn_en).setOnClickListener(this); } @Override public void onClick(View v) { int id = v.getId(); if (id == R.id.btn_en) { setLanguage("en"); } else if (id == R.id.btn_th) { setLanguage("th"); } } } 
 Locale locale = new Locale("en"); Locale.setDefault(locale); Configuration config = context.getResources().getConfiguration(); config.setLocale(locale); context.createConfigurationContext(config); 

重要更新:

 context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics()); 

请注意,在SDK> = 21上,您需要调用“Resources.updateConfiguration()” ,否则资源将不会更新。

 /*change language at Run-time*/ //use method like that: //setLocale("en"); public void setLocale(String lang) { myLocale = new Locale(lang); Resources res = getResources(); DisplayMetrics dm = res.getDisplayMetrics(); Configuration conf = res.getConfiguration(); conf.locale = myLocale; res.updateConfiguration(conf, dm); Intent refresh = new Intent(this, AndroidLocalize.class); startActivity(refresh); } 

在设置内容之前,应在每个activity设置Locale设置 – this.setContentView(R.layout.main);

首先为不同的语言创build多个string.xml; 然后在onCreate()方法中使用这段代码:

 super.onCreate(savedInstanceState); String languageToLoad = "fr"; // change your language here 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); 

Alex Volovoy答案只适用于我的活动的onCreate方法。

所有方法的答案在另一个线程中

在Android中以编程方式更改语言

这里是代码的修改

 Resources standardResources = getBaseContext().getResources(); AssetManager assets = standardResources.getAssets(); DisplayMetrics metrics = standardResources.getDisplayMetrics(); Configuration config = new Configuration(standardResources.getConfiguration()); config.locale = new Locale(languageToLoad); Resources defaultResources = new Resources(assets, metrics, config); 

希望它有帮助。

请注意,使用updateConfiguration这个解决scheme将不再适用于几个星期内发布的Android M版本。 现在使用applyOverrideConfiguration方法来查看API文档

你可以在这里find我的完整解决scheme,因为我自己面临这个问题: https : //stackoverflow.com/a/31787201/2776572

时间适当更新。

首先,将不赞成使用的API的不赞成使用的列表:

  • configuration.locale (API 17)
  • updateConfiguration(configuration, displaymetrics) (API 17)

最近得到解决的问题是新方法的使用

createConfigurationContext是updateConfiguration的新方法。

有些人像这样独立使用它:

 Configuration overrideConfiguration = ctx.getResources().getConfiguration(); Locale locale = new Locale("en_US"); overrideConfiguration.setLocale(locale); createConfigurationContext(overrideConfiguration); 

…但这不起作用。 为什么? 该方法返回一个上下文,然后用于处理Strings.xml翻译和其他本地化资源(图像,布局,任何)。

正确的用法是这样的:

 Configuration overrideConfiguration = ctx.getResources().getConfiguration(); Locale locale = new Locale("en_US"); overrideConfiguration.setLocale(locale); //the configuration can be used for other stuff as well Context context = createConfigurationContext(overrideConfiguration); Resources resources = context.getResources(); 

如果您只是将其复制粘贴到IDE中,则可能会看到API要求您针对API 17或更高版本的警告。 这可以通过将其放入一个方法,并添加注解@TargetApi(17)

可是等等。 旧的API呢?

您需要使用不带TargetApi批注的updateConfiguration创build另一个方法。

 Resources res = YourApplication.getInstance().getResources(); // Change locale settings in the app. DisplayMetrics dm = res.getDisplayMetrics(); android.content.res.Configuration conf = res.getConfiguration(); conf.locale = new Locale("th"); res.updateConfiguration(conf, dm); 

这里不需要返回上下文。

现在,pipe理这些可能是困难的。 在API 17+中,您需要创build的上下文(或创build的上下文中的资源)来获取基于本地化的适当资源。 你如何处理这个?

那么,这是我做的方式:

 /** * Full locale list: https://stackoverflow.com/questions/7973023/what-is-the-list-of-supported-languages-locales-on-android * @param lang language code (eg en_US) * @return the context * PLEASE READ: This method can be changed for usage outside an Activity. Simply add a COntext to the arguments */ public Context setLanguage(String lang/*, Context c*/){ Context c = AndroidLauncher.this;//remove if the context argument is passed. This is a utility line, can be removed totally by replacing calls to c with the activity (if argument Context isn't passed) int API = Build.VERSION.SDK_INT; if(API >= 17){ return setLanguage17(lang, c); }else{ return setLanguageLegacy(lang, c); } } /** * Set language for API 17 * @param lang * @param c * @return */ @TargetApi(17) public Context setLanguage17(String lang, Context c){ Configuration overrideConfiguration = c.getResources().getConfiguration(); Locale locale = new Locale(lang); Locale.setDefault(locale); overrideConfiguration.setLocale(locale); //the configuration can be used for other stuff as well Context context = createConfigurationContext(overrideConfiguration);//"local variable is redundant" if the below line is uncommented, it is needed //Resources resources = context.getResources();//If you want to pass the resources instead of a Context, uncomment this line and put it somewhere useful return context; } public Context setLanguageLegacy(String lang, Context c){ Resources res = c.getResources(); // Change locale settings in the app. DisplayMetrics dm = res.getDisplayMetrics();//Utility line android.content.res.Configuration conf = res.getConfiguration(); conf.locale = new Locale(lang);//setLocale requires API 17+ - just like createConfigurationContext Locale.setDefault(conf.locale); res.updateConfiguration(conf, dm); //Using this method you don't need to modify the Context itself. Setting it at the start of the app is enough. As you //target both API's though, you want to return the context as you have no clue what is called. Now you can use the Context //supplied for both things return c; } 

这段代码的工作原理是让一个方法根据什么API调用相应的方法。 这是我已经做了很多不同的弃用呼叫(包括Html.fromHtml)。 你有一个方法接受所需的参数,然后将其分成两个(或三个或更多)方法之一,并根据API级别返回适当的结果。 它是灵活的,因为你不必多次检查,“入口”方法为你做。 这里的入口方法是setLanguage

请在使用之前阅读本文

您需要使用获取资源时返回的上下文。 为什么? 我在这里看到了使用createConfigurationContext的其他答案,并且不使用它返回的上下文。 为了使它像那样工作,必须调用updateConfiguration。 已弃用。 使用方法返回的上下文获取资源。

用法示例

构造函数或类似的地方:

 ctx = getLanguage(lang);//lang is loaded or generated. How you get the String lang is not something this answer handles (nor will handle in the future) 

然后,无论你想获得资源,你都可以:

 String fromResources = ctx.getString(R.string.helloworld); 

使用任何其他上下文将(在理论上)打破这一点。

AFAIK你还必须使用一个活动上下文来显示对话框或Toast。 因为你可以使用一个活动的实例(如果你在外面)


最后,在活动上使用recreate()来刷新内容。 快捷方式不必创build一个意图刷新。

有一些步骤,你应该实现

首先,您需要更改您的configuration的区域设置

 Resources resources = context.getResources(); Configuration configuration = resources.getConfiguration(); configuration.locale = new Locale(language); resources.updateConfiguration(configuration, resources.getDisplayMetrics()); 

其次,如果希望将更改直接应用于可见的布局,则可以直接更新视图,也可以调用activity.recreate()重新启动当前的活动。

而且你也必须坚持你的改变,因为在用户closures你的应用程序后,你将失去语言的改变。

我在我的博文中以编程方式在Android中更改语言解释了更详细的解决scheme

基本上,你只需要调用你的应用程序类的LocaleHelper.onCreate(),如果你想改变区域设置,你可以调用LocaleHelper.setLocale()

类似于接受的答案,但2017版本,并添加重新启动(无需重新启动,有时下一个活动仍呈现英文):

 // Inside some activity... private void changeDisplayLanguage(String langCode) { // Step 1. Change the locale in the app's configuration Resources res = getResources(); android.content.res.Configuration conf = res.getConfiguration(); conf.setLocale(currentLocale); createConfigurationContext(conf); // Step 2. IMPORTANT! you must restart the app to make sure it works 100% restart(); } private void restart() { PackageManager packageManager = getPackageManager(); Intent intent = packageManager.getLaunchIntentForPackage(getPackageName()); ComponentName componentName = intent.getComponent(); Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName); mainIntent.putExtra("app_restarting", true); PrefUtils.putBoolean("app_restarting", true); startActivity(mainIntent); System.exit(0); } 

首先你创build目录名称值 – “语言名称”像印地文,而不是写“嗨”和相同的string文件名副本在这个目录中,改变值不会改变参数设置下面的代码后,你的行动像button等….

 Locale myLocale = new Locale("hi"); Resources res = getResources(); DisplayMetrics dm = res.getDisplayMetrics(); Configuration conf = res.getConfiguration(); conf.locale = myLocale; res.updateConfiguration(conf, dm); Intent refresh = new Intent(Home.this, Home.class); startActivity(refresh); finish(); 

这是工作,当我按下button来改变我的TextView的文本语言。(values.xml文件夹中的strings.xml)

 String languageToLoad = "de"; // your language Configuration config = getBaseContext().getResources().getConfiguration(); Locale locale = new Locale(languageToLoad); Locale.setDefault(locale); config.locale = locale; getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics()); recreate(); 
 private void setLanguage(String language) { Locale locale = new Locale(language); Locale.setDefault(locale); Configuration config = new Configuration(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { config.setLocale(locale); } else { config.locale = locale; } getResources().updateConfiguration(config, getResources().getDisplayMetrics()); } 

Just handle in method

 @Override public void onConfigurationChanged(android.content.res.Configuration newConfig). 

Follow the Link

I think it is useful

I encountered the same problem: I needed to set my language to a language chosen in my app.

My fix was this:

  1. Keep your strings in your XML file, don't extract it to resources
  2. Make an exact copy of your XML and rename it to _languagecode, like _fr (use lowercase!)
  3. Fix your translations in your XML copy
  4. In code you check your app-level language and inflate the relevant XML

例:

  String languageInitials = MyAppconfig.currentLanguageInitials(); if (languageInitials.equals("NL")) { view = inflater.inflate(R.layout.mylayout_nl, container, false); } else { view = inflater.inflate(R.layout.fragment_mylayout_fr, container, false); } 

From these XML's, you can still extract the needed strings to resources.

它为我工作

 Resources res = YourApplication.getInstance().getResources(); // Change locale settings in the app. DisplayMetrics dm = res.getDisplayMetrics(); android.content.res.Configuration conf = res.getConfiguration(); conf.locale = new Locale("th"); res.updateConfiguration(conf, dm);