最近公司项目销售到了澳门,文字要适配繁体,语音播报要适配粤语,于是就有了国际化需求。主要有 文字、布局、语音 四个方面的适配。本文基于Android Studio开发。
文字适配:文字随系统语言变化而变化,文字适配搜索的话一堆文章,但是能把步骤写清楚的很少,我尽量把步骤写详细点。
1.将项目切换到Project模式。
2.找到项目/src/res目录,选中,右键New/Android Resource File,选中,出现弹框,适配文字,File Name填-strings,最下方Available qualifiers选中Locale,选中后找你需要适配的国家和地区,若没找到你适配的国家和地区,直接在Directory name中输入也一样,点击OK。(英文:en,中文简体:zh-rCN,中文繁体:香港zh-rHK、澳门zh-rMO、台湾zh-rTW,其余的自己找吧)
3.可以看到res下生成了你选中国家地区的values文件,如values-en,values-rMO,如果是简体换繁体,直接将简体strings文件内容复制到word文档中,直接选择简转繁就可将简体转为繁体,以WPS为例,选中审阅-简转繁,自己读下转完的文字,如果读不通建议到 在线简转繁网站上再翻译一次。
4.填好适配的文字。
5.注册广播,监听系统语言。
private class LoacleChanged extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //判断是否修改系统语言返回 if (Objects.equals(intent.getAction(), Intent.ACTION_LOCALE_CHANGED)) { //根据系统语言进行某些切换操作 if(getResources().getConfiguration().locale.getCountry().equalsIgnoreCase("US") { }else { } } } }
6.运行demo,修改系统语言就行
问题:
1.系统语言刷新后,在Application中获取的文字不会自动刷新,需要在监听系统语言修改的方法李,增加刷新Application文字的方法。
2.若适配了英文,它的字符长度和中文是不一样的,可能一个布局显示中文很合适,英文的话布局就不适合了,由此我们接下来进行布局适配。
布局适配:和strings文件一样,发现哪个布局不对劲,先找到那个布局,按照文字适配的步骤1、2,找到Android Resource File界面,你如果要修改layout,Resource type 选择layout,File name 填layout名称,选择地区点击OK,res会生成layout-XX文件夹。
如果本身有些style控制布局,可以不动layout,生成不同的styles适配。
总结:Android Resource File 弹窗的Resource type的选项对应了res下想要生成国际化的文件夹,File Name是想要生成的具体文件,Directory name是想要适配的国家城市。
语音适配:公司项目有语音播报功能,澳门地区应播报粤语,音量随系统音量变化而变化。
1.用的讯飞语音,新增个广东话播报,LoacleChanged 中判断系统语言,切换语音;
2.注册广播,监听系统音量;
/** * 监听系统音量 */ class SettingContentObserver(val context: Context, handler:Handler):ContentObserver (handler){ override fun deliverSelfNotifications(): Boolean { return super.deliverSelfNotifications() } override fun onChange(selfChange: Boolean) { super.onChange(selfChange) VoiceSpeak.setVoiceVolume(context) } }
//系统音量utils object VolumeUtils { lateinit var settingContentObserver:SettingContentObserver @JvmStatic @Synchronized fun registerVolumeChangeReceiver(context: Context){ settingContentObserver = SettingContentObserver(context, Handler()) context.contentResolver.registerContentObserver(android.provider.Settings.System.CONTENT_URI, true, settingContentObserver) } @JvmStatic @Synchronized fun unRegisterVolumeChangeReceiver(context: Context){ if(settingContentObserver != null){ context.contentResolver.unregisterContentObserver(settingContentObserver) } } }
object VoiceSpeak { val TAG = "VoiceSpeak" val CITY_HK = "HK" val CITY_TW = "TW" @JvmStatic val COUNTRY_US = "US" @JvmStatic @Synchronized fun speak(str:String){ GlobalScope.launch (Dispatchers.IO){ VoiceClient.speakText(str, VoiceType.SPEAK_BY_SYSTEM) Log.d(TAG,"语音播报 ${str}") } } @JvmStatic fun getCurrentLanguageVoiceName(context:Context):VoiceName{ if(context.resources.configuration.locale.country.equals(CITY_HK, ignoreCase = true) || context.resources.configuration.locale.country.equals(CITY_TW, ignoreCase = true)){ return VoiceName.XIAOMEI }else{ return VoiceName.XIAOYAN } } @JvmStatic fun setVoiceVolume(context: Context){ val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) val volume = (currentVolume/maxVolume.toFloat() *100).toInt() VoiceClient.setVolume(volume) Log.d(TAG,"当前音量: $currentVolume max:${maxVolume} 设置值:${volume}") } }
问题:之前公司用的百度语音,版本没有做限制,这次国际化选择了讯飞语音,它支持的最小版本为4.4,如果有老设备用的是4.4以下的呢?(公司的性质支持用不同的包进行块状升级,如果公司项目不支持,选择语音平台前就应考虑清楚)
多渠道打包:这个按需求来,我公司需求是分两个包:1.不修改 minSdkVersion 17,使用百度语音;2.修改 minSdkVersion 19,使用讯飞语音
步骤:
1.app的build.gradle文件下,android目录中添加代码,如下
android { //差异化打包,名字任意起 flavorDimensions 'sun' //多渠道打包 productFlavors { cantonese{ minSdkVersion 19 } ori{ minSdkVersion 17 } } }
2.引入库修改,这里只有cantonese才需要引入讯飞库,引入写法 XXXImplementation ‘XXX’
cantoneseImplementation 'com.lachesis.androidlib:voice:1.1.19'
3.代码修改,除了库之外,使用的代码也可能不一样
a.将项目切换到Project模式。
b.找到项目/app/src,选中src文件夹,右键新建文件夹,为 productFlavors里你定义的名称,以cantonese为例,新建cantonese和ori文件夹,然后新建和main目录路径相同路径的类。
c.建好文件夹后,选中BuildVariant ,会看到你多渠道的debug和release选项。
d.必须选择某个渠道才能构建某个渠道的代码,否则你会发现,选择了Cantonese时修改ori的代码会报错哦。