Browse Source

上传设备绑定优化以及音量调整代码

newdev_shunjiawei
liwei1dao 1 year ago
parent
commit
e8fa2be978
  1. 7
      lib/data/models/appconfig.dart
  2. 24
      lib/data/models/appconfig_model.dart
  3. 16
      lib/data/models/appconfig_model.g.dart
  4. 5
      lib/data/models/user_Info.dart
  5. 13
      lib/data/services/network/api.dart
  6. 4
      lib/data/services/network/nw_api.dart
  7. 14
      lib/modules/devices/controllers/devices_controller.dart
  8. 6
      lib/modules/devices/views/devices_view.dart
  9. 5
      lib/modules/login/controllers/login_controller.dart
  10. 2
      lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart
  11. 27
      lib/modules/pairing/controllers/pairing_controller.dart
  12. 14
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt
  13. 142
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/SystemFunctionHandler.kt
  14. 102
      local_plugins/open_ai_service/android/src/main/kotlin/com/yunqiinnovation/open_ai_service/SystemFunctionHandler.kt

7
lib/data/models/appconfig.dart

@ -4,7 +4,6 @@ import 'package:deep_voice/data/models/appconfig_model.dart';
class AppConfig { class AppConfig {
static late UserGetAppConfigResp config; static late UserGetAppConfigResp config;
// 可选:提供初始化方法 // 可选:提供初始化方法
static void initialize(UserGetAppConfigResp resp) { static void initialize(UserGetAppConfigResp resp) {
config = resp; config = resp;
@ -25,4 +24,10 @@ class AppConfig {
final foundAgent = config.agents.firstWhere((agent) => agent.id == agentId); final foundAgent = config.agents.firstWhere((agent) => agent.id == agentId);
return foundAgent.systemPrompt; return foundAgent.systemPrompt;
} }
static List<String> allproductNames() {
List<String> names =
config.products.map((user) => user.devicename).toList();
return names;
}
} }

24
lib/data/models/appconfig_model.dart

@ -7,8 +7,13 @@ class UserGetAppConfigResp {
final Map<String, String> env; final Map<String, String> env;
final List<DBAgent> agents; final List<DBAgent> agents;
final Map<String, DBMCPServer> mcps; final Map<String, DBMCPServer> mcps;
final List<DBProduct> products;
UserGetAppConfigResp( UserGetAppConfigResp(
{required this.env, required this.agents, required this.mcps}); {required this.env,
required this.agents,
required this.mcps,
required this.products});
factory UserGetAppConfigResp.fromJson(Map<String, dynamic> json) => factory UserGetAppConfigResp.fromJson(Map<String, dynamic> json) =>
_$UserGetAppConfigRespFromJson(json); _$UserGetAppConfigRespFromJson(json);
@ -63,3 +68,20 @@ class DBMCPServer {
_$DBMCPServerFromJson(json); _$DBMCPServerFromJson(json);
Map<String, dynamic> toJson() => _$DBMCPServerToJson(this); Map<String, dynamic> toJson() => _$DBMCPServerToJson(this);
} }
@JsonSerializable()
class DBProduct {
final String id;
final int factoryid;
final String devicename;
DBProduct({
required this.id,
required this.factoryid,
required this.devicename,
});
factory DBProduct.fromJson(Map<String, dynamic> json) =>
_$DBProductFromJson(json);
Map<String, dynamic> toJson() => _$DBProductToJson(this);
}

16
lib/data/models/appconfig_model.g.dart

@ -16,6 +16,9 @@ UserGetAppConfigResp _$UserGetAppConfigRespFromJson(
mcps: (json['mcps'] as Map<String, dynamic>).map( mcps: (json['mcps'] as Map<String, dynamic>).map(
(k, e) => MapEntry(k, DBMCPServer.fromJson(e as Map<String, dynamic>)), (k, e) => MapEntry(k, DBMCPServer.fromJson(e as Map<String, dynamic>)),
), ),
products: (json['products'] as List<dynamic>)
.map((e) => DBProduct.fromJson(e as Map<String, dynamic>))
.toList(),
); );
Map<String, dynamic> _$UserGetAppConfigRespToJson( Map<String, dynamic> _$UserGetAppConfigRespToJson(
@ -24,6 +27,7 @@ Map<String, dynamic> _$UserGetAppConfigRespToJson(
'env': instance.env, 'env': instance.env,
'agents': instance.agents, 'agents': instance.agents,
'mcps': instance.mcps, 'mcps': instance.mcps,
'products': instance.products,
}; };
DBAgent _$DBAgentFromJson(Map<String, dynamic> json) => DBAgent( DBAgent _$DBAgentFromJson(Map<String, dynamic> json) => DBAgent(
@ -66,3 +70,15 @@ Map<String, dynamic> _$DBMCPServerToJson(DBMCPServer instance) =>
'url': instance.url, 'url': instance.url,
'tools': instance.tools, 'tools': instance.tools,
}; };
DBProduct _$DBProductFromJson(Map<String, dynamic> json) => DBProduct(
id: json['id'] as String,
factoryid: (json['factoryid'] as num).toInt(),
devicename: json['devicename'] as String,
);
Map<String, dynamic> _$DBProductToJson(DBProduct instance) => <String, dynamic>{
'id': instance.id,
'factoryid': instance.factoryid,
'devicename': instance.devicename,
};

5
lib/data/models/user_Info.dart

@ -23,6 +23,7 @@ class User {
int viplv = 0; //添加会员等级字段,0表示普通用户 int viplv = 0; //添加会员等级字段,0表示普通用户
String earphonename; String earphonename;
String earphonemac; String earphonemac;
String earphonelicense;
String earphoneauthcode; String earphoneauthcode;
// final Int64 lastbettime; // final Int64 lastbettime;
// final Int64 createtime; // final Int64 createtime;
@ -44,6 +45,7 @@ class User {
required this.viplv, // 添加默认值 required this.viplv, // 添加默认值
required this.earphonename, required this.earphonename,
required this.earphonemac, required this.earphonemac,
required this.earphonelicense,
required this.earphoneauthcode, required this.earphoneauthcode,
// required this.lastbettime, // required this.lastbettime,
// required this.createtime, // required this.createtime,
@ -74,6 +76,7 @@ class User {
viplv: (userData?['viplv'] as int?) ?? 0, // 提供默认值 viplv: (userData?['viplv'] as int?) ?? 0, // 提供默认值
earphonename: (userData?['earphonename'] as String?) ?? '', earphonename: (userData?['earphonename'] as String?) ?? '',
earphonemac: (userData?['earphonemac'] as String?) ?? '', earphonemac: (userData?['earphonemac'] as String?) ?? '',
earphonelicense: (userData?['earphonelicense'] as String?) ?? '',
earphoneauthcode: (userData?['earphoneauthcode'] as String?) ?? '', earphoneauthcode: (userData?['earphoneauthcode'] as String?) ?? '',
// lastbettime: _parseTimestamp(userData['lastbettime']), // lastbettime: _parseTimestamp(userData['lastbettime']),
// createtime: _parseTimestamp(userData['createtime']), // createtime: _parseTimestamp(userData['createtime']),
@ -102,6 +105,7 @@ class User {
viplv: (userData?['viplv'] as int?) ?? 0, // 提供默认值 viplv: (userData?['viplv'] as int?) ?? 0, // 提供默认值
earphonename: (userData?['earphonename'] as String?) ?? '', earphonename: (userData?['earphonename'] as String?) ?? '',
earphonemac: (userData?['earphonemac'] as String?) ?? '', earphonemac: (userData?['earphonemac'] as String?) ?? '',
earphonelicense: (userData?['earphonelicense'] as String?) ?? '',
earphoneauthcode: (userData?['earphoneauthcode'] as String?) ?? '', earphoneauthcode: (userData?['earphoneauthcode'] as String?) ?? '',
// lastbettime: _parseTimestamp(userData['lastbettime']), // lastbettime: _parseTimestamp(userData['lastbettime']),
// createtime: _parseTimestamp(userData['createtime']), // createtime: _parseTimestamp(userData['createtime']),
@ -128,6 +132,7 @@ class User {
'earphonename': earphonename, 'earphonename': earphonename,
'earphonemac': earphonemac, 'earphonemac': earphonemac,
"earphonelicense": earphonelicense,
'earphoneauthcode': earphoneauthcode, 'earphoneauthcode': earphoneauthcode,
// 'lastbettime': lastbettime, // 'lastbettime': lastbettime,

13
lib/data/services/network/api.dart

@ -74,10 +74,19 @@ class Api {
} }
//app获取设备信息 //app获取设备信息
static getequipmentinfo([params]) { static getproduct([params]) {
return DioManager().request( return DioManager().request(
NWMethod.post, NWMethod.post,
'/api/home/user_getequipmentinfo', '/api/home/user_getproduct',
params: params,
);
}
//app获取设备信息
static getproducts([params]) {
return DioManager().request(
NWMethod.post,
'/api/home/user_getproducts',
params: params, params: params,
); );
} }

4
lib/data/services/network/nw_api.dart

@ -1,5 +1,5 @@
class NWApi { class NWApi {
// static const baseApi = "https://www.deapsound.com"; // static const baseApi = "https://www.deapsound.com";
//static const baseApi = "https://api.deapsound.com"; static const baseApi = "https://api.deapsound.com";
static const baseApi = "https://api.ideapsound.com"; // static const baseApi = "https://api.ideapsound.com";
} }

14
lib/modules/devices/controllers/devices_controller.dart

@ -13,12 +13,14 @@ import 'package:get/get_state_manager/src/simple/get_controllers.dart';
class DevicesController extends GetxController { class DevicesController extends GetxController {
late final BleManager _bleManager; late final BleManager _bleManager;
//耳机绑定 //耳机绑定
final isearphone = false.obs; final earphonestate = 0.obs;
final earphoneName = "".obs; final earphoneName = "".obs;
final earphoneMac = "".obs; final earphoneMac = "".obs;
final earphoneLicense = "".obs;
final earphoneCode = "".obs; final earphoneCode = "".obs;
//录音笔 //录音笔
final voicepenstate = 0.obs;
final isvoicepen = false.obs; final isvoicepen = false.obs;
final voicepenName = "".obs; final voicepenName = "".obs;
final voicepenMac = "".obs; final voicepenMac = "".obs;
@ -29,9 +31,13 @@ class DevicesController extends GetxController {
_bleManager = Get.find<BleManager>(); _bleManager = Get.find<BleManager>();
earphoneName.value = User.instance.earphonename; earphoneName.value = User.instance.earphonename;
earphoneMac.value = User.instance.earphonemac; earphoneMac.value = User.instance.earphonemac;
earphoneLicense.value = User.instance.earphonelicense;
earphoneCode.value = User.instance.earphoneauthcode; earphoneCode.value = User.instance.earphoneauthcode;
if (earphoneCode.value != "") { if (earphoneCode.value != "") {
isearphone.value = true; earphonestate.value = 1;
}
if (earphoneLicense.value != "") {
earphonestate.value = 2;
} }
} }
@ -48,8 +54,8 @@ class DevicesController extends GetxController {
if (response != null) { if (response != null) {
User.instance.earphonename = ""; User.instance.earphonename = "";
User.instance.earphonemac = ""; User.instance.earphonemac = "";
User.instance.earphoneauthcode = ""; User.instance.earphonelicense = "";
isearphone.value = false; earphonestate.value = 0;
_bleManager.clearPairedDevices(); _bleManager.clearPairedDevices();
_bleManager.disconnect(); _bleManager.disconnect();
Get.toNamed(Routes.pairing); Get.toNamed(Routes.pairing);

6
lib/modules/devices/views/devices_view.dart

@ -93,10 +93,10 @@ class DevicesView extends GetView<DevicesController> {
() => () =>
// 耳机列表 // 耳机列表
_buildSimpleNavigationSetting( _buildSimpleNavigationSetting(
title: controller.isearphone.value title: controller.earphonestate.value != 0
? controller.earphoneName.value ? controller.earphoneName.value
: "未绑定", : "未绑定",
subtitle: controller.isearphone.value subtitle: controller.earphonestate.value != 0
? controller.earphoneMac.value ? controller.earphoneMac.value
: "还未绑定设备", : "还未绑定设备",
icon: Icons.headphones, icon: Icons.headphones,
@ -110,7 +110,7 @@ class DevicesView extends GetView<DevicesController> {
titleColor: isDarkMode ? Colors.white : null, titleColor: isDarkMode ? Colors.white : null,
subtitleColor: isDarkMode ? Colors.white70 : null, subtitleColor: isDarkMode ? Colors.white70 : null,
isDarkMode: isDarkMode, isDarkMode: isDarkMode,
showbutt: controller.isearphone.value, showbutt: controller.earphonestate == 2,
onPressed: () { onPressed: () {
controller.unbindearphone(); controller.unbindearphone();
}, },

5
lib/modules/login/controllers/login_controller.dart

@ -11,7 +11,6 @@ import 'weixinLogin.dart';
import '../../../data/services/network/api.dart'; import '../../../data/services/network/api.dart';
import '../../../../data/models/user_Info.dart'; import '../../../../data/models/user_Info.dart';
import '../../common/webview_page.dart'; import '../../common/webview_page.dart';
//import 'package:shared_preferences/shared_preferences.dart';
import 'package:get_storage/get_storage.dart'; import 'package:get_storage/get_storage.dart';
import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart';
import 'dart:io'; import 'dart:io';
@ -914,10 +913,6 @@ class LoginController extends GetxController {
print('getAppConfig:进来了'); print('getAppConfig:进来了');
// 根据API设计调整 // 根据API设计调整
final resp = UserGetAppConfigResp.fromJson(response); final resp = UserGetAppConfigResp.fromJson(response);
// 存储用户信息(示例)
// _storage.write('ENV', resp.env);
// _storage.write('AGENTS', resp.agents);
// _storage.write('MCPS', resp.mcps);
AppConfig.initialize(resp); AppConfig.initialize(resp);
return true; return true;
} catch (e) { } catch (e) {

2
lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart

@ -184,7 +184,7 @@ class OtaUpgradeController extends GetxController {
jlota.init(); jlota.init();
// API请求 // API请求
final response = await Api.getequipmentinfo({ final response = await Api.getproduct({
"id": deviceInfo.firmwareProductId, "id": deviceInfo.firmwareProductId,
}); });

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

@ -431,9 +431,12 @@ class PairingController extends GetxController {
try { try {
Logger.i(_tag, '开始验证设备: ${device.name} (${device.address})'); Logger.i(_tag, '开始验证设备: ${device.name} (${device.address})');
final result = await authbindingDevice(device); final result = await authbindingDevice(device);
if (result == 2) { if (result == 10) {
//验证失败 进入手动授权 //验证失败 进入手动授权
await connectble(device); await connectble(device);
} else if (result == 9) {
Logger.i(_tag, 'BLE已连接,直接完成配对');
_transition(PairingState.completed);
} else if (result == 1) { } else if (result == 1) {
//跳转绑定界面 //跳转绑定界面
//验证失败 进入手动授权 //验证失败 进入手动授权
@ -557,15 +560,22 @@ class PairingController extends GetxController {
//自动绑定设备 0 未合作商 1 合作商 2,已绑定 //自动绑定设备 0 未合作商 1 合作商 2,已绑定
Future<int> authbindingDevice(BluetoothDevice device) async { Future<int> authbindingDevice(BluetoothDevice device) async {
if (User.instance.earphonemac == device.address) { if (User.instance.earphonelicense != "" &&
User.instance.earphonemac == device.address) {
// 已经绑定 // 已经绑定
return 2; return 10;
}
if (User.instance.earphoneauthcode != "" &&
User.instance.earphonemac == device.address) {
// 已经绑定
return 9;
} }
// 检查设备名称是否包含 DeepSound 或 DeapSound // 检查设备名称是否包含 DeepSound 或 DeapSound
final deviceName = device.name; final deviceName = device.name;
print('获取到 deviceName: $deviceName');
if (deviceName.contains('DeepSound') || deviceName.contains('DeapSound')) { final names = AppConfig.allproductNames();
print('获取到 deviceName: $deviceName names:$names');
if (names.contains(deviceName)) {
await _bleManager.startScan(deviceName); await _bleManager.startScan(deviceName);
await Future.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
// 尝试最多读取 3 次设备信息,每次间隔 1 秒 // 尝试最多读取 3 次设备信息,每次间隔 1 秒
@ -610,7 +620,7 @@ class PairingController extends GetxController {
Logger.i(_tag, '绑定设备成功'); Logger.i(_tag, '绑定设备成功');
User.instance.earphonemac = currentDevice?.address ?? ''; User.instance.earphonemac = currentDevice?.address ?? '';
User.instance.earphonename = currentDevice?.name ?? ''; User.instance.earphonename = currentDevice?.name ?? '';
User.instance.earphoneauthcode = deviceCode.value; User.instance.earphonelicense = deviceCode.value;
_transition(PairingState.verifying); _transition(PairingState.verifying);
_verifyDevice(_currentClassicDevice!); _verifyDevice(_currentClassicDevice!);
return; return;
@ -642,8 +652,9 @@ class PairingController extends GetxController {
void onAutoCodeInputTap() async { void onAutoCodeInputTap() async {
// 调用BLE管理器的自动绑定方法 // 调用BLE管理器的自动绑定方法
final response = await Api.bindauthcode({ final response = await Api.bindauthcode({
"code": codeInputController.text.trim(),
"earphonname": currentDevice?.name,
"earphonemac": currentDevice?.address, "earphonemac": currentDevice?.address,
"earphoneauthcode": codeInputController.text.trim(),
}); });
Logger.i(_tag, '手动授权结果 ${response}'); Logger.i(_tag, '手动授权结果 ${response}');
if (response != null) { if (response != null) {

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

@ -734,6 +734,7 @@ object AgentService : CoroutineScope {
) { ) {
Log.d(TAG, "内部方法:通用的ChatAPI处理逻辑") Log.d(TAG, "内部方法:通用的ChatAPI处理逻辑")
// 如果有正在进行的AI流式输出,先停止它 // 如果有正在进行的AI流式输出,先停止它
audioPlayer?.stopAudio()
stopAiStream() stopAiStream()
stopTts() stopTts()
// 记录新的AI任务 // 记录新的AI任务
@ -748,6 +749,7 @@ object AgentService : CoroutineScope {
val responseBuilder = StringBuilder() val responseBuilder = StringBuilder()
var aiMetadata:String = "" var aiMetadata:String = ""
var userMetadata = JSONObject() var userMetadata = JSONObject()
var reply = false; //是否回复
var broadcast = true //是否播发 var broadcast = true //是否播发
// 如果有图片,添加图片信息到元数据 // 如果有图片,添加图片信息到元数据
if (hasImage) { if (hasImage) {
@ -814,10 +816,10 @@ object AgentService : CoroutineScope {
return return
} }
responseBuilder.append(token) responseBuilder.append(token)
if (speakResponse && broadcast) { if (speakResponse && reply && broadcast) {
ttsService?.speakStream(token) ttsService?.speakStream(token)
} }
if (broadcast) { if (reply && token.isNotEmpty()) {
// 发送流式回复token // 发送流式回复token
sendEvent("assistant_token", mapOf("token" to token)) sendEvent("assistant_token", mapOf("token" to token))
} }
@ -829,7 +831,7 @@ object AgentService : CoroutineScope {
override fun onComplete(sessionid:String) { override fun onComplete(sessionid:String) {
try { try {
// 视情况决定是否朗读回复 // 视情况决定是否朗读回复
if (speakResponse && broadcast && sessionid == currsessionId){ if (speakResponse && reply && broadcast && sessionid == currsessionId){
ttsService?.flushStream() ttsService?.flushStream()
audioPlayer?.stopAudio() audioPlayer?.stopAudio()
} }
@ -842,7 +844,10 @@ object AgentService : CoroutineScope {
if (hasImage) { if (hasImage) {
responseData["hasImage"] = true responseData["hasImage"] = true
} }
sendEvent("assistant_response", responseData) if (reply){
sendEvent("assistant_response", responseData)
}
if (response.isNotEmpty()) { if (response.isNotEmpty()) {
// 添加AI回复到历史记录 // 添加AI回复到历史记录
addToHistoryMessages(createAssistantMessage(response)) addToHistoryMessages(createAssistantMessage(response))
@ -903,6 +908,7 @@ object AgentService : CoroutineScope {
val resultmap = autoHandleFcunCallResult(name, functionCallResult); val resultmap = autoHandleFcunCallResult(name, functionCallResult);
aiMetadata = resultmap["meta"] as String; aiMetadata = resultmap["meta"] as String;
broadcast = resultmap["broadcast"] as Boolean; broadcast = resultmap["broadcast"] as Boolean;
reply = !(resultmap["notreply"] as Boolean);
sendEvent( sendEvent(
"function_call_result", mapOf( "function_call_result", mapOf(
"function_call" to functionCall.toString(), "function_call" to functionCall.toString(),

142
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/SystemFunctionHandler.kt

@ -8,6 +8,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.location.LocationManager import android.location.LocationManager
import android.media.AudioManager
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.provider.AlarmClock import android.provider.AlarmClock
@ -232,6 +233,42 @@ class SystemFunctionHandler(private val context: Context? = null) {
), ),
handler = ExitNavigationHandler(context) handler = ExitNavigationHandler(context)
) )
// 增加音量
client.registerLocalFunction(
name = "add_volume",
description = "增大音量",
parameters = mapOf(
"type" to "object",
"properties" to emptyMap<String, Any>(),
"required" to emptyList<String>()
),
handler = AddVolumeHandler(context)
)
// 增加音量
client.registerLocalFunction(
name = "reduce_volume",
description = "降低音量",
parameters = mapOf(
"type" to "object",
"properties" to emptyMap<String, Any>(),
"required" to emptyList<String>()
),
handler = ReduceVolumeHandler(context)
)
// 设置静音
client.registerLocalFunction(
name = "mute_volume",
description = "设置静音",
parameters = mapOf(
"type" to "object",
"properties" to emptyMap<String, Any>(),
"required" to emptyList<String>()
),
handler = MuteVolumeHandler(context)
)
} }
/** /**
@ -1321,3 +1358,108 @@ private class OpenRecorderHandler(private val context: Context?) : FunctionHandl
} }
} }
} }
/**
* 添加音量处理类
*/
private class AddVolumeHandler(private val context: Context?) : FunctionHandler {
//设置音量
fun setVolume(context: Context, streamType: Int, volume: Int) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val maxVolume = audioManager.getStreamMaxVolume(streamType)
val safeVolume = volume.coerceIn(0, maxVolume)
audioManager.setStreamVolume(streamType, safeVolume, AudioManager.FLAG_SHOW_UI)
}
fun getCurrentVolume(context: Context, streamType: Int): Int {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
return audioManager.getStreamVolume(streamType)
}
fun getMaxVolume(context: Context, streamType: Int): Int {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
return audioManager.getStreamMaxVolume(streamType)
}
//增加音量/减少音量
fun adjustVolume(context: Context, direction: Int) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, direction, AudioManager.FLAG_SHOW_UI)
}
override suspend fun handle(arguments: Map<String, Any>): String {
if (context == null) {
return JSONObject().apply {
put("error", JSONObject().apply {
put("code", "context_error")
put("message", "上下文未初始化")
})
}.toString()
}
// 发送广播通知退出交互
val result = adjustVolume(context, AudioManager.ADJUST_RAISE)
return JSONObject().apply {
put("result", "增加音量成功!")
put("broadcast", false)
}.toString()
}
}
/**
* 添加音量处理类
*/
private class ReduceVolumeHandler(private val context: Context?) : FunctionHandler {
//增加音量/减少音量
fun adjustVolume(context: Context, direction: Int) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, direction, AudioManager.FLAG_SHOW_UI)
}
override suspend fun handle(arguments: Map<String, Any>): String {
if (context == null) {
return JSONObject().apply {
put("error", JSONObject().apply {
put("code", "context_error")
put("message", "上下文未初始化")
})
}.toString()
}
// 发送广播通知退出交互
adjustVolume(context, AudioManager.ADJUST_LOWER)
return JSONObject().apply {
put("result", "降低音量成功!")
put("broadcast", false)
}.toString()
}
}
/**
* 添加音量处理类
*/
private class MuteVolumeHandler(private val context: Context?) : FunctionHandler {
//设置音量
fun setVolume(context: Context, streamType: Int, volume: Int) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val maxVolume = audioManager.getStreamMaxVolume(streamType)
val safeVolume = volume.coerceIn(0, maxVolume)
audioManager.setStreamVolume(streamType, safeVolume, AudioManager.FLAG_SHOW_UI)
}
override suspend fun handle(arguments: Map<String, Any>): String {
if (context == null) {
return JSONObject().apply {
put("error", JSONObject().apply {
put("code", "context_error")
put("message", "上下文未初始化")
})
}.toString()
}
// 发送广播通知退出交互
setVolume(context, AudioManager.STREAM_MUSIC, 0)
return JSONObject().apply {
put("result", "设置静音成功!")
put("broadcast", false)
}.toString()
}
}

102
local_plugins/open_ai_service/android/src/main/kotlin/com/yunqiinnovation/open_ai_service/SystemFunctionHandler.kt

@ -30,6 +30,7 @@ import androidx.core.content.ContextCompat
import android.app.ActivityManager import android.app.ActivityManager
import android.app.Application import android.app.Application
import android.content.ComponentName import android.content.ComponentName
import android.media.AudioManager
import android.os.Process import android.os.Process
/** /**
* 系统功能处理器 - 负责调用系统API执行各种功能以及注册系统功能 * 系统功能处理器 - 负责调用系统API执行各种功能以及注册系统功能
@ -78,6 +79,13 @@ class SystemFunctionHandler(private val context: Context) {
// 注册关闭导航服务功能 // 注册关闭导航服务功能
registerStopNavigationFunction(client) registerStopNavigationFunction(client)
//增加音量
registerAddVolumeFunction(client)
//减少音量
registerReduceVolumeFunction(client)
//静音
registerMuteVolumeFunction(client)
Log.d(TAG, "所有系统功能注册完成") Log.d(TAG, "所有系统功能注册完成")
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "注册系统功能失败: ${e.message}", e) Log.e(TAG, "注册系统功能失败: ${e.message}", e)
@ -438,6 +446,78 @@ class SystemFunctionHandler(private val context: Context) {
) )
Log.d(TAG, "已注册获取当前时间功能") Log.d(TAG, "已注册获取当前时间功能")
} }
/**
* 注册添加音量函数
*/
private fun registerAddVolumeFunction(client: MCPClient) {
client.registerLocalFunction(
"add_volume",
"增大音量",
JSONObject("""
{
"type": "object",
"properties": {},
"required": []
}
"""),
object : FunctionHandler {
override suspend fun handle(arguments: Map<String, Any>): String {
val result = adjustVolume(context, AudioManager.ADJUST_RAISE)
return "{\"result\": \"增加音量成功!\"}"
}
}
)
Log.d(TAG, "已注册音量调节功能")
}
/**
* 注册减少音量函数
*/
private fun registerReduceVolumeFunction(client: MCPClient) {
client.registerLocalFunction(
"reduce_volume",
"减少音量",
JSONObject("""
{
"type": "object",
"properties": {},
"required": []
}
"""),
object : FunctionHandler {
override suspend fun handle(arguments: Map<String, Any>): String {
val result = adjustVolume(context, AudioManager.ADJUST_LOWER)
return "{\"result\": \"减少音量成功!\"}"
}
}
)
Log.d(TAG, "已注册音量调节功能")
}
/**
* 注册静音函数
*/
private fun registerMuteVolumeFunction(client: MCPClient) {
client.registerLocalFunction(
"mute_volume",
"静音设置",
JSONObject("""
{
"type": "object",
"properties": {},
"required": []
}
"""),
object : FunctionHandler {
override suspend fun handle(arguments: Map<String, Any>): String {
val result = setVolume(context, AudioManager.STREAM_MUSIC, 0)
return "{\"result\": \"减少音量成功!\"}"
}
}
)
Log.d(TAG, "已注册音量调节功能")
}
/** /**
* 控制媒体播放 * 控制媒体播放
* @param action 操作类型:"play", "pause", "previous", "next" * @param action 操作类型:"play", "pause", "previous", "next"
@ -1241,6 +1321,28 @@ class SystemFunctionHandler(private val context: Context) {
} }
} }
//设置音量
fun setVolume(context: Context, streamType: Int, volume: Int) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val maxVolume = audioManager.getStreamMaxVolume(streamType)
val safeVolume = volume.coerceIn(0, maxVolume)
audioManager.setStreamVolume(streamType, safeVolume, AudioManager.FLAG_SHOW_UI)
}
fun getCurrentVolume(context: Context, streamType: Int): Int {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
return audioManager.getStreamVolume(streamType)
}
fun getMaxVolume(context: Context, streamType: Int): Int {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
return audioManager.getStreamMaxVolume(streamType)
}
//增加音量/减少音量
fun adjustVolume(context: Context, direction: Int) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, direction, AudioManager.FLAG_SHOW_UI)
}
/** /**
* 操作结果数据类 * 操作结果数据类
*/ */

Loading…
Cancel
Save