Androidリソースを使用しながら、プログラムでアプリの言語を変更することはできますか?
そうでない場合、特定の言語でリソースをリクエストすることは可能ですか?
ユーザーにアプリの言語をアプリから変更させたい。
Androidリソースを使用しながら、プログラムでアプリの言語を変更することはできますか?
そうでない場合、特定の言語でリソースをリクエストすることは可能ですか?
ユーザーにアプリの言語をアプリから変更させたい。
回答:
それが可能だ。ロケールを設定できます。ただし、お勧めしません。私たちは初期段階でそれを試しました、それは基本的にシステムとの戦いです。
言語を変更するための同じ要件がありますが、UIは電話のUIと同じでなければならないという事実に落ち着くことにしました。ロケールの設定を介して動作していましたが、バグが多すぎました。そして、私の経験からアクティビティ(各アクティビティ)に入るたびに設定する必要があります。これがまだ必要な場合のコードです(ここでもお勧めしません)
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);
言語固有のコンテンツがある場合-設定に基づいてその内容を変更できます。
2020年3月26日更新
public static void setLocale(Activitycontext) {
Locale locale;
Sessions session = new Sessions(context);
//Log.e("Lan",session.getLanguage());
locale = new Locale(langCode);
Configuration config = new Configuration(context.getResources().getConfiguration());
Locale.setDefault(locale);
config.setLocale(locale);
context.getBaseContext().getResources().updateConfiguration(config,
context.getBaseContext().getResources().getDisplayMetrics());
}
Context.createConfigurationContext()
。これを使用して、デフォルトのコンテキストをロケール固有の構成でラップgetResources
し、リソースオブジェクト自体の構成を更新する必要なくそれを呼び出すことができます。
conf.setLayoutDirection(locale)
代わりにconf.locale = new Locale(...))
、で置き換えることができますconf.setLocale(new Locale(...))
。内部的にを呼び出しますsetLayoutDirection
。
このコードは本当に機能します:
fa =ペルシア語、en =英語
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);
}
}
Resources.updateConfiguration
メソッドの2番目の引数にすぎません。コードをインデントして、わかりやすくしました。
プログラムでシステム言語を変更する方法を探していました。私は通常のアプリケーションがそれを行うべきではなく、代わりに次のいずれかであることを完全に理解しています:
システムの言語をプログラムによって実際に変更する必要がありました。
これは文書化されていない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);
android.permission.CHANGE_CONFIGURATION
performキーで署名されたアプリでのみ付与できます。
アプリ全体で言語を変更したい場合は、2つのことを行う必要があります。
まず、ベースアクティビティを作成し、すべてのアクティビティをこれから拡張します。
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に保存することに注意してください。
次に、次のようなアプリケーションの拡張を作成します。
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()は上記と同じです。
それで全部です!これが誰かに役立つことを願っています。
Application
がどのように使用するかを学びましょう。 mobomo.com/2011/05/how-to-use-application-object-of-android
configuration.locate
は非推奨で、setLocaleにはAPI
この記事によると。LocaleHelper.java
その記事で参照されているものをダウンロードする必要があります。
MyApplication
拡張するクラスを作成するApplication
attachBaseContext()
して言語を更新します。このクラスをマニフェストに登録します。
public class MyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
}
}
<application
android:name="com.package.MyApplication"
.../>
作成BaseActivity
してオーバーライドonAttach()
し、言語を更新します。Android 6以降で必要
public class BaseActivity extends Activity {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
}
アプリのすべてのアクティビティをから拡張し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;
}
}
私をつまずかせた余分な作品を追加するだけです。
他の答えは、たとえば「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());
activity.recreate()
android.content.res.Configuration conf = res.getConfiguration();
新しいConfiguration
インスタンスを作成する代わりに使用するのはどうですか?フレッシュなものを使うメリットはありますか?
アプリの起動自体がドイツ語に変更されました。
これが私の正しいコードです。誰もが私のためにこれを同じように使用したい..(プログラムでアンドロイドの言語を変更する方法)
私のコード:
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);
}
回答が遅いのはわかっていますが、この記事はこちらで見つかりました 。これはプロセス全体を非常によく説明し、適切に構造化されたコードを提供します。
ロケールヘルパークラス:
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");
ロケールを変更したい場所。
createConfigurationContext
役に立った
クラスをApplication
作成し、静的メソッドを拡張して作成します。次に、この前にすべてのアクティビティでこのメソッドを呼び出すことができます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);
}
古い回答
これには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());
}
私にとって完全に機能する唯一のソリューションは、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);
}
}
activity.recreate()
私も同じ問題に直面していました。GitHubでAndroid-LocalizationActivityライブラリを見つけました。
このライブラリを使用すると、実行時にアプリの言語を非常に簡単に変更できます。以下のコードサンプルをご覧ください。以下のサンプルコードと詳細を含むサンプルプロジェクトは、githubページにあります。
LocalizationActivityはAppCompatActivityを拡張するため、フラグメントを使用しているときにも使用できます。
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");
}
}
}
期限の更新の時間。
まず、非推奨となった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を使用して別のメソッドを作成する必要があります。
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);
ここでコンテキストを返す必要はありません。
現在、これらの管理は困難な場合があります。API 17以降では、ローカリゼーションに基づいて適切なリソースを取得するには、作成されたコンテキスト(または作成されたコンテキストからのリソース)が必要です。これをどのように処理しますか?
まあ、これは私がそれをする方法です:
/**
* Full locale list: /programming/7973023/what-is-the-list-of-supported-languages-locales-on-android
* @param lang language code (e.g. 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に基づいて適切なメソッドを呼び出す1つのメソッドを持つことで機能します。これは、さまざまな非推奨の呼び出し(Html.fromHtmlを含む)で私が行ったものです。必要な引数を受け取る1つのメソッドがあり、それを2つ(または3つ以上)のメソッドのいずれかに分割し、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でも、ダイアログまたはトーストを表示するには、アクティビティコンテキストを使用する必要があります。そのため、アクティビティのインスタンスを使用できます(外にいる場合)
最後recreate()
に、アクティビティを使用してコンテンツを更新します。更新するインテントを作成する必要がないショートカット。
あなたが書くなら
android:configChanges="locale"
すべてのアクティビティ(マニフェストファイル内)では、を入力するたびに設定する必要はありませんActivity
。
configChanges
ローテーションなどでアクティビティの状態を保持するためのハックに使用されただけなので、アクティビティが切り替わるときにAndroidがロケールを設定できないかどうかはわかりません。
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()'を呼び出す必要があることに注意してください。そうしないと、リソースは更新されません。
Context ctx = createConfigurationContext(args);
そしてそこからリソースを取得します
/*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.recreate()
Locale
configuration
activity
コンテンツを設定する前に、それぞれに設定する必要があります-this.setContentView(R.layout.main);
activity.recreate()
最初に、異なる言語用のマルチ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);
これは私のために働くいくつかのコードです:
public class MainActivity extends AppCompatActivity {
public static String storeLang;
@Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences shp = PreferenceManager.getDefaultSharedPreferences(this);
storeLang = shp.getString(getString(R.string.key_lang), "");
// Create a new Locale object
Locale locale = new Locale(storeLang);
// Create a new configuration object
Configuration config = new Configuration();
// Set the locale of the new configuration
config.locale = locale;
// Update the configuration of the Accplication context
getResources().updateConfiguration(
config,
getResources().getDisplayMetrics()
);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
出典:こちら
ここに記載されている解決策はどれも役に立ちませんでした。
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)の場合、言語がandroid> = 7.0に切り替わりませんでした
このLocaleUtilsは正常に動作します: https ://gist.github.com/GigigoGreenLabs/7d555c762ba2d3a810fe
LocaleUtils
public class LocaleUtils {
public static final String LAN_SPANISH = "es";
public static final String LAN_PORTUGUESE = "pt";
public static final String LAN_ENGLISH = "en";
private static Locale sLocale;
public static void setLocale(Locale locale) {
sLocale = locale;
if(sLocale != null) {
Locale.setDefault(sLocale);
}
}
public static void updateConfig(ContextThemeWrapper wrapper) {
if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration configuration = new Configuration();
configuration.setLocale(sLocale);
wrapper.applyOverrideConfiguration(configuration);
}
}
public static void updateConfig(Application app, Configuration configuration) {
if(sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
//Wrapping the configuration to avoid Activity endless loop
Configuration config = new Configuration(configuration);
config.locale = sLocale;
Resources res = app.getBaseContext().getResources();
res.updateConfiguration(config, res.getDisplayMetrics());
}
}
}
このコードをアプリケーションに追加しました
public class App extends Application {
public void onCreate(){
super.onCreate();
LocaleUtils.setLocale(new Locale("iw"));
LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleUtils.updateConfig(this, newConfig);
}
}
アクティビティのコード
public class BaseActivity extends AppCompatActivity {
public BaseActivity() {
LocaleUtils.updateConfig(this);
}
}
Alex Volovoyの回答は、アクティビティのonCreateメソッドにある場合にのみ機能します。
すべてのメソッドで機能する答えは別のスレッドにあります
ここにコードの適応があります
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
すると、数週間後のAndroid Mリリースでは機能しなくなります。これを行う新しい方法は、APIドキュメントapplyOverrideConfiguration
をContextThemeWrapper
参照してください。
私が自分で問題に直面したので、ここで私の完全な解決策を見つけることができます:https : //stackoverflow.com/a/31787201/2776572
実装する必要があるいくつかの手順があります
まず、設定のロケールを変更する必要があります
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = new Locale(language);
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
次に、変更を表示されているレイアウトに直接適用したい場合は、ビューを直接更新するか、またはactivity.recreate()を呼び出して現在のアクティビティを再開できます。
また、ユーザーがアプリケーションを閉じた後、言語の変更が失われるため、変更を永続化する必要があります。
Androidでプログラム的に言語を変更するブログ投稿で、より詳細な解決策を説明しました
基本的に、アプリケーションクラスでLocaleHelper.onCreate()を呼び出すだけです。その場でロケールを変更したい場合は、LocaleHelper.setLocale()を呼び出すことができます。
これは、ボタンを押してTextViewのテキスト言語を変更すると機能します。(values-deフォルダーの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();
LocaleHelperクラスを追加する
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;
}
}
活動中またはフラグメント中
Context context = LocaleHelper.setLocale(this, App.getSharedPre().getLanguage());
Resource resources = context.getResources();
すべてのテキストにSetText
TextView tv = findViewById(R.id.tv);
tv.setText(resources.getString(R.string.tv));
承認済みの回答済みですが、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);
}
activity.recreate()
3)リソースを取得するために使用する必要があると考えられるコンテキストが返される
まず、ディレクトリ名の値を作成します。「hi」と同じ文字列ファイル名のコピーをこのディレクトリに書き込むよりも、ヒンディー語のような「言語名」を使用し、ボタンなどのアクションでコードの下に設定した後、値を変更してもパラメータは変更されません。
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();
conf.locale
は非推奨です
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());
}
例では英語を設定します:
Configuration config = GetBaseContext().getResources().getConfiguration();
Locale locale = new Locale("en");
Locale.setDefault(locale);
config.locale = locale;
GetBaseContext().getResources().updateConfiguration(config,
GetBaseContext().getResources().getDisplayMetrics());
これは、アプリケーションだけでなく、デバイスシステムにも言語が見つかった場合にのみ機能することに注意してください。
アラビア語/ RTLサポートの場合
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(updateBaseContextLocale(newBase));
}
public Context updateBaseContextLocale(Context context) {
String language = SharedPreference.getInstance().getValue(context, "lan");//it return "en", "ar" like this
if (language == null || language.isEmpty()) {
//when first time enter into app (get the device language and set it
language = Locale.getDefault().getLanguage();
if (language.equals("ar")) {
SharedPreference.getInstance().save(mContext, "lan", "ar");
}
}
Locale locale = new Locale(language);
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResourcesLocale(context, locale);
return updateResourcesLocaleLegacy(context, locale);
}
return updateResourcesLocaleLegacy(context, locale);
}
@TargetApi(Build.VERSION_CODES.N)
private Context updateResourcesLocale(Context context, Locale locale) {
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}