通过android.content.res.Configuration 类,可以修改语言参数,实现对应用语言的变更:
Configuration configuration = getResources().getConfiguration();得到配置Configuration之后,可以得到Locale对象,包含本地的一些信息:
Locale locale = configuration.locale;注意,Android N之后这个Configuration类的locale成员变量被标记为deprecate,不推荐再使用:
/**
* Current user preference for the locale, corresponding to
* <a href="{@docRoot}guide/topics/resources/providing-resources.html#LocaleQualifier">locale</a>
* resource qualifier.
*
* @deprecated Do not set or read this directly. Use {@link #getLocales()} and
* {@link #setLocales(LocaleList)}. If only the primary locale is needed,
* <code>getLocales().get(0)</code> is now the preferred accessor.
*/
@Deprecated public Locale locale;Android N之后应当使用getLocales()方法,
LocaleList locales = configuration.getLocales();注意,如果在低于Android N上的手机运行上面的APP会奔溃,
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.easyicon.learnglide, PID: 5320
java.lang.NoSuchMethodError: No virtual method getLocales()Landroid/os/LocaleList; in class Landroid/content/res/Configuration; or its super classes (declaration of 'android.content.res.Configuration' appears in /system/framework/framework.jar)
为了兼容通过Build.VERSION.SDK_INT判断,参考《获取系统SDK版本、判断手机ROM 》。
1、获取地区
getCountry()方法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LocaleList locales = configuration.getLocales();
String country = locales.get(0).getCountry();
} else {
Locale locale = configuration.locale;
String country = locale.getCountry();
}2、获取系统语言
getLauguage()方法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LocaleList locales = configuration.getLocales();
String language = locales.get(0).getLanguage();
} else {
Locale locale = configuration.locale;
String language = locale.getLanguage();
}3、切换应用语言
设置整个APP的语言,继承Application,在onCreate()中设置语言。开发中就可以设置自己应用的语言,
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Resources resources = getResources();
Configuration config = resources.getConfiguration();
//这里设置语言或和者地区
config.setLocale(Locale.JAPAN);
DisplayMetrics dm = resources.getDisplayMetrics();
resources.updateConfiguration(config, dm);
}
}别忘了,在AndroidManifest中将Application替换成自定义的:
<application
...
android:name=".MyApplication">
...
</application>不需要整个应用切换语言可以在对应的Activity中配置android:configChanges属性,通过配置该属性,Activity可以捕捉设备状态的变化。参考onConfigurationChanged()及屏幕横竖屏锁定。
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>单独设置Activity的语言,不会立即生效,需要重启这个Activity。:
//刷新当前页面
Intent intent = new Intent(MainActivity.this,MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);4、设置系统语言
网上找了很多,两种方法,一种跳到系统设置手动选择语言。另一种通过反射调用系统方法,需要系统权限,一般系统应用才能操作或者把APP编译成有系统签名的APK。
4.1、跳转到设置(可用)
跳到系统设置,选择语言,对于普通应用只能做到这了:
Intent intent = new Intent(Settings.ACTION_LOCALE_SETTINGS);
startActivity(intent);4.2、反射代码(不可用)
切换系统语言的方法位于LocalePicker.java文件,参考源码。
/**
* Requests the system to update the list of system locales.
* Note that the system looks halted for a while during the Locale migration,
* so the caller need to take care of it.
*/
@UnsupportedAppUsage
public static void updateLocales(LocaleList locales) {
try {
final IActivityManager am = ActivityManager.getService();
final Configuration config = am.getConfiguration();
config.setLocales(locales);
config.userSetLocale = true;
am.updatePersistentConfiguration(config);
// Trigger the dirty bit for the Settings Provider.
BackupManager.dataChanged("com.android.providers.settings");
} catch (RemoteException e) {
// Intentionally left blank
}
}4.3、语言切换工具(仅部分手机)
废那么大功夫,就是为了调用LocalPicker。系统APP或者平台编译出来的APK可以直接调用LocalePicker,但是对于普通APP无法取到。

反编译出的源码可以看到这个工具系Android系统平台编译,可以直接方便的调用LocalePicker方法切换系统语言,仅需一句代码:

参考资料:

