Browse Source

上传测试代码

weicu
liwei1dao 12 months ago
parent
commit
0d29920805
  1. 2
      lib/modules/pairing/controllers/pairing_controller.dart
  2. 10
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt
  3. 126
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt
  4. 3
      local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift
  5. 4
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleConst.kt
  6. 19
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt
  7. 10
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/MusicSystemFunctionHandler.kt

2
lib/modules/pairing/controllers/pairing_controller.dart

@ -9,8 +9,6 @@ import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:get_storage/get_storage.dart';
import 'package:device_info_plus/device_info_plus.dart';
import '../../../routes/app_routes.dart';
import '../../../core/utils/logger.dart';
import '/data/models/appconfig.dart';

10
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt

@ -360,7 +360,7 @@ object AgentService : CoroutineScope {
restartIdleCheck()
sendEvent("tts_started", mapOf("status" to "started"))
// 停止气泡音,避免与TTS同时播放
audioPlayer?.stopAudio()
// audioPlayer?.stopAudio()
}
TtsEventType.SYNTHESIS_COMPLETED -> {
@ -374,14 +374,14 @@ object AgentService : CoroutineScope {
restartIdleCheck()
sendEvent("tts_canceled", mapOf("status" to "canceled"))
// TTS取消时停止气泡音
audioPlayer?.stopAudio()
// audioPlayer?.stopAudio()
}
TtsEventType.PLAYBACK_STARTED -> { //开始AI播报内容
restartIdleCheck()
sendEvent("playback_started", mapOf("status" to "playback_started"))
// 确保气泡音已停止,避免与TTS播放重叠
audioPlayer?.stopAudio()
// audioPlayer?.stopAudio()
if(_isInterrupt.get()){
BleService.closeCodec()
}
@ -1037,13 +1037,14 @@ object AgentService : CoroutineScope {
return
}
responseBuilder.append(token)
// Log.d(TAG, "liwei--------------- AI Call onToken:$token speakResponse:$speakResponse reply:$reply broadcast:$broadcast")
// Log.d(TAG, "liwei--------------- AI Call onToken:$token speakResponse:$speakResponse reply:$reply broadcast:$broadcast")
if (speakResponse && reply && broadcast && token.isNotEmpty()) {
ttsService?.speakStream(token)
}
if (reply && token.isNotEmpty()) {
// 发送流式回复token
sendEvent("assistant_token", mapOf("sessionid" to sessionid,"token" to token))
audioPlayer?.stopAudio()
}
} catch (e: Exception) {
Log.e(TAG, "liwei--------------- AI Call onToken 异常", e)
@ -1053,7 +1054,6 @@ object AgentService : CoroutineScope {
override fun onComplete(sessionid: String) {
try {
if (sessionid == currsessionId) {
audioPlayer?.stopAudio()
}
// 视情况决定是否朗读回复

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

@ -26,6 +26,7 @@ import com.yunqiinnovation.ble_service.BleCompanionManager
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
import android.content.BroadcastReceiver
import android.content.IntentFilter
import android.content.pm.PackageManager
@ -261,9 +262,9 @@ private var companionManager: BleCompanionManager? = null
if (deviceName.equals(TARGET_DEVICE_NAME, ignoreCase = true)) {
Log.i(TAG, "发现已绑定的目标设备: $deviceName")
val pairedUuid = companionManager?.getPairedUuid()
val pairedMac = companionManager?.getPairedMacAddress()
companionManager?.registerBackgroundScan(pairedMac, pairedUuid)
val pairedUuid = companionManager?.getPairedUuid()
val pairedMac = companionManager?.getPairedMacAddress()
companionManager?.registerBackgroundScan(pairedMac, pairedUuid)
// 注意:这里只能检查绑定状态,无法直接判断连接状态
// 实际连接状态需要通过广播接收器监听
}
@ -677,21 +678,130 @@ private var companionManager: BleCompanionManager? = null
super.onDestroy()
}
/**
* 蓝牙耳机设备信息数据类
*/
data class BluetoothHeadsetInfo(
val name: String,
val address: String
)
private fun checkBleConnection() {
Log.i(TAG, "checkBleConnection收到连接请求")
try {
// 使用协程异步处理连接
launch {
if(!BleService.isConnected()) {
BleService.connect()
}
// 首先检查经典蓝牙状态
if (bluetoothAdapter == null) {
Log.e(TAG, "蓝牙适配器不可用,无法进行BLE连接")
return
}
if (!bluetoothAdapter!!.isEnabled) {
Log.w(TAG, "经典蓝牙未开启,无法进行BLE连接")
return
}
// 检查蓝牙耳机连接状态
checkBluetoothHeadsetConnection { hasConnectedHeadset, headsetInfoList ->
if (hasConnectedHeadset && headsetInfoList.isNotEmpty()) {
Log.i(TAG, "检测到 ${headsetInfoList.size} 个蓝牙耳机已连接")
// 查找匹配的配对设备
val pairedMacAddress = BleService.getPairedMacAddress()
val targetHeadset = headsetInfoList.find { it.address == pairedMacAddress }
if (targetHeadset != null) {
Log.i(TAG, "找到匹配的蓝牙耳机: ${targetHeadset.name} (${targetHeadset.address})")
// 使用协程异步处理连接
launch {
if (!BleService.isConnected()) {
BleService.connect()
}
}
} else {
Log.w(TAG, "未找到匹配的配对设备,已连接的设备:")
headsetInfoList.forEach { headset ->
Log.w(TAG, " - ${headset.name} (${headset.address})")
}
Log.w(TAG, "配对的MAC地址: $pairedMacAddress")
}
} else {
Log.w(TAG, "未检测到蓝牙耳机连接,跳过BLE连接")
}
}
} catch (e: Exception) {
Log.e(TAG, "连接设备失败: ${e.message}", e)
}
}
/**
* 检查蓝牙耳机连接状态
* @param callback 回调函数,返回是否有蓝牙耳机连接以及耳机信息列表
*/
private fun checkBluetoothHeadsetConnection(callback: (Boolean, List<BluetoothHeadsetInfo>) -> Unit) {
try {
bluetoothAdapter?.let { adapter ->
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT)
!= PackageManager.PERMISSION_GRANTED) {
Log.w(TAG, "缺少蓝牙连接权限,无法检查蓝牙耳机连接状态")
callback(false, emptyList())
return
}
// 检查HEADSET设备连接状态
adapter.getProfileProxy(this, object : BluetoothProfile.ServiceListener {
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
try {
val connectedDevices = proxy.connectedDevices
val hasConnectedHeadset = connectedDevices.isNotEmpty()
Log.i(TAG, "蓝牙耳机连接设备数量: ${connectedDevices.size}")
if (hasConnectedHeadset) {
// 返回所有连接的蓝牙耳机设备信息
val headsetInfoList = connectedDevices.map { device ->
BluetoothHeadsetInfo(
name = device.name ?: "Unknown Headset",
address = device.address
)
}
Log.d(TAG, "蓝牙耳机连接设备列表:")
headsetInfoList.forEach { info ->
Log.d(TAG, " - ${info.name} (${info.address})")
}
adapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy)
callback(true, headsetInfoList)
} else {
adapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy)
callback(false, emptyList())
}
} catch (e: Exception) {
Log.e(TAG, "检查蓝牙耳机连接状态时发生异常", e)
adapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy)
callback(false, emptyList())
}
}
override fun onServiceDisconnected(profile: Int) {
Log.d(TAG, "蓝牙耳机服务断开连接")
}
}, BluetoothProfile.HEADSET)
} ?: run {
Log.e(TAG, "蓝牙适配器为空")
callback(false, emptyList())
}
} catch (e: Exception) {
Log.e(TAG, "检查蓝牙耳机连接状态时发生异常", e)
callback(false, emptyList())
}
}
/**
* 创建前台服务通知
*/

3
local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift

@ -1697,6 +1697,7 @@ class ChatApiStreamCallback: StreamCallback {
// 在开始流式TTS时立即停止气泡音
}
if (reply && token != "") {
try agentService.audioPlayer?.stopAwaitSound()
try agentService.sendEvent(name: "assistant_token", data: ["sessionid":sessionid,"token": token])
}
}catch {
@ -1876,7 +1877,7 @@ extension AgentServiceImpl: TtsEventListener {
isSpeaking = true
restartIdleCheck()
sendEvent(name: "tts_started", data: ["status": "started"])
audioPlayer?.stopAwaitSound()
// audioPlayer?.stopAwaitSound()
case .synthesisCompleted:
isSpeaking = false

4
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleConst.kt

@ -40,9 +40,9 @@ object BleConst {
// ================== 连接状态 ==================
const val STATE_DISCONNECTED = 0//未连接
const val STATE_CONNECTING = 1//已断开连接
const val STATE_CONNECTING = 1//连接中
const val STATE_CONNECTED = 2//已连接
const val STATE_DISCONNECTING = 3//连接中
const val STATE_DISCONNECTING = 3//已断开连接
const val STATE_ERROR = 4//连接错误
// ================== 广播厂商信息 ==================

19
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt

@ -640,7 +640,12 @@ object BleService {
*/
fun connect(address: String) {
if (connectionState.value == BleConst.STATE_CONNECTED) {
Log.w(TAG, "已经连接中,忽略连接请求")
Log.w(TAG, "已经连接,忽略连接请求")
return
}
if (connectionState.value == BleConst.STATE_CONNECTING) {
Log.w(TAG, "连接中,忽略连接请求")
return
}
@ -1472,6 +1477,18 @@ object BleService {
return connectionState.value == BleConst.STATE_CONNECTED
}
/**
* 获取缓存设备地址
* @return mac地址
*/
fun getPairedMacAddress(): String? {
companionManager = BleCompanionManager.getInstance(context)
// 获取已配对的 MAC 地址
val pairedMac = companionManager?.getPairedMacAddress()
return pairedMac
}
/**
* 获取已连接设备的地址
* @return 设备地址,未连接时返回null

10
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/MusicSystemFunctionHandler.kt

@ -186,7 +186,7 @@ private class MusicSearchHandler(private val context: Context?) : FunctionHandle
return JSONObject().apply {
put("result", "已开始播放媒体")
put("notreply", true)
// put("notreply", true)
put("broadcast", false)
}.toString()
}
@ -215,7 +215,7 @@ private class MusicSearchHandler(private val context: Context?) : FunctionHandle
return JSONObject().apply {
put("result", "已暂停媒体播放")
put("notreply", true)
// put("notreply", true)
put("broadcast", false)
}.toString()
}
@ -244,7 +244,7 @@ private class MusicSearchHandler(private val context: Context?) : FunctionHandle
return JSONObject().apply {
put("result", "已关闭媒体播放")
put("notreply", true)
// put("notreply", true)
put("broadcast", false)
}.toString()
}
@ -272,7 +272,7 @@ private class MusicSearchHandler(private val context: Context?) : FunctionHandle
return JSONObject().apply {
put("result", "已切换到上一首")
put("notreply", true)
// put("notreply", true)
put("broadcast", false)
}.toString()
}
@ -300,7 +300,7 @@ private class MusicSearchHandler(private val context: Context?) : FunctionHandle
return JSONObject().apply {
put("result", "已切换到下一首")
put("notreply", true)
// put("notreply", true)
put("broadcast", false)
}.toString()
}

Loading…
Cancel
Save