From 373e6ac199c49754b92d76be9e2c8c57b8ab4acb Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Sat, 5 Jul 2025 17:05:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=9F=B3=E4=B9=90=E6=92=AD?= =?UTF-8?q?=E6=94=BE=E7=8A=B6=E6=80=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/services/music_manager.dart | 2 +- .../agent/controllers/agent_controller.dart | 53 +++++++++---------- lib/modules/agent/views/music_card.dart | 2 +- .../music/views/music_playlist_view.dart | 15 +++--- .../agent_service/AgentService.kt | 8 +-- .../music_service/MusicService.kt | 46 ++++++++-------- .../music_service/lib/music_service.dart | 7 +-- 7 files changed, 63 insertions(+), 70 deletions(-) diff --git a/lib/data/services/music_manager.dart b/lib/data/services/music_manager.dart index 621cd927c..51975424f 100644 --- a/lib/data/services/music_manager.dart +++ b/lib/data/services/music_manager.dart @@ -105,7 +105,7 @@ class MusicManager extends GetxService { required Function() onPrevious, required Function(int) onSeekTo, required Function() onStop, - required Function(String, int, int, double) onStop1, + required Function(int, int, int, double) onStop1, }) async { try { await _musicService.setMediaSessionCallbacks( diff --git a/lib/modules/agent/controllers/agent_controller.dart b/lib/modules/agent/controllers/agent_controller.dart index 6c69ad897..8eec19a15 100644 --- a/lib/modules/agent/controllers/agent_controller.dart +++ b/lib/modules/agent/controllers/agent_controller.dart @@ -5,7 +5,6 @@ import 'dart:io'; import 'package:amap_service/amap_service.dart'; import 'package:deep_voice/core/utils/upload_oss.dart'; import 'package:deep_voice/data/models/user_Info.dart'; -import 'package:deep_voice/data/services/location_manager.dart'; import 'package:deep_voice/data/services/music_manager.dart'; import 'package:deep_voice/data/services/navigation_manager.dart'; import 'package:deep_voice/data/services/network/api.dart'; @@ -126,11 +125,11 @@ class AgentController extends GetxController { // 添加加载状态跟踪 final RxBool isLoadingMusic = false.obs; - final RxString loadingMusicId = ''.obs; + final RxInt loadingMusicId = 0.obs; // 设置加载状态的方法 - void setLoadingMusic(String id, bool loading) { - loadingMusicId.value = loading ? id : ''; + void setLoadingMusic(int id, bool loading) { + loadingMusicId.value = loading ? id : 0; isLoadingMusic.value = loading; } @@ -1333,7 +1332,7 @@ class AgentController extends GetxController { try { var status = await _musiceManager.getStatus(); isPlaying.value = status['isPlaying'] ?? false; - currentId.value = status['id'] ?? 0; + currentId.value = status['id'] as int; Logger.d('AgentController', '音乐状态更新: playing=${isPlaying.value}, url=${currentId.value}'); print("音乐状态更新: playing=${isPlaying.value}, url=${currentId.value}"); @@ -1351,16 +1350,14 @@ class AgentController extends GetxController { isPlaying.value = true; // 修复:确保currentId接收int类型 final songId = song['id']; - currentId.value = songId is int - ? songId - : (int.tryParse(songId?.toString() ?? '0') ?? 0); + currentId.value = songId ?? 0; // 重置进度状态 currentPosition.value = 0; duration.value = 0; progress.value = 0.0; - final id = song['id'] ?? ""; + final id = song['id'] ?? 0; final timestampMs = song['ts'] ?? 0; // 检查URL是否需要刷新(只有当有时间戳时才检查) @@ -1382,9 +1379,7 @@ class AgentController extends GetxController { song["url"] = urldata['url'] ?? ''; // 修复:确保currentId接收int类型 final newSongId = song['id']; - currentId.value = newSongId is int - ? newSongId - : (int.tryParse(newSongId?.toString() ?? '0') ?? 0); + currentId.value = newSongId ?? 0; Logger.d(TAG, '获取新URL成功'); } catch (e) { Logger.e(TAG, '获取新URL失败: $e'); @@ -1394,8 +1389,8 @@ class AgentController extends GetxController { } // 转换为MusicManager期望的格式 - final musicData = { - 'id': song['id']?.toString() ?? '', + final musicData = { + 'id': song['id'], 'url': song['url']?.toString() ?? '', 'title': song['title']?.toString() ?? song['name']?.toString() ?? '', 'artist': @@ -1521,10 +1516,10 @@ class AgentController extends GetxController { } // 获取播放进度 - Future updateMusicProgress1(String currentIdInternal, int newPosition, + Future updateMusicProgress1(int currentIdInternal, int newPosition, int newDuration, double newProgress) async { try { - if (int.parse(currentIdInternal) != 0) { + if (currentIdInternal != 0) { isPlaying.value = true; // return; // 如果没有在播放,直接返回 } @@ -1533,11 +1528,11 @@ class AgentController extends GetxController { // final newPosition = progressInfo['currentPosition'] ?? 0; // final newDuration = progressInfo['duration'] ?? 0; // final newProgress = progressInfo['progress'] ?? 0.0; - print( - "updateMusicProgress1:currentIdInternal:$currentIdInternal newPosition:$newPosition newDuration:$newDuration newProgress:$newProgress"); + // print( + // "updateMusicProgress1:currentIdInternal:$currentIdInternal newPosition:$newPosition newDuration:$newDuration newProgress:$newProgress"); bool hasUpdate = false; - if (currentId.value != int.parse(currentIdInternal)) { - currentId.value = int.parse(currentIdInternal); + if (currentId.value != currentIdInternal) { + currentId.value = currentIdInternal; hasUpdate = true; } // 只有当值发生变化时才更新,避免不必要的UI刷新 @@ -1610,7 +1605,7 @@ class AgentController extends GetxController { } // 跳转到指定位置 - Future seekToPosition1(String currentIdInternal, int newPosition, + Future seekToPosition1(int currentIdInternal, int newPosition, int newDuration, double newProgress) async { try { //await _musiceManager.seekTo(positionMs); @@ -1676,7 +1671,7 @@ class AgentController extends GetxController { // 设置加载状态 isLoadingMusic.value = true; - loadingMusicId.value = playlist[0]['id']?.toString() ?? ''; + loadingMusicId.value = playlist[0]['id']; // 重置播放状态 isPlaying.value = true; @@ -1687,7 +1682,7 @@ class AgentController extends GetxController { // 格式化歌曲列表数据 final formattedPlaylist = playlist.map((song) { return { - 'id': song['id']?.toString() ?? '', + 'id': song['id'], 'url': song['url']?.toString() ?? '', 'title': song['title']?.toString() ?? song['name']?.toString() ?? '', 'artist': @@ -1702,7 +1697,7 @@ class AgentController extends GetxController { // 更新当前播放歌曲ID if (formattedPlaylist.isNotEmpty) { - currentId.value = int.tryParse(formattedPlaylist[0]['id'] ?? '0') ?? 0; + currentId.value = formattedPlaylist[0]['id'] ?? 0; } // 启动进度定时器 @@ -1726,7 +1721,7 @@ class AgentController extends GetxController { } finally { // 清除加载状态 isLoadingMusic.value = false; - loadingMusicId.value = ''; + loadingMusicId.value = 0; } } @@ -1778,7 +1773,7 @@ class AgentController extends GetxController { // 查找当前歌曲在列表中的索引 int index = -1; for (int i = 0; i < playlist.length; i++) { - if (int.tryParse(playlist[i]['id']?.toString() ?? '0') == songId) { + if (playlist[i]['id'] == songId) { index = i; break; } @@ -1837,10 +1832,10 @@ class AgentController extends GetxController { } /// 处理来自系统通知栏的跳转操作 - Future onMediaSessionSeekTo1(String currentIdInternal, int newPosition, + Future onMediaSessionSeekTo1(int currentIdInternal, int newPosition, int newDuration, double newProgress) async { - print( - "onMediaSessionSeekTo1 currentIdInternal :$currentIdInternal ,newPosition:$newPosition newDuration:$newDuration newProgress:$newProgress"); + // print( + // "onMediaSessionSeekTo1 currentIdInternal :$currentIdInternal ,newPosition:$newPosition newDuration:$newDuration newProgress:$newProgress"); await seekToPosition1( currentIdInternal, newPosition, newDuration, newProgress); } diff --git a/lib/modules/agent/views/music_card.dart b/lib/modules/agent/views/music_card.dart index f4af0c4fb..e00cb158a 100644 --- a/lib/modules/agent/views/music_card.dart +++ b/lib/modules/agent/views/music_card.dart @@ -200,7 +200,7 @@ Widget buildMusicContent( ...playlist.asMap().entries.take(4).map((entry) { final index = entry.key; final item = entry.value; - final id = item["id"] ?? 0; + final id = item["id"]; final name = item["name"] ?? "未知歌曲"; final url = item["url"] ?? ""; final singer = item["sgener"] ?? "未知歌手"; diff --git a/lib/modules/music/views/music_playlist_view.dart b/lib/modules/music/views/music_playlist_view.dart index 69fa15a85..ec63a75c2 100644 --- a/lib/modules/music/views/music_playlist_view.dart +++ b/lib/modules/music/views/music_playlist_view.dart @@ -1,8 +1,6 @@ import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:flutter/services.dart'; - import '../../../core/utils/logger.dart'; import '../../agent/controllers/agent_controller.dart'; import '../../agent/views/circular_progress_button.dart'; @@ -80,12 +78,11 @@ class MusicPlaylistView extends StatelessWidget { if (controller.currentId.value != 0) { try { currentSong = playlist.firstWhere( - (song) => - int.tryParse(song['id']?.toString() ?? '0') == - controller.currentId.value, + (song) => song['id'] == controller.currentId.value, ); } catch (e) { // 如果没找到,使用第一首歌曲 + currentSong = playlist.isNotEmpty ? playlist.first : null; } } else { @@ -192,7 +189,7 @@ class MusicPlaylistView extends StatelessWidget { itemCount: playlist.length, itemBuilder: (context, index) { final item = playlist[index]; - final id = item["id"]?.toString() ?? ""; + final id = item["id"] ?? 0; final name = item["name"] ?? "未知歌曲"; final url = item["url"] ?? ""; final singer = item["singer"] ?? item["sgener"] ?? "未知歌手"; @@ -215,7 +212,7 @@ class MusicPlaylistView extends StatelessWidget { Widget _buildMusicItem( BuildContext context, AgentController controller, - String id, + int id, String name, String url, String singer, @@ -323,7 +320,7 @@ class MusicPlaylistView extends StatelessWidget { SizedBox(width: 14.w), // 播放按钮 Obx(() { - final currentIdInt = int.tryParse(id) ?? 0; + final currentIdInt = id; final isThisPlaying = controller.isPlaying.value && controller.currentId.value == currentIdInt; final currentProgress = @@ -601,7 +598,7 @@ class MusicPlaylistView extends StatelessWidget { // 播放选中的歌曲 void _playSelectedSong(AgentController controller, Map song, List> playlist) { - final songId = int.tryParse(song['id']?.toString() ?? '0') ?? 0; + final songId = song['id'] ?? 0; controller.updateCurrentPlaylistContext(playlist, songId); controller.musicPlay(song); } diff --git a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt index 132b8efa1..b51f5aa2b 100644 --- a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt +++ b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt @@ -1447,12 +1447,12 @@ object AgentService : CoroutineScope { // Log.d(TAG, "mcp调用结果: $metaStr") if (meta.has("card_music")) { //音乐卡片 val cardMusic = meta.getJSONObject("card_music") - val id = cardMusic.optInt("id", 0) + val id = cardMusic.optLong("id", 0) val url = cardMusic.optString("url", "") val name = cardMusic.optString("name", "") val sgener = cardMusic.optString("sgener", "") val image = cardMusic.optString("image", "") - val ts = cardMusic.optInt("ts", 0) + val ts = cardMusic.optLong("ts", 0) processMusicPlay( mapOf( "id" to id, @@ -1470,12 +1470,12 @@ object AgentService : CoroutineScope { val playlist = mutableListOf>() for (i in 0 until musics.length()) { val item = musics.optJSONObject(i) ?: continue - val id = item.optInt("id", 0) + val id = item.optLong("id", 0) val url = item.optString("url", "") val name = item.optString("name", "") val sgener = item.optString("sgener", "") val image = item.optString("image", "") - val ts = item.optInt("ts", 0) + val ts = item.optLong("ts", 0) playlist.add( mapOf( "id" to id, diff --git a/local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicService.kt b/local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicService.kt index 2e11c4301..0956f50d8 100644 --- a/local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicService.kt +++ b/local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicService.kt @@ -38,7 +38,7 @@ class MusicService : MediaBrowserServiceCompat() { private const val DELETE_ACTION = "com.yunqiinnovation.music_service.DELETE_NOTIFICATION" private val isRunning = AtomicBoolean(false) - private var currentIdInternal: String? = null + private var currentIdInternal: Long? = null private var currentStatus = false private var playlist = mutableListOf>() private var currentIndex = 0 @@ -48,7 +48,7 @@ class MusicService : MediaBrowserServiceCompat() { fun isServiceRunning() = isRunning.get() fun isPlaying() = currentStatus - fun getCurrentId(): String? = currentIdInternal + fun getCurrentId(): Long? = currentIdInternal // // 获取播放进度信息 // fun getProgress(): Map { @@ -118,11 +118,11 @@ class MusicService : MediaBrowserServiceCompat() { fun updateMediaSessionMetadata(song: Map) { instance?.let { service -> try { - val title = song["title"] as? String ?: song["name"] as? String ?: "未知标题" - val artist = song["artist"] as? String ?: song["sgener"] as? String ?: "未知歌手" - val coverUrl = song["coverUrl"] as? String ?: song["image"] as? String ?: "" -currentIdInternal = song["id"] as? String ?: song["id"] as? String ?: "0" - Log.i(TAG, "updateMediaSessionMetadata currentIdInternal: $currentIdInternal") + val title = song["title"] as? String ??: "未知标题" + val artist = song["artist"] as? String ??: "未知歌手" + val coverUrl = song["coverUrl"] as? String ??: "" + currentIdInternal = (song["id"] as? Number)?.toLong() ?: 0L + Log.i(TAG, "updateMediaSessionMetadata currentIdInternal: $currentIdInternal") val metadata = android.support.v4.media.MediaMetadataCompat.Builder() .putString(android.support.v4.media.MediaMetadataCompat.METADATA_KEY_TITLE, title) .putString(android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ARTIST, artist) @@ -216,13 +216,12 @@ private fun updateProgress() { // 更新媒体会话进度 // 通知Flutter层 - flutterChannel?.invokeMethod("onMediaSessionSeekTo1", - mapOf( + flutterChannel?.invokeMethod("onMediaSessionSeekTo1", mapOf( "currentIdInternal" to currentIdInternal, - "currentPosition" to currentPosition, - "duration" to duration, - "progress" to progress - )) + "currentPosition" to currentPosition, + "duration" to duration, + "progress" to progress + )) } } } @@ -238,19 +237,20 @@ private fun updateProgress() { when (command) { "play" -> intent.getSerializableExtra("song")?.let { url -> val songMap = intent.getSerializableExtra("song") as? Map + Log.i(TAG, "MusicePlay onStartCommand: $songMap") songMap?.let { song -> - val songId = song["id"]as? String ?:"0" - Log.i(TAG, "command songId: $songId") + val songId = (song["id"] as? Number)?.toLong() ?: 0L + currentIdInternal = songId - val existingIndex = playlist.indexOfFirst { it["id"] == songId } + val existingIndex = playlist.indexOfFirst { it["id"] == songId} if (existingIndex == -1) { playlist.add(song) currentIndex = playlist.size - 1 } else { currentIndex = existingIndex } - + Log.i(TAG, "MusicePlay songId: $songId currentIndex:$currentIndex" ) play(song) } } @@ -546,8 +546,8 @@ private fun updateProgress() { private fun play(song: Map) { val url = song["url"] as? String ?: return Log.i(TAG, "开始播放: $url") - val id = song["id"] as? String ?: "0" - Log.i(TAG, "开始播放play id: $id") + val id = (song["id"] as? Number)?.toLong() ?: 0L + Log.i(TAG, "开始播放play id: $id") val title = song["title"] as? String ?: "未知标题" val artist = song["artist"] as? String ?: "未知歌手" val coverUrl = song["coverUrl"] as String @@ -586,8 +586,8 @@ private fun updateProgress() { val title = song["title"] as? String ?: "未知标题" val artist = song["artist"] as? String ?: "未知歌手" val coverUrl = song["coverUrl"] as String - val id = song["id"] as? String ?: "0" - Log.i(TAG, "pause id: $id") + val id =(song["id"] as? Number)?.toLong() ?: 0L + Log.i(TAG, "pause id: $id") currentIdInternal = id updateNotification(title,artist,coverUrl) setPlaybackState(PlaybackStateCompat.STATE_PAUSED); @@ -607,8 +607,8 @@ private fun updateProgress() { val title = song["title"] as? String ?: "未知标题" val artist = song["artist"] as? String ?: "未知歌手" val coverUrl = song["coverUrl"] as String - val id = song["id"] as? String ?: "0" - Log.i(TAG, "resume id: $id") + val id = (song["id"] as? Number)?.toLong() ?: 0L + Log.i(TAG, "resume id: $id") currentIdInternal = id updateNotification(title,artist,coverUrl) setPlaybackState(PlaybackStateCompat.STATE_PLAYING); diff --git a/local_plugins/music_service/lib/music_service.dart b/local_plugins/music_service/lib/music_service.dart index 8be33fe68..b6401acd1 100644 --- a/local_plugins/music_service/lib/music_service.dart +++ b/local_plugins/music_service/lib/music_service.dart @@ -1,3 +1,5 @@ +import 'dart:ffi'; + import 'package:flutter/services.dart'; class MusicService { @@ -101,7 +103,7 @@ class MusicService { required Function() onPrevious, required Function(int) onSeekTo, required Function() onStop, - required Function(String, int, int, double) onStop1, + required Function(int, int, int, double) onStop1, }) async { // 设置方法调用处理器来处理来自原生平台的回调 _methodChannel.setMethodCallHandler((call) async { @@ -126,8 +128,7 @@ class MusicService { onStop(); break; case 'onMediaSessionSeekTo1': - final currentIdInternal = - call.arguments['currentIdInternal'] as String; + final currentIdInternal = call.arguments['currentIdInternal'] as int; final currentPosition = call.arguments['currentPosition'] as int; final duration = call.arguments['duration'] as int; final progress = call.arguments['progress'] as double;