解决方案之Android 国际化资源完美兼容6.0,7.0,8.0

解决方案之Android 国际化资源完美兼容6.0,7.0,8.0

在Android世界中,一般App应用的语言是根据Android系统显示的语言变化的,但是有时候有些应用需要单独设置App的显示语言。

Android 国际化实现

国际化一般最常用的是支持简体中文和美式英文。
思路:

  1. 切换Project视图
  2. 创建多个国家的资源文件夹
  3. 调用语言切换工具类(获取string.xml 通过Resource对象,然后更新)
  4. 在Application启动的时候加载修改语言方法
  5. 创建一个Activity基类,方便随时随地重启和替换掉所有界面的Context

1. 首先需要将项目切换到Project 视图(必要)

2. 建立资源文件夹(必要)

比如国际化需要支持简体中文和美式英语,需要这三个string.xml

  • values 默认的字符串资源文件,必须有
  • values-zh-rCN 简体中文字符串资源文件
  • values-en-rUS 美式英语字符串资源文件


格式规范: values-语言代码-r国家代码
例如:values-zh-rCN(中文)和values-en-rUS(英文)

这里可以考虑使用一些辅助工具:
国家_地区语言速查表

手动创建

  1. 选中res 文件夹右键,New ——> Android Resource Directory
  2. 选中Locale

    3.选择要支持的资源文件夹

比如中文中国

选择英文美式

3. 中文和英文切换调用方法(必要)

MainActivity.java

  /*** App 语言切换成英文**/private void appLanguageSwitchToEnglish() {Locale locale=new Locale("en","US");//强制修改成英文LanguageUtil.changeAppLanguage(locale, true);//English 点击后按钮文字修改为简体中文loginPageSwitchLanguageButton.setText(getString(R.string.login_page_switch_language_Chinese_language));ToastTools.showLong(MyApplication.getContext(),"Current App Language Have Switch To English");//重启ApprestartApplication();}/*** App语言切换成中文*/private void appLanguageSwitchToChinese() {Locale chineseLocale=new Locale("zh","CN");//强制切换成中文简体LanguageUtil.changeAppLanguage(chineseLocale, true);loginPageSwitchLanguageButton.setText(getString(R.string.login_page_switch_language_English_language));loginPageSwitchLanguageButton.invalidate();ToastTools.showLong(MyApplication.getContext(),"当前App语言已切换为简体中文");//重启应用restartApplication();}

4.语言切换工具类(必要)

LanguageUtil.java

public class LanguageUtil {public static Context appContext=MyApplication.getContext();/*** 更改应用语言* @param locale 语言地区* @param persistence 是否持久化*/public static void changeAppLanguage(Locale locale, boolean persistence) {//获取应用程序的所有资源对象Resources resources = MyApplication.getContext().getResources();//获取屏幕参数DisplayMetrics metrics = resources.getDisplayMetrics();//获取设置对象Configuration configuration = resources.getConfiguration();//如果API < 17if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {configuration.locale = locale;appContext= MyApplication.getContext();} else //如果 17 < = API < 25 Android 7.7.1if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N_MR1){configuration.setLocale(locale);appContext=MyApplication.getContext();}else{//API 25  Android 7.7.1configuration.setLocale(locale);configuration.setLocales(new LocaleList(locale));appContext=MyApplication.getContext().createConfigurationContext(configuration);}//更新配置信息resources.updateConfiguration(configuration, metrics);//持久化if (persistence) {SharePreferencesTools.saveObjectToSharePreferences(MyApplication.getContext(), LanguageSwitchConstant.LANGUA_SWITCH_FILE_NAME, LanguageSwitchConstant.LANGUA_SWITCH_SELECTED_KEY,locale);}}/*** 获取App当前语言* 如果存过信息那么以存的信息为准否则取系统的配置信息为准* @Return Locale* **/public static Locale getAppLocale() {//读取本地配置文件信息Locale currentAppLocale=null;currentAppLocale=(Locale) SharePreferencesTools.readObjectFromSharePreferences(MyApplication.getContext(),LanguageSwitchConstant.LANGUA_SWITCH_FILE_NAME,LanguageSwitchConstant.LANGUA_SWITCH_SELECTED_KEY);if(currentAppLocale==null){currentAppLocale=getSystemLocale();}return currentAppLocale;}/******* 获取当前系统语言*/public static Locale getSystemLocale(){Locale currentSystemLocale;//API >= 24if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {currentSystemLocale = Resources.getSystem().getConfiguration().getLocales().get(0);} else {currentSystemLocale = Resources.getSystem().getConfiguration().locale;}return currentSystemLocale;}
}

其中静态常量类配置内容如下:

public class LanguageSwitchConstant {public final static String LANGUA_SWITCH_FILE_NAME="language_switch_config";public final static String LANGUA_SWITCH_SELECTED_KEY="language_switch_selected_key";
}

5. MyApplication中调用(必要)

MyApplication.java

public class MyApplication extends Application {/**** 系统上下文*/private static Context context;@Overridepublic void onCreate() {super.onCreate();context=getApplicationContext();Locale currentAppLocale=LanguageUtil.getAppLocale();LanguageUtil.changeAppLanguage(currentAppLocale,false);}public static Context getContext(){return context;}
}

6. BaseActivity替换所有的Context

SmartBaseActivity.java

public class SmartBaseActivity extends AppCompatActivity{@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);}/**** 重启应用程序* */protected void restartApplication() {final Intent intent = MyApplication.getContext().getPackageManager().getLaunchIntentForPackage(getPackageName());intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);startActivity(intent);}@Overrideprotected void attachBaseContext(Context newBase) {super.attachBaseContext(LanguageUtil.appContext);}
}

7. SharePreferencesTools 保存国际化状态(必要)

SharePreferencesTools.java

public class SharePreferencesTools {/*** 方法描述: SharePreferences 保存对象* 调用方法SharePreferencesSaveObject(Context context,String fileName,String key ,Object obj);* @param context  上下文对象* @param fileName SharePreference 文件名称* @param key Key* @param obj 要保存的对象* @return void* *//*******************SharePreferences 保存对象 *****************************/public static void saveObjectToSharePreferences(Context context, String fileName, String key, Object obj){try {// 保存对象SharedPreferences.Editor sharedata = context.getSharedPreferences(fileName,0).edit();//先将序列化结果写到byte缓存中,其实就分配一个内存空间ByteArrayOutputStream bos=new ByteArrayOutputStream();ObjectOutputStream os=new ObjectOutputStream(bos);//将对象序列化写入byte缓存os.writeObject(obj);//将序列化的数据转为16进制保存String bytesToHexString = bytesToHexString(bos.toByteArray());//保存该16进制数组sharedata.putString(key, bytesToHexString);sharedata.commit();} catch (IOException e) {e.printStackTrace();SmartLogUtils.debugInformation("保存Obj失败"+e.toString(),true);}}/*** desc:将数组转为16进制* @param bArray* @return String*/private static String bytesToHexString(byte[] bArray) {if(bArray == null){return null;}if(bArray.length == 0){return "";}StringBuffer sb = new StringBuffer(bArray.length);String sTemp;for (int i = 0; i < bArray.length; i++) {sTemp = Integer.toHexString(0xFF & bArray[i]);if (sTemp.length() < 2)sb.append(0);sb.append(sTemp.toUpperCase());}return sb.toString();}/*******************SharePreferences 保存对象 *****************************//*** 方法描述: 获取SharePreferences保存的Object对象* 调用方法     Object obj= readSharePreferencesObject(Context context,String fileName,String key );* @param context  上下文对象* @param filename 读取文件名* @param key* @return 异常返回null,成功返回该对象*//*******************读取 SharePreferences 保存对象 *****************************/public static Object readObjectFromSharePreferences(Context context,String fileName,String key ){try {SharedPreferences sharedata = context.getSharedPreferences(fileName, 0);if (sharedata.contains(key)) {String string = sharedata.getString(key,"");if(TextUtils.isEmpty(string)){return null;}else{//将16进制的数据转为数组,准备反序列化byte[] stringToBytes = StringToBytes(string);ByteArrayInputStream bis=new ByteArrayInputStream(stringToBytes);ObjectInputStream is=new ObjectInputStream(bis);//返回反序列化得到的对象Object readObject = is.readObject();return readObject;}}} catch (StreamCorruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}//所有异常返回nullreturn null;}/*** desc:将16进制的数据转为数组* @param  data* @return*/private static byte[] StringToBytes(String data){String hexString=data.toUpperCase().trim();if (hexString.length()%2!=0) {return null;}byte[] retData=new byte[hexString.length()/2];for(int i=0;i<hexString.length();i++){int int_ch;  // 两位16进制数转化后的10进制数char hex_char1 = hexString.charAt(i); 两位16进制数中的第一位(高位*16)int int_ch1;if(hex_char1 >= '0' && hex_char1 <='9')int_ch1 = (hex_char1-48)*16;    0 的Ascll - 48else if(hex_char1 >= 'A' && hex_char1 <='F')int_ch1 = (hex_char1-55)*16;  A 的Ascll - 65elsereturn null;i++;char hex_char2 = hexString.charAt(i); ///两位16进制数中的第二位(低位)int int_ch2;if(hex_char2 >= '0' && hex_char2 <='9')int_ch2 = (hex_char2-48);  0 的Ascll - 48else if(hex_char2 >= 'A' && hex_char2 <='F')int_ch2 = hex_char2-55;  A 的Ascll - 65elsereturn null;int_ch = int_ch1+int_ch2;retData[i/2]=(byte) int_ch;//将转化后的数放入Byte里}return retData;}/*******************读取 SharePreferences 保存对象 *****************************/
}

8. 吐司工具类 (非必须)

/*** Toast 弹出信息工具类,简化代码编写* @author fairy* */
public class SmartToastUtils{public static void showLong(String info) {Toast.makeText(MyApplication.getContext(),info, Toast.LENGTH_LONG).show();}public static void showShort(String info) {Toast.makeText(MyApplication.getContext(),info,Toast.LENGTH_SHORT).show();}
}

9. 日志工具类(非必要)

public class SmartLogUtils {/**** 封装日志打印方法* @param  message 打印的消息* @param  showMessage 是否显示打印的消息* **/public static void debugInformation(String message,Boolean showMessage){if(showMessage){int max_str_length = 2001 - DebugConstant.DEBUG_TAG.length();//大于4000时while (message.length() > max_str_length) {Log.e(DebugConstant.DEBUG_TAG, message.substring(0, max_str_length));message = message.substring(max_str_length);}//剩余部分Log.e(DebugConstant.DEBUG_TAG,message);}}private final static String DEBUG_TAG="xingyun";/**** 封装日志打印方法* @param  message 打印的消息* @param  showMessage 是否显示打印的消息* **/public static void showInfo(String message,Boolean showMessage){if(showMessage){int max_str_length = 2001 - DEBUG_TAG.length();//大于4000时while (message.length() > max_str_length) {Log.i(DEBUG_TAG, message.substring(0, max_str_length));message = message.substring(max_str_length);}//剩余部分Log.i(DEBUG_TAG,message);}}/**** 封装日志打印方法* @param  message 打印的消息* @param  showMessage 是否显示打印的消息* **/public static void showDebug(String message,Boolean showMessage){if(showMessage){int max_str_length = 2001 - DEBUG_TAG.length();//大于4000时while (message.length() > max_str_length) {Log.d(DEBUG_TAG, message.substring(0, max_str_length));message = message.substring(max_str_length);}//剩余部分Log.d(DEBUG_TAG,message);}}public static void showError(String message,Boolean showMessage){if(showMessage){int max_str_length = 2001 - DEBUG_TAG.length();//大于4000时while (message.length() > max_str_length) {Log.e(DEBUG_TAG, message.substring(0, max_str_length));message = message.substring(max_str_length);}//剩余部分Log.e(DEBUG_TAG,message);}}
}

本篇完~
如有疑问欢迎留言~

发布者:admin,转转请注明出处:http://www.yc00.com/news/1689148200a213119.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信