WeChat number: public CodingAndroid CSDN:blog.csdn.net/xinpengfei5… Disclaimer: this article by CodingAndroid original, unauthorized, can not be reproduced at will!

Recently, our company’s business has expanded to Hong Kong, we all know that Hong Kong is used in traditional Chinese, as a result, our APP can be set to traditional language, it’s not we want to keep up with the pace of international, multilingual, will send our products demand mainly for simplified Chinese, traditional Chinese character, English three languages switch, specific business logic is: When the user enters the APP for the first time, the language of the APP follows the current system language. When the user sets a certain language, the language will be switched to the language set by the user. No matter what language is set later in the system, the language set by the user will not be affected. The language of the APP should also change with the system language Settings.

Note: This article takes simplified Chinese, traditional Chinese and English as an example for a brief explanation.

1. Implementation idea

We can use SharedPreference to store a language type value in advance. When the user enters the APP for the first time, we take out the value through Key, which will definitely not be available for the first time. At this time, we can set the language of the APP to the default value of the current system. When the user sets multiple languages, we can save the value corresponding to this language locally through SharedPreference, then restart the APP and set it to the language set by the user. In the future, when entering the APP, we only need to retrieve the language setting saved by the user. The general setting language is written in the onCreate() method of the Application entry.

2. Customize the SharedPreference tool class

Function: Used to save the current setting language type, this article to SharedPreference save as an example, of course, the use of database or other save methods can also be.

/ * *

* Created by xpf on 2017/03/25 :)

* Function: sp stored utility class

* /


public class SpUtil {

private static final String APP_SP = "app_sp";

private static final String TAG = SpUtil.class.getSimpleName();

private SpUtil(a) {

}

private static SpUtil instance = new SpUtil();

private static SharedPreferences mSp = null;

public static SpUtil getInstance(a) {

if (mSp == null) {

mSp = MyApplication.getContext().getSharedPreferences(APP_SP, Context.MODE_PRIVATE);

}

return instance;

}

/ * *

* Save data

*

* @paramThe key key

* @paramThe value value

* /


public void save(String key, Object value) {

if (value == null) {

Log.e(TAG, "Value ==null failed to save");

return;

}

if (value instanceof String) {

mSp.edit().putString(key, (String) value).commit();

} else if (value instanceof Boolean) {

mSp.edit().putBoolean(key, (Boolean) value).commit();

} else if (value instanceof Integer) {

mSp.edit().putInt(key, (Integer) value).commit();

}

}

/ * *

* Read String data

*

* @param key

* @param defValue

* @return

* /


public String getString(String key, String defValue) {

return mSp.getString(key, defValue);

}

/ * *

* Read Boolean data

*

* @param key

* @param defValue

* @return

* /


public boolean getBoolean(String key, boolean defValue) {

return mSp.getBoolean(key, defValue);

}

/ * *

* Read Boolean data

*

* @param key

* @param defValue

* @return

* /


public int getInt(String key, int defValue) {

return mSp.getInt(key, defValue);

}

/ * *

* Clear all saved data (xxx.xml still exists, but has no internal data)

* /


public void clearAll(a) {

mSp.edit().clear().commit();

}

}

Copy the code

3. Customize the LocaleUtil utility class

Function: Used to set the save language and obtain the current language, restart the APP and other operations

public class LocaleUtil {

/ * *

* Gets the Locale set by the user

*

* @return Locale

* /


public static Locale getUserLocale(a) {

int currentLanguage = SpUtil.getInstance().getInt("currentLanguage".0);

Locale myLocale = Locale.SIMPLIFIED_CHINESE;

switch (currentLanguage) {

case 0:

myLocale = Locale.SIMPLIFIED_CHINESE;

break;

case 1:

myLocale = Locale.ENGLISH;

break;

case 2:

myLocale = Locale.TRADITIONAL_CHINESE;

break;

}

return myLocale;

}

/ * *

* Setting language: Follow the setting if it has been set before; follow the system language if it has not been set before

* /


public static void changeAppLanguage(Context context) {

if (context == null) return;

Context appContext = context.getApplicationContext();

int currentLanguage = SpUtil.getInstance().getInt("currentLanguage", -1);

Locale myLocale;

// 0 Simplified Chinese 1 Traditional Chinese 2 English

switch (currentLanguage) {

case 0:

myLocale = Locale.SIMPLIFIED_CHINESE;

break;

case 1:

myLocale = Locale.TRADITIONAL_CHINESE;

break;

case 2:

myLocale = Locale.ENGLISH;

break;

default:

myLocale = appContext.getResources().getConfiguration().locale;

}

// Local language Settings

if (needUpdateLocale(appContext, myLocale)) {

updateLocale(appContext, myLocale);

}

}

/ * *

* Save the language of the setting

*

* @param currentLanguage index

* /


public static void changeAppLanguage(Context context, int currentLanguage) {

if (context == null) return;

Context appContext = context.getApplicationContext();

SpUtil.getInstance().save("currentLanguage", currentLanguage);

Locale myLocale = Locale.SIMPLIFIED_CHINESE;

// 0 Simplified Chinese 1 Traditional Chinese 2 English

switch (currentLanguage) {

case 0:

myLocale = Locale.SIMPLIFIED_CHINESE;

break;

case 1:

myLocale = Locale.TRADITIONAL_CHINESE;

break;

case 2:

myLocale = Locale.ENGLISH;

break;

}

// Local language Settings

if (LocaleUtil.needUpdateLocale(appContext, myLocale)) {

LocaleUtil.updateLocale(appContext, myLocale);

}

Toast.makeText(appContext, appContext.getString(R.string.set_success), Toast.LENGTH_SHORT).show();

restartApp(appContext);

}

/ * *

* Restart the app to take effect

*

* @param context

* /


public static void restartApp(Context context) {

Intent intent = new Intent(context, MainActivity.class);

intent.setAction(Intent.ACTION_MAIN);

intent.addCategory(Intent.CATEGORY_LAUNCHER);

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(intent);

}

/ * *

* Gets the current Locale

*

* @param context Context

* @return Locale

* /


public static Locale getCurrentLocale(Context context) {

Locale locale;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //7.0 has multi-language Settings to get the language at the top

locale = context.getResources().getConfiguration().getLocales().get(0);

} else {

locale = context.getResources().getConfiguration().locale;

}

return locale;

}

/ * *

* update the Locale

*

* @param context Context

* @param locale New User Locale

* /


public static void updateLocale(Context context, Locale locale) {

if (needUpdateLocale(context, locale)) {

Configuration configuration = context.getResources().getConfiguration();

if (Build.VERSION.SDK_INT >= 19) {

configuration.setLocale(locale);

} else {

configuration.locale = locale;

}

DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();

context.getResources().updateConfiguration(configuration, displayMetrics);

}

}

/ * *

* Determine if an update is needed

*

* @param context Context

* @param locale New User Locale

* @return true / false

* /


public static boolean needUpdateLocale(Context context, Locale locale) {

returnlocale ! =null && !getCurrentLocale(context).equals(locale);

}

/ * *

* Continue to follow the user-set language when the system language changes

*

* @param context

* @param newConfig

* /


public static void setLanguage(Context context, Configuration newConfig) {

if (context == null) return;

Context appContext = context.getApplicationContext();

int currentLanguage = SpUtil.getInstance().getInt("currentLanguage", -1);

Locale locale;

// 0 Simplified Chinese 1 Traditional Chinese 2 English

switch (currentLanguage) {

case 0:

locale = Locale.SIMPLIFIED_CHINESE;

break;

case 1:

locale = Locale.TRADITIONAL_CHINESE;

break;

case 2:

locale = Locale.ENGLISH;

break;

default:

locale = appContext.getResources().getConfiguration().locale;

}

// The system language has been changed to keep the previously set language of the application

if(locale ! =null) {

Locale.setDefault(locale);

Configuration configuration = new Configuration(newConfig);

if (Build.VERSION.SDK_INT >= 19) {

configuration.setLocale(locale);

} else {

configuration.locale = locale;

}

appContext.getResources().updateConfiguration(configuration, appContext.getResources().getDisplayMetrics());

}

}

}

Copy the code

3.1 Called in Application to initialize language Settings

    @Override

public void onCreate(a) {

super.onCreate();

LocaleUtil.changeAppLanguage(this);

}

Copy the code

3.2 Rewrite the following method in Application: Used to set the language when the system sets the language

    @Override

public void onConfigurationChanged(Configuration newConfig) {

super.onConfigurationChanged(newConfig);

Log.e("TAG"."onConfigurationChanged");

LocaleUtil.setLanguage(mContext, newConfig);

}

Copy the code

3.3 Set the APP language on the Multi-language Setting interface

When the user clicks “Save”, the Index value of the current language is passed in. In this case, an Int value is saved, and each Int value corresponds to the type of the language. Of course, you can save it as a String according to your own implementation.

LocaleUtil.changeAppLanguage(mContext.currentLanguage);

Copy the code

4. Multi-language folders are named in the following table:

This article only uses simplified Chinese, traditional Chinese and English as examples. For more language Settings, please refer to the following table:

countries Folder Name
Chinese (China) values-zh-rCN
Chinese (Taiwan) values-zh-rTW
Chinese (Hong Kong) values-zh-rHK
English (US) values-en-rUS
English (UK) values-en-rGB
English (Australia) values-en-rAU
English (Canada) values-en-rCA
English (Ireland) values-en-rIE
English (India) values-en-rIN
English (New Zealand) values-en-rNZ
English (Singapore) values-en-rSG
English (South Africa) values-en-rZA
Arabic (Egyptian) values-ar-rEG
Arabic (Israel) values-ar-rIL
Bulgarian values-bg-rBG
Catalan values-ca-rES
The Czech republic, values-cs-rCZ
dansk values-da-rDK
German (Austria) values-de-rAT
German (Switzerland) values-de-rCH
German (Germany) values-de-rDE
German (Liechtenstein) values-de-rLI
Greek values-el-rGR
Spanish (Spanish) values-es-rES
Spanish (American) values-es-rUS
Finnish (Finnish) values-fi-rFI
French (Belgium) values-fr-rBE
French (Canadian) values-fr-rCA
French (Swiss) values-fr-rCH
French (French) values-fr-rFR
Hebrew values-iw-rIL
Hindi values-hi-rIN
Croatian values-hr-rHR
In Hungary, values-hu-rHU
Indonesian values-in-rID
Italian (Swiss) values-it-rCH
Italian (Italian) values-it-rIT
Japanese values-ja-rJP
Korean values-ko-rKR
Lithuania, valueslt-rLT
Latvian values-lv-rLV
Bokmalven, Norway values-nb-rNO
Dutch (Belgian) values-nl-BE
Dutch (Dutch) values-nl-rNL
polish values-pl-rPL
Portuguese (Brazilian) values-pt-rBR
Portuguese (Portuguese) values-pt-rPT
Romanian values-ro-rRO
ru values-ru-rRU
Slovak values-sk-rSK
Slovene values-sl-rSI
Serbian values-sr-rRS
swe values-sv-rSE
Thai values-th-rTH
Tower gallo values-tl-rPH
Turkish values–r-rTR
Ukraine, values-uk-rUA
Vietnamese values-vi-rVN

5. Common potholes

  • Setting English language does not work on some phones. During development, we tried setting English language on Redmi Note 4 phones. This is because some phone manufacturers have British English by default, but we only use American English. ① Set the setting options of two Kinds of English, namely American English and British English; (2) You can name the res folder values-en without distinguishing between British and American English.
  • Before Android Studio3.0, if some strings do not correspond to other languages, that is, some fields are not translated, they will be warned when packaging, and can be packaged, but after 3.0, it is not possible, packaging will fail, so each strings must correspond to a complete set of translation!

6. Related permissions

<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>

Copy the code

7. More discussion

In fulfilling the APP to switch languages, tried WeChat multilingual Settings page is in grade 4, when it first after setting the language to jump to me interface (1 page), and then to set the interface (2 pages), seemingly WeChat didn’t restart the APP, it’s just preserved the Activity stack task management, and finally to jump to set the interface, In my example, I just restarted the App and did not jump back to the setting interface. Of course, it depends on specific needs. In my personal opinion, there is no need to jump back after setting.


Finally attached Demo: github.com/xinpengfei5…

If you feel good, you can give me a star,3Q~

If you encounter any problems in the process of use, or have good suggestions, welcome to put forward in the public account “CodingAndroid”