Android中如何通过BroadcastReceiver检测具体哪个配置属性发生变化?
问题描述
我有一个TWOSBroadcastReceiver类代码如下:
class TWOSBroadcastReceiver: BroadcastReceiver () { override fun onReceive (context: Context?, pIntent: Intent?) { when (pIntent!!.action) { Intent.ACTION_CONFIGURATION_CHANGED -> { context!!.resources.configuration.locales context.resources.configuration.uiMode context.resources.configuration.orientation } } } }
当修改系统语言、屏幕方向或主题时,都会触发相同的ACTION_CONFIGURATION_CHANGED动作,我需要识别具体是语言、方向还是主题属性发生了变化,以便执行不同的操作。请问是否需要存储之前的配置进行对比,还是有其他实现方法?
解决方案
必须存储之前的配置状态来做对比,因为ACTION_CONFIGURATION_CHANGED广播只会告知配置发生了变化,但不会直接指明具体是哪一项属性变更。具体实现可按以下步骤来:
- 存储历史配置:用
SharedPreferences或者全局单例类保存上次的Configuration关键属性值,比如语言区域(locales)、屏幕方向(orientation)、UI模式(uiMode)。 - 接收广播时对比差异:收到广播后获取当前
Configuration的属性,和存储的历史值逐一对比,定位变化项:- 对比
locales判断语言是否变更 - 对比
orientation判断屏幕方向是否变更 - 对比
uiMode的UI_MODE_NIGHT_MASK位判断明暗主题是否变更
- 对比
修改后的示例代码:
class TWOSBroadcastReceiver: BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (intent?.action == Intent.ACTION_CONFIGURATION_CHANGED && context != null) { val prefs = context.getSharedPreferences("ConfigPrefs", Context.MODE_PRIVATE) val currentConfig = context.resources.configuration // 检测语言变化 val lastLocale = prefs.getString("last_locale", currentConfig.locales[0].toLanguageTag()) val currentLocale = currentConfig.locales[0].toLanguageTag() if (lastLocale != currentLocale) { // 执行语言变更后的操作 prefs.edit().putString("last_locale", currentLocale).apply() } // 检测屏幕方向变化 val lastOrientation = prefs.getInt("last_orientation", currentConfig.orientation) if (lastOrientation != currentConfig.orientation) { // 执行屏幕方向变更后的操作 prefs.edit().putInt("last_orientation", currentConfig.orientation).apply() } // 检测明暗主题变化 val lastUiMode = prefs.getInt("last_ui_mode", currentConfig.uiMode) val currentNightMode = currentConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK val lastNightMode = lastUiMode and Configuration.UI_MODE_NIGHT_MASK if (lastNightMode != currentNightMode) { // 执行主题变更后的操作 prefs.edit().putInt("last_ui_mode", currentConfig.uiMode).apply() } } } }
注意事项
- 首次运行时历史配置为空,直接存储当前值即可,不会触发变更操作。
- 若应用支持多语言区域,需调整
locales的对比逻辑,覆盖多Locale场景。 uiMode包含多种配置项,仅对比UI_MODE_NIGHT_MASK位就能判断明暗主题变化。
内容的提问来源于stack exchange,提问作者Jatin guglani
相关产品推荐
相关产品推荐

