├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── ce │ │ └── switchlanguage │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── ce │ │ │ └── switchlanguage │ │ │ ├── LocaleUtils.java │ │ │ ├── MainActivity.java │ │ │ └── MyApplication.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── menu │ │ └── main_menu.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-ru │ │ └── strings.xml │ │ ├── values-zh │ │ └── strings.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── ce │ └── switchlanguage │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /README.md: -------------------------------------------------------------------------------- 1 | # SwitchLanguage 2 | Switch Language 3 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.ce.switchlanguage" 8 | minSdkVersion 15 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:24.0.0' 28 | testCompile 'junit:junit:4.12' 29 | compile 'com.google.code.gson:gson:2.2.4' 30 | compile 'com.android.support:design:25.1.0' 31 | } 32 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\android\android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/ce/switchlanguage/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.ce.switchlanguage; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext=InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.ce.switchlanguage", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/ce/switchlanguage/LocaleUtils.java: -------------------------------------------------------------------------------- 1 | package com.ce.switchlanguage; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.content.res.Configuration; 6 | import android.os.Build; 7 | import android.util.DisplayMetrics; 8 | 9 | import com.google.gson.Gson; 10 | 11 | import java.util.Locale; 12 | 13 | public class LocaleUtils { 14 | /** 15 | * 中文 16 | */ 17 | public static final Locale LOCALE_CHINESE = Locale.CHINESE; 18 | /** 19 | * 英文 20 | */ 21 | public static final Locale LOCALE_ENGLISH = Locale.ENGLISH; 22 | /** 23 | * 俄文 24 | */ 25 | public static final Locale LOCALE_RUSSIAN = new Locale("ru"); 26 | /** 27 | * 保存SharedPreferences的文件名 28 | */ 29 | private static final String LOCALE_FILE = "LOCALE_FILE"; 30 | /** 31 | * 保存Locale的key 32 | */ 33 | private static final String LOCALE_KEY = "LOCALE_KEY"; 34 | 35 | /** 36 | * 获取用户设置的Locale 37 | * @param pContext Context 38 | * @return Locale 39 | */ 40 | public static Locale getUserLocale(Context pContext) { 41 | SharedPreferences _SpLocale = pContext.getSharedPreferences(LOCALE_FILE, Context.MODE_PRIVATE); 42 | String _LocaleJson = _SpLocale.getString(LOCALE_KEY, ""); 43 | return jsonToLocale(_LocaleJson); 44 | } 45 | /** 46 | * 获取当前的Locale 47 | * @param pContext Context 48 | * @return Locale 49 | */ 50 | public static Locale getCurrentLocale(Context pContext) { 51 | Locale _Locale; 52 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //7.0有多语言设置获取顶部的语言 53 | _Locale = pContext.getResources().getConfiguration().getLocales().get(0); 54 | } else { 55 | _Locale = pContext.getResources().getConfiguration().locale; 56 | } 57 | return _Locale; 58 | } 59 | /** 60 | * 保存用户设置的Locale 61 | * @param pContext Context 62 | * @param pUserLocale Locale 63 | */ 64 | public static void saveUserLocale(Context pContext, Locale pUserLocale) { 65 | SharedPreferences _SpLocal=pContext.getSharedPreferences(LOCALE_FILE, Context.MODE_PRIVATE); 66 | SharedPreferences.Editor _Edit=_SpLocal.edit(); 67 | String _LocaleJson = localeToJson(pUserLocale); 68 | _Edit.putString(LOCALE_KEY, _LocaleJson); 69 | _Edit.apply(); 70 | } 71 | /** 72 | * Locale转成json 73 | * @param pUserLocale UserLocale 74 | * @return json String 75 | */ 76 | private static String localeToJson(Locale pUserLocale) { 77 | Gson _Gson = new Gson(); 78 | return _Gson.toJson(pUserLocale); 79 | } 80 | /** 81 | * json转成Locale 82 | * @param pLocaleJson LocaleJson 83 | * @return Locale 84 | */ 85 | private static Locale jsonToLocale(String pLocaleJson) { 86 | Gson _Gson = new Gson(); 87 | return _Gson.fromJson(pLocaleJson, Locale.class); 88 | } 89 | /** 90 | * 更新Locale 91 | * @param pContext Context 92 | * @param pNewUserLocale New User Locale 93 | */ 94 | public static void updateLocale(Context pContext, Locale pNewUserLocale) { 95 | if (needUpdateLocale(pContext, pNewUserLocale)) { 96 | Configuration _Configuration = pContext.getResources().getConfiguration(); 97 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 98 | _Configuration.setLocale(pNewUserLocale); 99 | } else { 100 | _Configuration.locale =pNewUserLocale; 101 | } 102 | DisplayMetrics _DisplayMetrics = pContext.getResources().getDisplayMetrics(); 103 | pContext.getResources().updateConfiguration(_Configuration, _DisplayMetrics); 104 | saveUserLocale(pContext, pNewUserLocale); 105 | } 106 | } 107 | /** 108 | * 判断需不需要更新 109 | * @param pContext Context 110 | * @param pNewUserLocale New User Locale 111 | * @return true / false 112 | */ 113 | public static boolean needUpdateLocale(Context pContext, Locale pNewUserLocale) { 114 | return pNewUserLocale != null && !getCurrentLocale(pContext).equals(pNewUserLocale); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/java/com/ce/switchlanguage/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.ce.switchlanguage; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.Menu; 8 | import android.view.MenuItem; 9 | 10 | public class MainActivity extends AppCompatActivity { 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.activity_main); 16 | Toolbar _Toolbar =(Toolbar) findViewById(R.id.toolbar); 17 | setSupportActionBar(_Toolbar); 18 | } 19 | 20 | @Override 21 | public boolean onCreateOptionsMenu(Menu menu) { 22 | getMenuInflater().inflate(R.menu.main_menu,menu); 23 | return true; 24 | } 25 | 26 | @Override 27 | public boolean onOptionsItemSelected(MenuItem item) { 28 | int _ItemId=item.getItemId(); 29 | switch (_ItemId) { 30 | case R.id.chinese: 31 | if (LocaleUtils.needUpdateLocale(this, LocaleUtils.LOCALE_CHINESE)) { 32 | LocaleUtils.updateLocale(this, LocaleUtils.LOCALE_CHINESE); 33 | restartAct(); 34 | } 35 | break; 36 | case R.id.english: 37 | if (LocaleUtils.needUpdateLocale(this, LocaleUtils.LOCALE_ENGLISH)) { 38 | LocaleUtils.updateLocale(this, LocaleUtils.LOCALE_ENGLISH); 39 | restartAct(); 40 | } 41 | break; 42 | case R.id.russian: 43 | if (LocaleUtils.needUpdateLocale(this, LocaleUtils.LOCALE_RUSSIAN)) { 44 | LocaleUtils.updateLocale(this, LocaleUtils.LOCALE_RUSSIAN); 45 | restartAct(); 46 | } 47 | } 48 | return true; 49 | } 50 | 51 | /** 52 | * 重启当前Activity 53 | */ 54 | private void restartAct() { 55 | finish(); 56 | Intent _Intent = new Intent(this, MainActivity.class); 57 | startActivity(_Intent); 58 | //清除Activity退出和进入的动画 59 | overridePendingTransition(0, 0); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/ce/switchlanguage/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.ce.switchlanguage; 2 | 3 | import android.app.Application; 4 | import android.content.res.Configuration; 5 | import android.os.Build; 6 | 7 | import java.util.Locale; 8 | 9 | public class MyApplication extends Application { 10 | @Override 11 | public void onCreate() { 12 | super.onCreate(); 13 | Locale _UserLocale=LocaleUtils.getUserLocale(this); 14 | LocaleUtils.updateLocale(this, _UserLocale); 15 | } 16 | 17 | @Override 18 | public void onConfigurationChanged(Configuration newConfig) { 19 | super.onConfigurationChanged(newConfig); 20 | Locale _UserLocale=LocaleUtils.getUserLocale(this); 21 | //系统语言改变了应用保持之前设置的语言 22 | if (_UserLocale != null) { 23 | Locale.setDefault(_UserLocale); 24 | Configuration _Configuration = new Configuration(newConfig); 25 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 26 | _Configuration.setLocale(_UserLocale); 27 | } else { 28 | _Configuration.locale =_UserLocale; 29 | } 30 | getResources().updateConfiguration(_Configuration, getResources().getDisplayMetrics()); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 15 | 16 | 23 | 24 | 25 | 29 |