feat: 系统控制模块 - 硬件抽象层

新增:
- ScreenController 屏幕控制接口 + FiseScreenController 实现(ROM广播)
- NfcController NFC控制接口 + FiseNfcController 实现(sysfs读写)
- VibrationController 振动接口 + FiseVibrationController 实现(13种方案+音频)
- SystemStateMonitor 系统状态监听(电量、蓝牙状态广播)
- DeviceModule Hilt硬件抽象绑定
- 8个音频文件(res/raw/)
- AppEvent 新增4个系统状态事件

修改:
- MainActivity 注册 SystemStateMonitor
- HomeFragment 硬件验证demo(熄屏/振动/NFC/电量实时显示)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongliang
2026-04-27 13:50:25 +09:30
parent 5680613e86
commit c7ae11a574
22 changed files with 815 additions and 100 deletions

View File

@@ -0,0 +1,129 @@
package com.xiaoqu.watch.service.manager
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import com.xiaoqu.watch.event.AppEvent
import com.xiaoqu.watch.event.EventBus
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
/**
* 系统状态监听器
* 注册 BroadcastReceiver 监听电量、蓝牙状态变化,通过 EventBus 分发事件
*
* 使用方式:
* - MainActivity.onCreate 中调用 register()
* - MainActivity.onDestroy 中调用 unregister()
*/
@Singleton
class SystemStateMonitor @Inject constructor(
@ApplicationContext private val context: Context,
private val eventBus: EventBus
) {
/** 协程作用域(用于发送事件) */
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
/** 是否已注册 */
private var registered = false
/** 广播接收器 */
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
// 电量变化
Intent.ACTION_BATTERY_CHANGED -> handleBatteryChanged(intent)
// 蓝牙开关状态变化
BluetoothAdapter.ACTION_STATE_CHANGED -> handleBluetoothStateChanged(intent)
// 蓝牙设备连接
BluetoothDevice.ACTION_ACL_CONNECTED -> handleBluetoothConnected(intent)
// 蓝牙设备断开
BluetoothDevice.ACTION_ACL_DISCONNECTED -> handleBluetoothDisconnected(intent)
}
}
}
/** 注册广播监听 */
fun register() {
if (registered) return
val filter = IntentFilter().apply {
addAction(Intent.ACTION_BATTERY_CHANGED)
addAction(BluetoothAdapter.ACTION_STATE_CHANGED)
addAction(BluetoothDevice.ACTION_ACL_CONNECTED)
addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
}
context.registerReceiver(receiver, filter)
registered = true
Timber.d("系统状态监听: 已注册")
}
/** 取消注册 */
fun unregister() {
if (!registered) return
try {
context.unregisterReceiver(receiver)
} catch (e: Exception) {
Timber.w(e, "系统状态监听: 取消注册异常")
}
registered = false
Timber.d("系统状态监听: 已取消注册")
}
/** 处理电量变化广播 */
private fun handleBatteryChanged(intent: Intent) {
// 电量百分比 = level / scale * 100
val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
val scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100)
val percent = (level * 100) / scale
// 充电状态
val status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
val isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING
|| status == BatteryManager.BATTERY_STATUS_FULL
emitEvent(AppEvent.BatteryChanged(percent, isCharging))
}
/** 处理蓝牙开关状态变化 */
private fun handleBluetoothStateChanged(intent: Intent) {
val state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
val isOn = state == BluetoothAdapter.STATE_ON
Timber.d("系统状态监听: 蓝牙状态 isOn=$isOn")
emitEvent(AppEvent.BluetoothStateChanged(isOn))
}
/** 处理蓝牙设备连接 */
private fun handleBluetoothConnected(intent: Intent) {
val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
val name = device?.name ?: "未知设备"
Timber.d("系统状态监听: 蓝牙已连接 $name")
emitEvent(AppEvent.BluetoothDeviceConnected(name))
}
/** 处理蓝牙设备断开 */
private fun handleBluetoothDisconnected(intent: Intent) {
val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
val name = device?.name ?: "未知设备"
Timber.d("系统状态监听: 蓝牙已断开 $name")
emitEvent(AppEvent.BluetoothDeviceDisconnected(name))
}
/** 通过 EventBus 发送事件 */
private fun emitEvent(event: AppEvent) {
scope.launch {
eventBus.emit(event)
}
}
}