Browse Source

Merge branch 'liwei' of https://git.onewaygame.cn/deepsound/deepvoice_client into lxm

newdev_shunjiawei
lxm 1 year ago
parent
commit
68dcda413c
  1. 10
      lib/data/services/music_manager.dart
  2. 15
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt
  3. 1
      local_plugins/music_service/android/src/main/AndroidManifest.xml
  4. 41
      local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicService.kt
  5. 2
      local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicServiceStarter.kt
  6. 2
      local_plugins/open_ai_service/android/src/main/kotlin/com/yunqiinnovation/open_ai_service/OpenAIService.kt

10
lib/data/services/music_manager.dart

@ -1,6 +1,7 @@
import 'package:deep_voice/core/utils/logger.dart'; import 'package:deep_voice/core/utils/logger.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:music_service/music_service.dart'; import 'package:music_service/music_service.dart';
import 'package:permission_handler/permission_handler.dart';
//音乐播放管理 //音乐播放管理
class MusicManager extends GetxService { class MusicManager extends GetxService {
@ -13,7 +14,14 @@ class MusicManager extends GetxService {
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
Logger.info('BLE管理器初始化'); requestNotificationPermission();
Logger.info('初始化权限请求');
}
Future<void> requestNotificationPermission() async {
if (await Permission.notification.isDenied) {
await Permission.notification.request();
}
} }
/// 释放资源 /// 释放资源

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

@ -171,13 +171,13 @@ object AgentService : CoroutineScope {
// 设置系统提示词 // 设置系统提示词
// val customSystemPrompt = config["systemPrompt"] as? String val customSystemPrompt = config["systemPrompt"] as? String
// if (!customSystemPrompt.isNullOrBlank()) { if (!customSystemPrompt.isNullOrBlank()) {
// systemPrompt = customSystemPrompt systemPrompt = customSystemPrompt
// } else { } else {
// initSystemPrompt() initSystemPrompt()
// } }
initSystemPrompt() // initSystemPrompt()
// 初始化Azure ASR // 初始化Azure ASR
azureAsrHelper = AzureAsrHelper(context).apply { azureAsrHelper = AzureAsrHelper(context).apply {
initialize( initialize(
@ -675,6 +675,7 @@ object AgentService : CoroutineScope {
// 先添加系统提示词 // 先添加系统提示词
if (systemPrompt.isNotEmpty()) { if (systemPrompt.isNotEmpty()) {
messagesWithSystemPrompt.put(openAIService.createSystemMessage(systemPrompt)) messagesWithSystemPrompt.put(openAIService.createSystemMessage(systemPrompt))
Log.d(TAG, "系统提示词: ${systemPrompt}")
} }
// 再添加历史消息 // 再添加历史消息

1
local_plugins/music_service/android/src/main/AndroidManifest.xml

@ -3,6 +3,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application> <application>
<service <service

41
local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicService.kt

@ -3,6 +3,7 @@ package com.yunqiinnovation.music_service
import android.app.Notification import android.app.Notification
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
@ -18,6 +19,7 @@ import androidx.core.app.NotificationCompat
import androidx.media.MediaBrowserServiceCompat import androidx.media.MediaBrowserServiceCompat
import androidx.media.session.MediaButtonReceiver import androidx.media.session.MediaButtonReceiver
import android.util.Log import android.util.Log
import android.view.KeyEvent
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.URL import java.net.URL
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
@ -125,6 +127,7 @@ class MusicService : MediaBrowserServiceCompat() {
) )
isActive = true isActive = true
} }
mediaSession.setMediaButtonReceiver(null)
// 将 token 暴露给 MediaBrowserServiceCompat // 将 token 暴露给 MediaBrowserServiceCompat
setSessionToken(mediaSession.sessionToken) setSessionToken(mediaSession.sessionToken)
} }
@ -137,15 +140,11 @@ class MusicService : MediaBrowserServiceCompat() {
) )
} }
val prevIntent = MediaButtonReceiver.buildMediaButtonPendingIntent( val prevIntent = mediaButtonPendingIntent(PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS)
this, PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS val playPauseIntent = mediaButtonPendingIntent(
) if (currentStatus) PlaybackStateCompat.ACTION_PAUSE else PlaybackStateCompat.ACTION_PLAY
val playPauseIntent = MediaButtonReceiver.buildMediaButtonPendingIntent(
this, if (currentStatus) PlaybackStateCompat.ACTION_PAUSE else PlaybackStateCompat.ACTION_PLAY
)
val nextIntent = MediaButtonReceiver.buildMediaButtonPendingIntent(
this, PlaybackStateCompat.ACTION_SKIP_TO_NEXT
) )
val nextIntent = mediaButtonPendingIntent(PlaybackStateCompat.ACTION_SKIP_TO_NEXT)
val builder = NotificationCompat.Builder(this, CHANNEL_ID) val builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle(title) .setContentTitle(title)
@ -192,6 +191,26 @@ class MusicService : MediaBrowserServiceCompat() {
return builder.build() return builder.build()
} }
fun mediaButtonPendingIntent(action: Long): PendingIntent {
val intent = Intent(this, MusicService::class.java).apply {
this.action = Intent.ACTION_MEDIA_BUTTON
putExtra(Intent.EXTRA_KEY_EVENT, KeyEvent(KeyEvent.ACTION_DOWN, action.toKeyCode()))
}
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
} else {
PendingIntent.FLAG_UPDATE_CURRENT
}
return PendingIntent.getService(this, action.toInt(), intent, flags)
}
// 转换 PlaybackStateCompat.ACTION 到 KeyEvent
fun Long.toKeyCode(): Int = when (this) {
PlaybackStateCompat.ACTION_PLAY -> KeyEvent.KEYCODE_MEDIA_PLAY
PlaybackStateCompat.ACTION_PAUSE -> KeyEvent.KEYCODE_MEDIA_PAUSE
PlaybackStateCompat.ACTION_SKIP_TO_NEXT -> KeyEvent.KEYCODE_MEDIA_NEXT
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS -> KeyEvent.KEYCODE_MEDIA_PREVIOUS
else -> KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
}
/** /**
* 设置播放状态 * 设置播放状态
*/ */
@ -242,7 +261,7 @@ class MusicService : MediaBrowserServiceCompat() {
} }
prepareAsync() prepareAsync()
} }
setPlaybackState(PlaybackStateCompat.STATE_PAUSED); setPlaybackState(PlaybackStateCompat.STATE_PLAYING);
} }
private fun pause() { private fun pause() {
@ -259,7 +278,7 @@ class MusicService : MediaBrowserServiceCompat() {
val artist = song["artist"] ?: "未知歌手" val artist = song["artist"] ?: "未知歌手"
val coverUrl = song["coverUrl"] val coverUrl = song["coverUrl"]
updateNotification(title,artist,coverUrl) updateNotification(title,artist,coverUrl)
setPlaybackState(PlaybackStateCompat.STATE_PLAYING); setPlaybackState(PlaybackStateCompat.STATE_PAUSED);
Log.i(TAG, "已暂停") Log.i(TAG, "已暂停")
} }
@ -279,7 +298,7 @@ class MusicService : MediaBrowserServiceCompat() {
val artist = song["artist"] ?: "未知歌手" val artist = song["artist"] ?: "未知歌手"
val coverUrl = song["coverUrl"] val coverUrl = song["coverUrl"]
updateNotification(title,artist,coverUrl) updateNotification(title,artist,coverUrl)
setPlaybackState(PlaybackStateCompat.STATE_PAUSED); setPlaybackState(PlaybackStateCompat.STATE_PLAYING);
// Log.i(TAG, "继续播放") // Log.i(TAG, "继续播放")
} }
} }

2
local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicServiceStarter.kt

@ -2,8 +2,10 @@ package com.yunqiinnovation.music_service
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build
import android.util.Log import android.util.Log
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import java.util.jar.Manifest
//@Parcelize //@Parcelize
//data class Song( //data class Song(

2
local_plugins/open_ai_service/android/src/main/kotlin/com/yunqiinnovation/open_ai_service/OpenAIService.kt

@ -514,6 +514,8 @@ class OpenAIService(private val context: Context? = null) : CoroutineScope {
if (tools.length() > 0) { if (tools.length() > 0) {
put("tools", tools) put("tools", tools)
} }
Log.i(TAG, "请求Ai对话: 携带工具数据 ${tools.length()}")
} }
val mediaType = "application/json".toMediaTypeOrNull() val mediaType = "application/json".toMediaTypeOrNull()

Loading…
Cancel
Save