Android中监听语言变化的两种方式
来源:互联网 发布:matlab 三维矩阵 画图 编辑:程序博客网 时间:2024/06/05 17:50
Android中监听语言变化的方式有两种,通过在Activity里配置configChanges,然后重写onConfigurationChanged方法,另一种方式通过注册广播监听LOCALE_CHANGED,下面就来看下,这两种方式以及遇到的一些问题。
1.在Activity里配置configChanges
1.1 在对应Activity里添加configChanges配置
<activity android:name=".MainActivity" android:configChanges="locale|layoutDirection" android:exported="true" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>在配置android:configChanges时,开始只配置了locale,发现改变语言时当app处于后台,并没有finish时,并不会在resume时调用Activity重写的onConfigurationChanged函数。原来是因为Android 4.2增加了layoutDirection属性,当改变语言设置后,该属性也会成newConfig中的一个mask位,所以ActivityManagerService(实际在ActivityStack)在决定是否重启Activity的时候总是判断为重启,所以在android:configChanges 中同时添加locale和layoutDirection时,才会在resume时调用Activity重写的onConfigurationChanged函数
1.2 Activity里重写onConfigurationChanged函数
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Toast.makeText(this,"onConfigurationChanged language change "+newConfig.locale.toString(),Toast.LENGTH_SHORT).show(); Log.d("jason","onConfigurationChanged newConfig:"+newConfig.toString()); }
上面的步骤就可以了吗,其实不然,还有件重要事情没干,在清单文件中添加下面权限:
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>
另外附上android:configChanges 可选值
任何或所有下列字符串均是该属性的有效值。多个值使用“|
”分隔 — 例如,“locale|navigation|orientation
”。
mcc
”IMSI 移动国家/地区代码 (MCC) 发生了变化 - 检测到了 SIM 并更新了 MCC。“mnc
”IMSI 移动网络代码 (MNC) 发生了变化 - 检测到了 SIM 并更新了 MNC。“locale
”语言区域发生了变化 — 用户为文本选择了新的显示语言。“touchscreen
”触摸屏发生了变化。(这种情况通常永远不会发生。)“keyboard
”键盘类型发生了变化 — 例如,用户插入了一个外置键盘。“keyboardHidden
”键盘无障碍功能发生了变化 — 例如,用户显示了硬件键盘。“navigation
”导航类型(轨迹球/方向键)发生了变化。(这种情况通常永远不会发生。)“screenLayout
”屏幕布局发生了变化 — 这可能是由激活了其他显示方式所致。“fontScale
”字体缩放系数发生了变化 — 用户选择了新的全局字号。“uiMode
”用户界面模式发生了变化 — 这可能是因用户将设备放入桌面/车载基座或夜间模式发生变化所致。 请参阅 UiModeManager
。 此项为 API 级别 8 中新增配置。“orientation
”屏幕方向发生了变化 — 用户旋转了设备。注:如果您的应用面向 API 级别 13 或更高级别(按照 minSdkVersion
和 targetSdkVersion
属性所声明的级别),则还应声明 "screenSize"
配置,因为当设备在横向与纵向之间切换时,该配置也会发生变化。
screenSize
”当前可用屏幕尺寸发生了变化。它表示当前可用尺寸相对于当前纵横比的变化,因此会在用户在横向与纵向之间切换时发生变化。 不过,如果您的应用面向 API 级别 12 或更低级别,则 Activity 始终会自行处理此配置变更(即便是在 Android 3.2 或更高版本的设备上运行,此配置变更也不会重新启动 Activity)。此项为 API 级别 13 中新增配置。
“smallestScreenSize
”物理屏幕尺寸发生了变化。它表示与方向无关的尺寸变化,因此只有在实际物理屏幕尺寸发生变化(如切换到外部显示器)时才会变化。 对此配置的变更对应于smallestWidth 配置的变化。 不过,如果您的应用面向 API 级别 12 或更低级别,则 Activity 始终会自行处理此配置变更(即便是在 Android 3.2 或更高版本的设备上运行,此配置变更也不会重新启动 Activity)。此项为 API 级别 13 中新增配置。
“layoutDirection
”布局方向发生了变化。例如,从从左至右 (LTR) 更改为从右至左 (RTL)。 此项为 API 级别 17 中新增配置。2.利用BroadcastReceiver注册监听语言切换的广播
自定义LanguageReceiver,在AndroidManifest注册如下:
<receiver android:name=".LanguageReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="1000"> <action android:name="android.intent.action.LOCALE_CHANGED"/> </intent-filter> </receiver>
上面在receiver节点里有android:enabled和android:exported,下面分别看看这两个啥意思
android:enabled 系统是否可将其实例化 — "true" 表示可以,“false”表示不可以。 默认值为“true”。
android:exported 是否可由其他应用的组件启动 —“true”表示可以,“false”表示不可以。若为“false”,则只能由同一应用的组件或使用同一用户 ID 的不同应用启动。
默认值取决于 Receiver 是否包含 Intent 过滤器,没有任何过滤器,默认值为“false”,反之默认值为“true”。
android:exported 是否可由其他应用的组件启动 —“true”表示可以,“false”表示不可以。若为“false”,则只能由同一应用的组件或使用同一用户 ID 的不同应用启动。
默认值取决于 Receiver 是否包含 Intent 过滤器,没有任何过滤器,默认值为“false”,反之默认值为“true”。
当语言切换后,LanguageReceiver@onReceive方法会被调用
public class LanguageReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO: This method is called when the BroadcastReceiver is receiving // an Intent broadcast. Log.d("jason", " LanguageReceiver onReceive"); Toast.makeText(context,"LanguageReceiveronReceive ",Toast.LENGTH_SHORT).show(); }}
上面的广播的是哪发出的呢,忍不住跟踪了一把,最后发现是在ActivityManagerService.java发出来
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean initLocale, boolean persistent, int userId, boolean deferResume) { ... if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { intent = new Intent(Intent.ACTION_LOCALE_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); if (initLocale || !mProcessesReady) { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } ...}
阅读全文
0 0
- Android中监听语言变化的两种方式
- 监听EditText内容变化的两种方式
- 监听UITextField内容变化的两种方式
- (转)监听EditText内容变化的两种方式
- android事件监听的两种方式
- Android在web view中监听屏幕双击的两种方式onClick与onTouch
- Android 监听ContentProvider中数据的变化
- 监听Android中ContentProvider内容的变化
- Android 监听ContentProvider中数据的变化
- Android 监听ContentProvider中数据的变化
- Android 监听ContentProvider中数据的变化
- Android 监听系统语言变化
- Android手机上监听短信的两种方式
- Android手机上监听短信的两种方式
- Android手机上监听短信的两种方式
- Android手机上监听短信的两种方式
- Android手机上监听短信的两种方式
- Android手机上监听短信的两种方式
- codeforces 165-C. Another Problem on Strings(计数+尺取)
- php利用curl实现多进程下载文件类
- 第21篇 oracle的卸载
- 字符设备驱动高级篇2——字符设备驱动注册代码分析
- MyBatis一级缓存,二级缓存
- Android中监听语言变化的两种方式
- 面向对象的六大原则
- Codeforces 492A
- 打包配置问题
- UVA-253-骰子涂色
- 创建第一个Django项目(一)
- 【机器学习】卷积神经网络(CNN)架构解析
- 新手上路之oracle 92 99 表连接(笔记)
- 栈的应用:左右符号匹配