From 36b0a8ea90591cc8fc8ef6b8de823a673235acff Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Mon, 12 May 2025 15:20:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E8=80=B3=E6=9C=BA=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E5=BC=80=E5=85=B3=20=E6=96=B9=E4=BE=BF=E8=B0=83?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/pairing_controller.dart | 21 +++-- .../music_service/android/build.gradle | 1 + .../android/src/main/AndroidManifest.xml | 9 +- .../music_service/MusicService.kt | 87 ++++++++++++++++--- 4 files changed, 99 insertions(+), 19 deletions(-) diff --git a/lib/modules/pairing/controllers/pairing_controller.dart b/lib/modules/pairing/controllers/pairing_controller.dart index 44a30fa2c..d83d043dd 100644 --- a/lib/modules/pairing/controllers/pairing_controller.dart +++ b/lib/modules/pairing/controllers/pairing_controller.dart @@ -15,6 +15,8 @@ import 'package:ble_service/ble_service.dart'; class PairingController extends GetxController { static PairingController get to => Get.find(); + //是否需要连接耳机 + final isneedearphone = false; // 状态标志 final isLoading = false.obs; @@ -196,13 +198,17 @@ class PairingController extends GetxController { } _updateStatusDescription(); }); + if (!isneedearphone) { + //不需要耳机 + _handleDeviceConnected(); + } } /// 处理设备连接成功事件 Future _handleDeviceConnected() async { - if (!isDeviceConnected || _isNavigatingToHome) return; + if ((!isDeviceConnected && isneedearphone) || _isNavigatingToHome) return; // 如果已经完成关联,直接跳转 - if (_companionAssociated.value) { + if (isneedearphone && _companionAssociated.value) { _autoNavigateToHome(); return; } @@ -306,7 +312,6 @@ class PairingController extends GetxController { Logger.info('已关联的Companion设备与当前连接的设备一致'); _companionAssociated.value = true; await _bleService.registerBackgroundScan(); - // 调试情况下注释 保证正常能启动服务 // _autoNavigateToHome(); // return; } else { @@ -323,8 +328,6 @@ class PairingController extends GetxController { deviceNamePattern: currentDevice!.name, macAddress: currentDevice!.address, ); - Logger.info('Companion设备关联结果: $success'); - success = true; //李伟测试用,去掉关联流程 if (success) { Logger.info('Companion设备关联成功'); _companionAssociated.value = true; @@ -342,6 +345,12 @@ class PairingController extends GetxController { // 关联失败,但仍然可以跳转到主页(用户体验考虑) _autoNavigateToHome(); } + } else if (!isneedearphone) { + // 启动BLE后台服务(可选) + await _startAgentService(); + + // 关联和后台扫描都成功后,再跳转 + _autoNavigateToHome(); } } catch (e) { Logger.error('Companion设备关联过程发生错误: $e'); @@ -382,7 +391,7 @@ class PairingController extends GetxController { /// 启动BLE后台服务 Future _startAgentService() async { try { - if (!isDeviceConnected) return; + if (isneedearphone && !isDeviceConnected) return; // 启动BLE服务,无需传递配置参数,将从.env读取 final result = await BleManager.to.startAgentService(); diff --git a/local_plugins/music_service/android/build.gradle b/local_plugins/music_service/android/build.gradle index 8c1602312..3a98cc976 100644 --- a/local_plugins/music_service/android/build.gradle +++ b/local_plugins/music_service/android/build.gradle @@ -67,4 +67,5 @@ android { dependencies { implementation project(':deepvoice_utils') + implementation("androidx.media:media:1.6.0") } diff --git a/local_plugins/music_service/android/src/main/AndroidManifest.xml b/local_plugins/music_service/android/src/main/AndroidManifest.xml index bacfd3dee..334dcc16a 100644 --- a/local_plugins/music_service/android/src/main/AndroidManifest.xml +++ b/local_plugins/music_service/android/src/main/AndroidManifest.xml @@ -3,7 +3,6 @@ - @@ -13,5 +12,13 @@ android:exported="false" android:enabled="true" android:foregroundServiceType="mediaPlayback" /> + + + + + + 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 0e3d34c3f..fd09c5a7c 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 @@ -9,6 +9,8 @@ import android.os.Build import android.os.IBinder import android.util.Log import androidx.core.app.NotificationCompat +import android.support.v4.media.session.MediaSessionCompat +import android.support.v4.media.session.PlaybackStateCompat import com.yunqiinnovation.deepvoice_utils.FileLogger import java.util.concurrent.atomic.AtomicBoolean @@ -28,7 +30,7 @@ class MusicService : Service() { fun isPlaying(): Boolean = currentStatus fun getCurrentUrl(): String? = currentUrlInternal } - + private lateinit var mediaSession: MediaSessionCompat private var mediaPlayer: MediaPlayer? = null private val playlist = mutableListOf() // 可选:初始化为预置歌曲 private var currentIndex = 0 @@ -38,9 +40,38 @@ class MusicService : Service() { FileLogger.init(this) FileLogger.i(TAG, "MusicService 正在创建...") isRunning.set(true) - Log.i(TAG, "MusicService Created") + mediaSession = MediaSessionCompat(this, TAG).apply { + setCallback(object : MediaSessionCompat.Callback() { + override fun onPlay() { + resume() + } + + override fun onPause() { + pause() + } + + override fun onSkipToNext() { + if (currentIndex + 1 < playlist.size) { + currentIndex++ + play(playlist[currentIndex]) + } + } + + override fun onSkipToPrevious() { + if (currentIndex - 1 >= 0) { + currentIndex-- + play(playlist[currentIndex]) + } + } + + override fun onStop() { + stopSelf() + } + }) + isActive = true + } startForeground(NOTIFICATION_ID, createNotification("等待播放...")) - isRunning.set(true) + Log.i(TAG, "MusicService Created") } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { @@ -173,15 +204,14 @@ class MusicService : Service() { manager.createNotificationChannel(channel) } - val intent = packageManager.getLaunchIntentForPackage(packageName)?.apply { - flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP - } - val pendingIntent = intent?.let { - PendingIntent.getActivity( - this, 0, it, - PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - ) - } + // 修复 pendingIntent:打开 App 主 Activity + val activityIntent = packageManager.getLaunchIntentForPackage(packageName) + val pendingIntent = PendingIntent.getActivity( + this, + 0, + activityIntent, + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + ) return NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("DeepSound") @@ -189,6 +219,39 @@ class MusicService : Service() { .setSmallIcon(android.R.drawable.ic_media_play) .setContentIntent(pendingIntent) .setOngoing(true) + .setStyle( + androidx.media.app.NotificationCompat.MediaStyle() + .setMediaSession(mediaSession.sessionToken) + .setShowActionsInCompactView(0, 1, 2) + ) + .addAction( + NotificationCompat.Action( + android.R.drawable.ic_media_previous, "上一曲", + androidx.media.session.MediaButtonReceiver.buildMediaButtonPendingIntent( + this, + PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS + ) + ) + ) + .addAction( + NotificationCompat.Action( + if (currentStatus) android.R.drawable.ic_media_pause else android.R.drawable.ic_media_play, + if (currentStatus) "暂停" else "播放", + androidx.media.session.MediaButtonReceiver.buildMediaButtonPendingIntent( + this, + PlaybackStateCompat.ACTION_PLAY_PAUSE + ) + ) + ) + .addAction( + NotificationCompat.Action( + android.R.drawable.ic_media_next, "下一曲", + androidx.media.session.MediaButtonReceiver.buildMediaButtonPendingIntent( + this, + PlaybackStateCompat.ACTION_SKIP_TO_NEXT + ) + ) + ) .build() }