Browse Source

加入蓝牙监听

newdev_shunjiawei
fdp 1 year ago
parent
commit
7d5755d96d
  1. 387
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt

387
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt

@ -21,6 +21,14 @@ import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.Dispatchers
import com.yunqiinnovation.ble_service.BleConst
import com.yunqiinnovation.ble_service.BleService
// 添加蓝牙相关导入
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.content.BroadcastReceiver
import android.content.IntentFilter
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat
/**
* BLE代理服务
@ -28,6 +36,7 @@ import com.yunqiinnovation.ble_service.BleService
* 1. 语音代理初始化和管理
* 2. BLE设备连接管理
* 3. 后台扫描结果处理
* 4. 蓝牙设备连接监听
*/
class BleMediaService : Service(), CoroutineScope {
@ -37,6 +46,9 @@ class BleMediaService : Service(), CoroutineScope {
private const val NOTIFICATION_ID = 1002
private const val PREF_NAME = "deep_voice_config"
// 目标蓝牙设备名称
private const val TARGET_DEVICE_NAME = "DeapSound"
// ChatAgent配置参数键
private const val KEY_AZURE_SPEECH_KEY = "azureSpeechKey"
private const val KEY_AZURE_SPEECH_REGION = "azureSpeechRegion"
@ -75,6 +87,301 @@ class BleMediaService : Service(), CoroutineScope {
// 当前启动Intent
private var currentIntent: Intent? = null
// 蓝牙相关组件
private var bluetoothAdapter: BluetoothAdapter? = null
private var bluetoothReceiver: BroadcastReceiver? = null
// 添加标志位跟踪广播接收器注册状态
private var isBluetoothReceiverRegistered = false
// 添加定期检查蓝牙状态的协程作业
private var bluetoothCheckJob: kotlinx.coroutines.Job? = null
/**
* 蓝牙设备连接状态广播接收器
* 监听蓝牙设备的连接和断开事件
*/
private fun createBluetoothReceiver(): BroadcastReceiver {
return object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
BluetoothDevice.ACTION_ACL_CONNECTED -> {
val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
device?.let { handleDeviceConnected(it) }
}
BluetoothDevice.ACTION_ACL_DISCONNECTED -> {
val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
device?.let { handleDeviceDisconnected(it) }
}
BluetoothAdapter.ACTION_STATE_CHANGED -> {
val state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
handleBluetoothStateChanged(state)
}
}
}
}
}
/**
* 处理蓝牙设备连接事件
* @param device 连接的蓝牙设备
*/
private fun handleDeviceConnected(device: BluetoothDevice) {
val deviceName = device.name ?: "Unknown"
val deviceAddress = device.address ?: "Unknown"
Log.i(TAG, "蓝牙设备已连接: $deviceName ($deviceAddress)")
// 检查是否是目标设备
if (deviceName.equals(TARGET_DEVICE_NAME, ignoreCase = true)) {
Log.i(TAG, "检测到目标设备 '$TARGET_DEVICE_NAME' 连接!")
Log.i(TAG, "设备信息:")
Log.i(TAG, " - 设备名称: $deviceName")
Log.i(TAG, " - 设备地址: $deviceAddress")
Log.i(TAG, " - 设备类型: ${getDeviceTypeString(device.type)}")
Log.i(TAG, " - 绑定状态: ${getBondStateString(device.bondState)}")
// 可以在这里添加更多的处理逻辑,比如自动连接BLE服务等
onTargetDeviceConnected(device)
}
}
/**
* 处理蓝牙设备断开事件
* @param device 断开的蓝牙设备
*/
private fun handleDeviceDisconnected(device: BluetoothDevice) {
val deviceName = device.name ?: "Unknown"
val deviceAddress = device.address ?: "Unknown"
Log.i(TAG, "蓝牙设备已断开: $deviceName ($deviceAddress)")
if (deviceName.equals(TARGET_DEVICE_NAME, ignoreCase = true)) {
Log.i(TAG, "目标设备 '$TARGET_DEVICE_NAME' 已断开连接")
onTargetDeviceDisconnected(device)
}
}
/**
* 处理蓝牙适配器状态变化
* @param state 蓝牙适配器状态
*/
private fun handleBluetoothStateChanged(state: Int) {
when (state) {
BluetoothAdapter.STATE_OFF -> {
Log.w(TAG, "蓝牙已关闭")
// 蓝牙关闭时,注销设备连接监听器(保留状态监听器)
unregisterDeviceConnectionReceiver()
}
BluetoothAdapter.STATE_ON -> {
Log.i(TAG, "蓝牙已开启")
// 蓝牙开启后,重新注册设备连接监听器
registerDeviceConnectionReceiver()
// 检查已连接的设备
checkAlreadyConnectedDevices()
}
BluetoothAdapter.STATE_TURNING_OFF -> {
Log.i(TAG, "蓝牙正在关闭...")
}
BluetoothAdapter.STATE_TURNING_ON -> {
Log.i(TAG, "蓝牙正在开启...")
}
}
}
/**
* 目标设备连接时的处理逻辑
* @param device 连接的目标设备
*/
private fun onTargetDeviceConnected(device: BluetoothDevice) {
// 在这里可以添加目标设备连接后的特殊处理逻辑
// 比如自动启动某些功能、发送通知等
Log.i(TAG, "目标设备 '${device.name}' 连接成功,执行相关处理逻辑")
}
/**
* 目标设备断开时的处理逻辑
* @param device 断开的目标设备
*/
private fun onTargetDeviceDisconnected(device: BluetoothDevice) {
// 在这里可以添加目标设备断开后的处理逻辑
Log.i(TAG, "目标设备 '${device.name}' 断开连接,执行清理逻辑")
}
/**
* 获取设备类型字符串
* @param type 设备类型
* @return 设备类型描述
*/
private fun getDeviceTypeString(type: Int): String {
return when (type) {
BluetoothDevice.DEVICE_TYPE_CLASSIC -> "经典蓝牙"
BluetoothDevice.DEVICE_TYPE_LE -> "低功耗蓝牙(BLE)"
BluetoothDevice.DEVICE_TYPE_DUAL -> "双模蓝牙"
else -> "未知类型"
}
}
/**
* 获取绑定状态字符串
* @param bondState 绑定状态
* @return 绑定状态描述
*/
private fun getBondStateString(bondState: Int): String {
return when (bondState) {
BluetoothDevice.BOND_NONE -> "未绑定"
BluetoothDevice.BOND_BONDING -> "正在绑定"
BluetoothDevice.BOND_BONDED -> "已绑定"
else -> "未知状态"
}
}
/**
* 检查已连接的蓝牙设备
* 在服务启动或蓝牙开启时调用,检查是否有目标设备已经连接
*/
private fun checkAlreadyConnectedDevices() {
try {
bluetoothAdapter?.let { adapter ->
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT)
== PackageManager.PERMISSION_GRANTED) {
val bondedDevices = adapter.bondedDevices
Log.i(TAG, "检查已绑定的设备数量: ${bondedDevices?.size ?: 0}")
bondedDevices?.forEach { device ->
val deviceName = device.name ?: "Unknown"
Log.d(TAG, "已绑定设备: $deviceName (${device.address})")
if (deviceName.equals(TARGET_DEVICE_NAME, ignoreCase = true)) {
Log.i(TAG, "发现已绑定的目标设备: $deviceName")
// 注意:这里只能检查绑定状态,无法直接判断连接状态
// 实际连接状态需要通过广播接收器监听
}
}
} else {
Log.w(TAG, "缺少蓝牙连接权限,无法检查已连接设备")
}
}
} catch (e: Exception) {
Log.e(TAG, "检查已连接设备时发生异常", e)
}
}
/**
* 初始化蓝牙监听器
* 设置蓝牙适配器和注册广播接收器
*/
private fun initializeBluetoothListener() {
try {
// 获取蓝牙管理器和适配器
val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as? BluetoothManager
bluetoothAdapter = bluetoothManager?.adapter
if (bluetoothAdapter == null) {
Log.w(TAG, "设备不支持蓝牙功能")
return
}
// 创建蓝牙广播接收器
if (bluetoothReceiver == null) {
bluetoothReceiver = createBluetoothReceiver()
}
// 首先注册蓝牙状态变化监听器(始终保持注册)
registerBluetoothStateReceiver()
// 如果蓝牙已开启,注册设备连接监听器
if (bluetoothAdapter!!.isEnabled) {
Log.i(TAG, "蓝牙已开启,注册设备连接监听器")
registerDeviceConnectionReceiver()
// 检查已连接的设备
checkAlreadyConnectedDevices()
} else {
Log.w(TAG, "蓝牙未开启,仅注册状态监听器")
}
} catch (e: Exception) {
Log.e(TAG, "初始化蓝牙监听器时发生异常", e)
}
}
/**
* 注册蓝牙状态变化监听器
* 这个监听器始终保持注册状态,用于监听蓝牙开关状态
*/
private fun registerBluetoothStateReceiver() {
try {
if (!isBluetoothReceiverRegistered && bluetoothReceiver != null) {
val stateFilter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
registerReceiver(bluetoothReceiver, stateFilter)
isBluetoothReceiverRegistered = true
Log.i(TAG, "蓝牙状态监听器注册成功")
}
} catch (e: Exception) {
Log.e(TAG, "注册蓝牙状态监听器时发生异常", e)
}
}
/**
* 注册设备连接监听器
* 仅在蓝牙开启时注册,用于监听设备连接和断开事件
*/
private fun registerDeviceConnectionReceiver() {
try {
if (isBluetoothReceiverRegistered && bluetoothReceiver != null) {
// 先注销现有的接收器
unregisterReceiver(bluetoothReceiver!!)
// 重新注册包含所有事件的接收器
val fullFilter = IntentFilter().apply {
addAction(BluetoothDevice.ACTION_ACL_CONNECTED)
addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
addAction(BluetoothAdapter.ACTION_STATE_CHANGED)
}
registerReceiver(bluetoothReceiver, fullFilter)
Log.i(TAG, "设备连接监听器注册成功")
}
} catch (e: Exception) {
Log.e(TAG, "注册设备连接监听器时发生异常", e)
}
}
/**
* 注销设备连接监听器
* 蓝牙关闭时调用,但保留状态监听器
*/
private fun unregisterDeviceConnectionReceiver() {
try {
if (isBluetoothReceiverRegistered && bluetoothReceiver != null) {
// 注销当前接收器
unregisterReceiver(bluetoothReceiver!!)
// 重新注册仅包含状态变化的接收器
val stateFilter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
registerReceiver(bluetoothReceiver, stateFilter)
Log.i(TAG, "设备连接监听器已注销,保留状态监听器")
}
} catch (e: Exception) {
Log.e(TAG, "注销设备连接监听器时发生异常", e)
}
}
/**
* 完全注销蓝牙广播接收器
* 仅在服务销毁时调用
*/
private fun unregisterBluetoothReceiver() {
try {
if (isBluetoothReceiverRegistered && bluetoothReceiver != null) {
unregisterReceiver(bluetoothReceiver!!)
isBluetoothReceiverRegistered = false
Log.i(TAG, "蓝牙广播接收器已完全注销")
}
} catch (e: Exception) {
Log.e(TAG, "注销蓝牙广播接收器时发生异常", e)
}
}
override fun onCreate() {
super.onCreate()
@ -84,9 +391,77 @@ class BleMediaService : Service(), CoroutineScope {
isRunning.set(true)
startForeground(NOTIFICATION_ID, createNotification())
// 初始化蓝牙监听器
initializeBluetoothListener()
// 启动定期蓝牙状态检查
startBluetoothStatusCheck()
Log.i(TAG, "BLE代理服务已启动")
}
/**
* 启动定期蓝牙状态检查
* 每30秒检查一次蓝牙状态,确保监听器正常工作
*/
private fun startBluetoothStatusCheck() {
bluetoothCheckJob = launch {
while (isRunning.get()) {
try {
kotlinx.coroutines.delay(30000) // 30秒检查一次
checkAndRestoreBluetoothListener()
} catch (e: Exception) {
Log.e(TAG, "蓝牙状态检查时发生异常", e)
}
}
}
Log.i(TAG, "蓝牙状态定期检查已启动")
}
/**
* 检查并恢复蓝牙监听器
* 确保在蓝牙开启时监听器正常工作
*/
private fun checkAndRestoreBluetoothListener() {
try {
bluetoothAdapter?.let { adapter ->
val isBluetoothEnabled = adapter.isEnabled
Log.d(TAG, "蓝牙状态检查: 蓝牙${if (isBluetoothEnabled) "已开启" else "已关闭"}, 接收器${if (isBluetoothReceiverRegistered) "已注册" else "未注册"}")
if (isBluetoothEnabled && isBluetoothReceiverRegistered) {
// 蓝牙开启且接收器已注册,检查是否需要重新注册设备连接监听器
// 这里可以通过尝试获取当前注册的IntentFilter来判断
// 但Android没有直接的API,所以我们采用重新注册的方式确保监听器有效
Log.d(TAG, "重新确认设备连接监听器注册状态")
registerDeviceConnectionReceiver()
} else if (isBluetoothEnabled && !isBluetoothReceiverRegistered) {
// 蓝牙开启但接收器未注册,重新初始化
Log.w(TAG, "检测到蓝牙已开启但监听器未注册,重新初始化")
initializeBluetoothListener()
} else if (!isBluetoothEnabled && isBluetoothReceiverRegistered) {
// 蓝牙关闭但接收器仍注册,保持状态监听器
Log.d(TAG, "蓝牙已关闭,确保仅保留状态监听器")
unregisterDeviceConnectionReceiver()
}
} ?: run {
// 蓝牙适配器为空,重新初始化
Log.w(TAG, "蓝牙适配器为空,重新初始化监听器")
initializeBluetoothListener()
}
} catch (e: Exception) {
Log.e(TAG, "检查和恢复蓝牙监听器时发生异常", e)
}
}
/**
* 停止蓝牙状态检查
*/
private fun stopBluetoothStatusCheck() {
bluetoothCheckJob?.cancel()
bluetoothCheckJob = null
Log.i(TAG, "蓝牙状态定期检查已停止")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.i(TAG, "BleAgentService.onStartCommand: ${intent?.action}")
@ -269,6 +644,14 @@ class BleMediaService : Service(), CoroutineScope {
override fun onDestroy() {
Log.i(TAG, "BLE代理服务正在销毁...")
// 停止蓝牙状态检查
stopBluetoothStatusCheck()
// 完全注销蓝牙广播接收器
unregisterBluetoothReceiver()
bluetoothReceiver = null
bluetoothAdapter = null
// 取消所有协程
cancel()
@ -335,4 +718,4 @@ class BleMediaService : Service(), CoroutineScope {
return builder.build()
}
}
}
Loading…
Cancel
Save