AndroidManifest.xml
引用OSportApplciation
<application
android:name=".OSportApplciation"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
tools:targetApi="31">
OSportApplciation.kt
package com.oplayer.myapplication
import android.app.Application
import android.content.Context
import com.oplayer.language.MultiLanguages
class OSportApplciation : Application() {
override fun onCreate() {
super.onCreate()
//初始化多语言工具
MultiLanguages.init(this)
}
override fun attachBaseContext(base: Context?) {
// 国际化适配(绑定语种)
super.attachBaseContext(MultiLanguages.attach(base))
}
}
MainActivity.kt
设置语言
package com.oplayer.myapplication
import android.os.Bundle
import android.util.Log
import com.oplayer.BaseActivity
import com.oplayer.language.MultiLanguages
import java.util.*
class MainActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun initView() {
//设置语言
MultiLanguages.setAppLanguage(this, Locale("de","DE"))//de_DE en,US
Log.d("","当前app语言 ${ MultiLanguages.getAppLanguage()} ")
}
override fun initInfo() {
}
override fun initData() {
}
}
BaseActivity.kt
package com.oplayer
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
abstract class BaseActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initView()
initInfo()
initData()
}
abstract fun initView()
abstract fun initInfo()
abstract fun initData()
}
多语言工具类
ActivityLanguages.java
package com.oplayer.language;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
/**
* author : Android 轮子哥
* github : https://github.com/getActivity/MultiLanguages
* time : 2021/01/21
* desc : Activity 语种绑定
*/
final class ActivityLanguages implements Application.ActivityLifecycleCallbacks {
static void inject(Application application) {
application.registerActivityLifecycleCallbacks(new ActivityLanguages());
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
MultiLanguages.updateAppLanguage(activity);
}
@Override
public void onActivityStarted(Activity activity) {}
@Override
public void onActivityResumed(Activity activity) {
MultiLanguages.updateAppLanguage(activity);
}
@Override
public void onActivityPaused(Activity activity) {}
@Override
public void onActivityStopped(Activity activity) {}
@Override
public void onActivityDestroyed(Activity activity) {}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
}
LanguagesConfig.java
package com.oplayer.language;
import android.content.Context;
import android.content.SharedPreferences;
import java.util.Locale;
/**
* author : Android 轮子哥
* github : https://github.com/getActivity/MultiLanguages
* time : 2019/05/03
* desc : 配置保存类
*/
final class LanguagesConfig {
private static final String KEY_LANGUAGE = "key_language";
private static final String KEY_COUNTRY = "key_country";
private static final String KEY_LANGUAGE_TYPE = "key_language_type";
private static String sSharedPreferencesName = "language_setting";
private static Locale sCurrentLanguage;
static void setSharedPreferencesName(String name) {
sSharedPreferencesName = name;
}
private static SharedPreferences getSharedPreferences(Context context) {
return context.getSharedPreferences(sSharedPreferencesName, Context.MODE_PRIVATE);
}
static void setAppLanguage(Context context, Locale locale) {
sCurrentLanguage = locale;
getSharedPreferences(context).edit()
.putString(KEY_LANGUAGE, locale.getLanguage())
.putString(KEY_COUNTRY, locale.getCountry())
.apply();
}
static Locale getAppLanguage(Context context) {
if (sCurrentLanguage == null) {
String language = getSharedPreferences(context).getString(KEY_LANGUAGE, null);
String country = getSharedPreferences(context).getString(KEY_COUNTRY, null);
if (language != null && !"".equals(language)) {
sCurrentLanguage = new Locale(language, country);
} else {
sCurrentLanguage = Locale.getDefault();
}
}
return sCurrentLanguage;
}
static void clearLanguage(Context context) {
sCurrentLanguage = MultiLanguages.getSystemLanguage();
getSharedPreferences(context).edit().remove(KEY_LANGUAGE).remove(KEY_COUNTRY).apply();
}
static void setLanguageType(Context context, boolean isSystemLanguage) {
getSharedPreferences(context).edit()
.putBoolean(KEY_LANGUAGE_TYPE, isSystemLanguage)
.apply();
}
static boolean getLanguageType(Context context) {
return getSharedPreferences(context).getBoolean(KEY_LANGUAGE_TYPE, true);
}
}
LanguagesObserver.java
package com.oplayer.language;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import java.util.Locale;
/**
* author : Android 轮子哥
* github : https://github.com/getActivity/MultiLanguages
* time : 2019/05/06
* desc : 语种变化监听
*/
final class LanguagesObserver implements ComponentCallbacks {
/** 系统语种 */
private static volatile Locale sSystemLanguage;
static {
// 获取当前系统的语种
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
sSystemLanguage = Resources.getSystem().getConfiguration().getLocales().get(0);
} else {
sSystemLanguage = Resources.getSystem().getConfiguration().locale;
}
}
/**
* 获取系统的语种
*/
static Locale getSystemLanguage() {
return sSystemLanguage;
}
/**
* 注册系统语种变化监听
*/
static void register(Context context) {
context.registerComponentCallbacks(new LanguagesObserver());
}
/**
* 手机的语种发生了变化
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
Locale newLocale =LanguagesTools.getLocale(newConfig);
Locale oldLocale = sSystemLanguage;
if (newLocale.equals(oldLocale)) {
return;
}
sSystemLanguage = newLocale;
OnLanguageListener listener = MultiLanguages.getOnLanguagesListener();
if (listener != null) {
listener.onSystemLocaleChange(oldLocale, newLocale);
}
}
@Override
public void onLowMemory() {}
}
LanguagesTools.java
package com.oplayer.language;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.LocaleList;
import java.util.Locale;
/**
* author : Android 轮子哥
* github : https://github.com/getActivity/MultiLanguages
* time : 2019/05/03
* desc : 国际化工具类
*/
@SuppressWarnings("deprecation")
final class LanguagesTools {
/**
* 获取当前语种对象
*/
static Locale getLocale(Context context) {
return getLocale(context.getResources().getConfiguration());
}
static Locale getLocale(Configuration config) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return config.getLocales().get(0);
} else {
return config.locale;
}
}
/**
* 绑定当前 App 的语种
*/
static Context attachLanguages(Context context, Locale locale) {
Resources resources = context.getResources();
Configuration config = new Configuration(resources.getConfiguration());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LocaleList localeList = new LocaleList(locale);
LocaleList.setDefault(localeList);
config.setLocales(localeList);
} else {
config.setLocale(locale);
}
context = context.createConfigurationContext(config);
} else {
config.locale = locale;
}
resources.updateConfiguration(config, resources.getDisplayMetrics());
Locale.setDefault(locale);
return context;
}
/**
* 更新 Resources 语种
*/
static void updateLanguages(Resources resources, Locale locale) {
Configuration config = resources.getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LocaleList localeList = new LocaleList(locale);
LocaleList.setDefault(localeList);
config.setLocales(localeList);
} else {
config.setLocale(locale);
}
} else {
config.locale = locale;
}
resources.updateConfiguration(config, resources.getDisplayMetrics());
Locale.setDefault(locale);
}
/**
* 获取某个语种下的 Resources 对象
*/
static Resources getLanguageResources(Context context, Locale locale) {
Configuration config = new Configuration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LocaleList localeList = new LocaleList(locale);
LocaleList.setDefault(localeList);
config.setLocales(localeList);
} else {
config.setLocale(locale);
}
return context.createConfigurationContext(config).getResources();
}
config.locale = locale;
return new Resources(context.getAssets(), context.getResources().getDisplayMetrics(), config);
}
}
MultiLanguages.java
package com.oplayer.language;
import android.app.Application;
import android.content.Context;
import android.content.res.Resources;
import java.util.Locale;
/**
* author : Android 轮子哥
* github : https://github.com/getActivity/MultiLanguages
* time : 2019/05/03
* desc : 多语种适配
*/
public final class MultiLanguages {
/** Application 对象 */
private static Application sApplication;
/** 语种变化监听对象 */
private static OnLanguageListener sLanguageListener;
/**
* 初始化多语种框架
*/
public static void init(Application application) {
init(application, true);
}
public static void init(Application application, boolean inject) {
sApplication = application;
LanguagesObserver.register(application);
if (inject) {
ActivityLanguages.inject(application);
}
}
/**
* 在上下文的子类中重写 attachBaseContext 方法(用于更新 Context 的语种)
*/
public static Context attach(Context context) {
if (!LanguagesTools.getLocale(context).equals(LanguagesConfig.getAppLanguage(context))) {
return LanguagesTools.attachLanguages(context, LanguagesConfig.getAppLanguage(context));
}
return context;
}
/**
* 更新 Context 的语种
*/
public static void updateAppLanguage(Context context) {
updateAppLanguage(context.getResources());
}
/**
* 更新 Resources 的语种
*/
public static void updateAppLanguage(Resources resources) {
if (!LanguagesTools.getLocale(resources.getConfiguration()).equals(LanguagesConfig.getAppLanguage(sApplication))) {
LanguagesTools.updateLanguages(resources, LanguagesConfig.getAppLanguage(sApplication));
}
}
/**
* 获取 App 的语种
*/
public static Locale getAppLanguage() {
return LanguagesConfig.getAppLanguage(sApplication);
}
/**
* 获取 App 的语种
*/
public static Locale getLanguage() {
// return LanguagesConfig.getAppLanguage(sApplication);
if (LanguagesConfig.getLanguageType(sApplication)){
return getSystemLanguage();
} else {
return LanguagesConfig.getAppLanguage(sApplication);
}
}
/**
* 设置 App 的语种
*/
public static boolean setAppLanguage(Context context, Locale newLocale) {
if (LanguagesTools.getLocale(context).equals(newLocale)) {
// 不需要重启
return false;
}
Locale oldLocale = LanguagesTools.getLocale(context);
// 更新 Activity 的语种
LanguagesTools.updateLanguages(context.getResources(), newLocale);
if (context != sApplication) {
// 更新 Application 的语种
LanguagesTools.updateLanguages(sApplication.getResources(), newLocale);
}
LanguagesConfig.setAppLanguage(context, newLocale);
LanguagesConfig.setLanguageType(context, false);
if (sLanguageListener != null) {
sLanguageListener.onAppLocaleChange(oldLocale, newLocale);
}
// 需要重启
return true;
}
/**
* 获取系统的语种
*/
public static Locale getSystemLanguage() {
return LanguagesObserver.getSystemLanguage();
}
/**
* 将 App 语种设置为系统语种
*/
public static boolean setSystemLanguage(Context context) {
LanguagesConfig.clearLanguage(context);
LanguagesConfig.setLanguageType(context, true);
if (!LanguagesTools.getLocale(context).equals(getSystemLanguage())) {
LanguagesTools.updateLanguages(context.getResources(), getSystemLanguage());
if (context != sApplication) {
// 更新 Application 的语种
LanguagesTools.updateLanguages(sApplication.getResources(), getSystemLanguage());
}
// 需要重启
return true;
}
// 不需要重启
return false;
}
/**
* 对比两个语言是否是同一个语种(比如:中文的简体和繁体,英语的美式和英式)
*/
public static boolean equalsLanguage(Locale locale1, Locale locale2) {
return locale1.getLanguage().equals(locale2.getLanguage());
}
/**
* 对比两个语言是否是同一个地方的(比如:中国大陆用的中文简体,中国台湾用的中文繁体)
*/
public static boolean equalsCountry(Locale locale1, Locale locale2) {
return equalsLanguage(locale1, locale2) && locale1.getCountry().equals(locale2.getCountry());
}
/**
* 获取某个语种下的 String
*/
public static String getLanguageString(Context context, Locale locale, int id) {
return getLanguageResources(context, locale).getString(id);
}
/**
* 获取某个语种下的 Resources 对象
*/
public static Resources getLanguageResources(Context context, Locale locale) {
return LanguagesTools.getLanguageResources(context, locale);
}
/**
* 设置语种变化监听器
*/
public static void setOnLanguageListener(OnLanguageListener listener) {
sLanguageListener = listener;
}
static OnLanguageListener getOnLanguagesListener() {
return sLanguageListener;
}
/**
* 设置保存的 SharedPreferences 文件名
*/
public static void setSharedPreferencesName(String name) {
LanguagesConfig.setSharedPreferencesName(name);
}
}
OnLanguageListener.java
package com.oplayer.language;
import java.util.Locale;
/**
* author : Android 轮子哥
* github : https://github.com/getActivity/MultiLanguages
* time : 2021/01/18
* desc : 语种变化监听器
*/
public interface OnLanguageListener {
/**
* 当前应用语种发生变化时回调
*
* @param oldLocale 旧语种
* @param newLocale 新语种
*/
void onAppLocaleChange(Locale oldLocale, Locale newLocale);
/**
* 手机系统语种发生变化时回调
*
* @param oldLocale 旧语种
* @param newLocale 新语种
*/
void onSystemLocaleChange(Locale oldLocale, Locale newLocale);
}
述