Android实现多语言国际化并适配Android7.0以上

一、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源码

你可能感兴趣的:(Android)