一、Android国际化的例子有很多,但是都是老的,有的在Android7.0以上是没办法实现多语言。这个例子的需求是这样的:App每次启动都去读取手机本地设置的语音环境,如果是中文,不管简体繁体,都显示中文,其他的语言则显示英文。还有一种需求就是在App里面设置固定的语音,这里的话,参考这位传送门 。本人也是在这个上做的简化更改。
二、做法思路:
1、在application 的 attachBaseContext设置当前设置的语言Local。
2、在application 的onConfigurationChanged(改变系统语言时会调用到)设置当前的语言Local。
3、在 Activity 的attachBaseContext设置当前设置的语言Local,所以一般这里是创建BaseActivity来方便统一改变。
4、在Fragment中的做法和在Activity中一样,只要在Fragment所在的Activity中设置attachBaseContext。
三、上代码:
1、先写一个存储工具类,将当前手机所这只的语音保存起来。
public class LocalSPUtil {
private final String SP_NAME = "language_setting";
private final String TAG_LANGUAGE = "language_select";
private static volatile LocalSPUtil instance;
private final SharedPreferences mSharedPreferences;
private Locale systemCurrentLocal = Locale.ENGLISH;
public LocalSPUtil(Context context) {
mSharedPreferences = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
}
public void saveLanguage(int select) {
SharedPreferences.Editor edit = mSharedPreferences.edit();
edit.putInt(TAG_LANGUAGE, select);
edit.commit();
}
public int getSelectLanguage() {
return mSharedPreferences.getInt(TAG_LANGUAGE, 0);
}
public Locale getSystemCurrentLocal() {
return systemCurrentLocal;
}
public void setSystemCurrentLocal(Locale local) {
systemCurrentLocal = local;
}
public static LocalSPUtil getInstance(Context context) {
if (instance == null) {
synchronized (LocalSPUtil.class) {
if (instance == null) {
instance = new LocalSPUtil(context);
}
}
}
return instance;
}
}
2、一个语音设置管理工具类:
public class LocalManageUtil {
private static final String TAG = "LocalManageUtil";
/**
* 获取系统的locale
*
* @return Locale对象
*/
public static Locale getSystemLocale(Context context) {
switch (LocalSPUtil.getInstance(context).getSystemCurrentLocal().getLanguage()){
case "zh":
return Locale.CHINA;
case "en":
return Locale.ENGLISH;
default:
return Locale.ENGLISH;
}
}
public static Context setLocal(Context context) {
return updateResources(context, getSystemLocale(context));
}
private static Context updateResources(Context context, Locale locale) {
Locale.setDefault(locale);
Resources res = context.getResources();
Configuration config = new Configuration(res.getConfiguration());
if (Build.VERSION.SDK_INT >= 17) {
config.setLocale(locale);
context = context.createConfigurationContext(config);
} else {
config.locale = locale;
res.updateConfiguration(config, res.getDisplayMetrics());
}
return context;
}
public static void saveSystemCurrentLanguage(Context context) {
Locale locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
locale = LocaleList.getDefault().get(0);
} else {
locale = Locale.getDefault();
}
Log.d(TAG, locale.getLanguage());
Log.d(TAG, locale.getCountry());
LocalSPUtil.getInstance(context).setSystemCurrentLocal(locale);
}
public static void onConfigurationChanged(Context context){
saveSystemCurrentLanguage(context);
setLocal(context);
}
}
这里对上面做一下说明,首先getSystemLocale()是获取的系统当前的设置语言,如果是中文,则返回Locale.CHINA;其他的则返回Locale.ENGLISH;这就是App根据本地语音设置当前语音的关键。二、更新App里的语言updateResources(),这里面里注意到有对Android版本的判断对设置Local的方法是不一样的。三、saveSystemCurrentLanguage(),是官方API获取当前手机Local,这里也对版本做了判断,在Android7.0以上Local是放在一个List里面,所以获取的时候要注意。
3、在Application中初始化设置:
public class MyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
LocalManageUtil.saveSystemCurrentLanguage(base);
super.attachBaseContext(LocalManageUtil.setLocal(base));
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocalManageUtil.onConfigurationChanged(getApplicationContext());
}
@Override
public void onCreate() {
super.onCreate();
LocalManageUtil.setLocal(this);
}
}
4、在Activity中基类只需要重写以下方法,并调用LocalManageUtil.setLocal(context):
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(LocalManageUtil.setLocal(newBase));
}
最后,在res包下面创建values-en,里面创建一个sting.xml将英文翻译放进去就ok了。
附源码:demo源码