Browse Source

上传qq音乐服务代码

weicu
liwei1dao 1 year ago
parent
commit
495a5cfe76
  1. 4
      android/app/sign/DeepSound.properties
  2. 36
      lib/modules/qqmusic/controllers/qqmusic_playlist_controller.dart
  3. 2
      local_plugins/qq_music/android/src/main/kotlin/com/yunqiinnovation/qq_music/QQMusicLoginManager.kt
  4. 21
      local_plugins/qq_music/android/src/main/kotlin/com/yunqiinnovation/qq_music/QQMusicManager.kt
  5. 41
      local_plugins/qq_music/android/src/main/kotlin/com/yunqiinnovation/qq_music/QQMusicSingleton.kt
  6. 43
      local_plugins/qq_music/android/src/main/kotlin/com/yunqiinnovation/qq_music/util/QPlayBindHelper.kt

4
android/app/sign/DeepSound.properties

@ -1,4 +0,0 @@
storePassword=13071376716
keyPassword=13071376716
keyAlias=DeepSound
storeFile=sign/DeepSound.keystore

36
lib/modules/qqmusic/controllers/qqmusic_playlist_controller.dart

@ -1,3 +1,5 @@
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import '../../../data/models/song_model.dart';
import '../../../data/services/qq_musoc.dart';
@ -22,6 +24,16 @@ class QQMusicPlaylistController extends GetxController {
void onInit() {
super.onInit();
// 使用 WidgetsBinding.instance.addPostFrameCallback 延迟执行状态更新
WidgetsBinding.instance.addPostFrameCallback((_) {
_initializePlaylist();
});
print('🎵 [QQMusicPlaylistController] 控制器初始化完成');
}
/// 初始化播放列表 - 延迟执行避免构建期间状态更新
void _initializePlaylist() {
// 从路由参数获取播放列表
final arguments = Get.arguments;
if (arguments != null && arguments['playlist'] != null) {
@ -76,11 +88,9 @@ class QQMusicPlaylistController extends GetxController {
// 界面初始化时同步播放状态和进度
_syncInitialState();
print('🎵 [QQMusicPlaylistController] 控制器初始化完成');
}
/// 同步初始播放状态
/// 同步初始播放状态 - 移除 update() 调用
Future<void> _syncInitialState() async {
try {
Logger.d('QQMusicPlaylist', '开始同步初始播放状态');
@ -94,8 +104,8 @@ class QQMusicPlaylistController extends GetxController {
_qqMusicService.startPlaybackStateMonitor();
}
// 触发UI更新
update();
// 移除这行,避免在构建期间调用 update()
// update();
Logger.d('QQMusicPlaylist', '初始状态同步完成');
} catch (e) {
@ -103,6 +113,16 @@ class QQMusicPlaylistController extends GetxController {
}
}
/// 音乐状态变化回调 - 使用 SchedulerBinding 延迟更新
void _onMusicStateChanged() {
// 使用 SchedulerBinding 确保在构建完成后再更新
SchedulerBinding.instance.addPostFrameCallback((_) {
if (!isClosed) {
update();
}
});
}
@override
void onClose() {
// 移除状态监听器
@ -110,12 +130,6 @@ class QQMusicPlaylistController extends GetxController {
super.onClose();
}
/// 音乐状态变化回调
void _onMusicStateChanged() {
// 触发UI更新
update();
}
/// 播放歌曲
Future<void> playSong(SongModel song, {List<SongModel>? songList}) async {
try {

2
local_plugins/qq_music/android/src/main/kotlin/com/yunqiinnovation/qq_music/QQMusicLoginManager.kt

@ -76,7 +76,7 @@ class QQMusicLoginManager(private val activity: Activity) {
} else {
Log.e(TAG, "QQ音乐服务绑定失败")
callback.onError("BIND_FAILED", "绑定QQ音乐服务失败,请确保已安装QQ音乐")
callback.onError("APP_NOT_INSTALLED", "请先安装QQ音乐App才能使用音乐功能")
}
}
}

21
local_plugins/qq_music/android/src/main/kotlin/com/yunqiinnovation/qq_music/QQMusicManager.kt

@ -5,6 +5,7 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
import android.os.Bundle
import android.os.IBinder
import android.util.Log
@ -275,6 +276,7 @@ class QQMusicManager(private val activity: Activity) {
index: Int = 0,
callback: PlayCallback
) {
if (!isBindQQMusicService || qqmusicApi == null) {
callback.onError(-1, "QQ音乐服务未连接")
return
@ -303,6 +305,7 @@ class QQMusicManager(private val activity: Activity) {
* 播放音乐
*/
fun playMusic(callback: PlayCallback) {
if (!isBindQQMusicService || qqmusicApi == null) {
callback.onError(-1, "QQ音乐服务未连接")
return
@ -614,10 +617,24 @@ class QQMusicManager(private val activity: Activity) {
if (isBindQQMusicService) {
activity.unbindService(serviceConnection)
isBindQQMusicService = false
Log.d(TAG, "QQ音乐服务已解绑")
}
} catch (e: Exception) {
Log.e(TAG, "清理资源异常", e)
Log.e(TAG, "解绑QQ音乐服务失败", e)
}
}
/**
* 获取当前平台对应的QQ音乐包名
*/
private fun getQQMusicPackageName(): String {
return when (Config.BIND_PLATFORM) {
CommonCmd.AIDL_PLATFORM_TYPE_PHONE -> "com.tencent.qqmusic"
CommonCmd.AIDL_PLATFORM_TYPE_CAR -> "com.tencent.qqmusiccar"
CommonCmd.AIDL_PLATFORM_TYPE_TV -> "com.tencent.qqmusictv"
else -> "com.tencent.qqmusic"
}
qqmusicApi = null
}
}

41
local_plugins/qq_music/android/src/main/kotlin/com/yunqiinnovation/qq_music/QQMusicSingleton.kt

@ -3,6 +3,7 @@ package com.yunqiinnovation.qq_music
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.os.Handler
import android.os.Looper
import android.util.Log
@ -56,7 +57,32 @@ class QQMusicSingleton private constructor() {
loadSavedLoginInfo()
Log.d(TAG, "QQ音乐单例初始化完成")
}
/**
* 检查QQ音乐App是否已安装
*/
private fun isQQMusicInstalled(): Boolean {
val packageName = when (Config.BIND_PLATFORM) {
CommonCmd.AIDL_PLATFORM_TYPE_PHONE -> "com.tencent.qqmusic"
CommonCmd.AIDL_PLATFORM_TYPE_CAR -> "com.tencent.qqmusiccar"
CommonCmd.AIDL_PLATFORM_TYPE_TV -> "com.tencent.qqmusictv"
else -> {
Log.e(TAG, "不支持的平台类型: ${Config.BIND_PLATFORM}")
return false
}
}
return try {
this.activity?.packageManager?.getPackageInfo(packageName, 0)
Log.d(TAG, "QQ音乐app已安装: $packageName")
true
} catch (e: PackageManager.NameNotFoundException) {
Log.w(TAG, "QQ音乐app未安装: $packageName")
false
} catch (e: Exception) {
Log.e(TAG, "检查QQ音乐app安装状态失败", e)
false
}
}
/**
* 检查是否已登录且未过期
*/
@ -88,6 +114,11 @@ class QQMusicSingleton private constructor() {
* 登录接口
*/
fun login(callback: (Result<LoginResult>) -> Unit) {
if (!isQQMusicInstalled()){
callback(Result.failure(Exception("未安装QQ音乐软件,请先安装QQ音乐软件")))
return
}
// 先检查是否已经登录且未过期
if (isLoggedIn()) {
Log.d(TAG, "用户已登录且未过期,直接返回登录信息")
@ -140,6 +171,10 @@ class QQMusicSingleton private constructor() {
searchType: Int = Data.SearchType.SEARCH_TYPE_SONG,
callback: (Result<List<Map<String, Any?>>>) -> Unit
) {
if (!isQQMusicInstalled()){
callback(Result.failure(Exception("未安装QQ音乐软件,请先安装QQ音乐软件")))
return
}
searchWithRetry(keyword, searchType, 0, callback)
}
@ -264,12 +299,16 @@ class QQMusicSingleton private constructor() {
index: Int = 0,
callback: (Result<Unit>) -> Unit
) {
val currentActivity = activity
if (currentActivity == null) {
callback(Result.failure(Exception("Activity not available")))
return
}
if (!isQQMusicInstalled()){
callback(Result.failure(Exception("未安装QQ音乐软件,请先安装QQ音乐软件")))
return
}
ensureMusicManager(currentActivity)
musicManager?.playSongs(songMids, index, object : QQMusicManager.PlayCallback {
override fun onSuccess() {

43
local_plugins/qq_music/android/src/main/kotlin/com/yunqiinnovation/qq_music/util/QPlayBindHelper.kt

@ -4,6 +4,7 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
import android.os.Handler
import android.os.IBinder
import android.os.Looper
@ -12,6 +13,7 @@ import android.widget.Toast
import com.tencent.qqmusic.third.api.contract.CommonCmd
import com.tencent.qqmusic.third.api.contract.CommonCmd.AIDL_PLATFORM_TYPE_PHONE
import com.tencent.qqmusic.third.api.contract.IQQMusicApi
import com.yunqiinnovation.qq_music.Config
class QPlayBindHelper(private val context: Context, private val bindPlatform: String = AIDL_PLATFORM_TYPE_PHONE) {
companion object {
@ -104,11 +106,50 @@ class QPlayBindHelper(private val context: Context, private val bindPlatform: St
bindQQMusic(callback)
}
/**
* 检查QQ音乐App是否已安装
*/
private fun isQQMusicInstalled(): Boolean {
return try {
val packageName = getQQMusicPackageName()
context.packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES)
true
} catch (e: PackageManager.NameNotFoundException) {
Log.w(TAG, "QQ音乐App未安装: ${e.message}")
false
}
}
/**
* 获取QQ音乐包名
*/
private fun getQQMusicPackageName(): String {
return when (Config.BIND_PLATFORM) {
CommonCmd.AIDL_PLATFORM_TYPE_PHONE -> "com.tencent.qqmusic"
CommonCmd.AIDL_PLATFORM_TYPE_CAR -> "com.tencent.qqmusiccar"
CommonCmd.AIDL_PLATFORM_TYPE_TV -> "com.tencent.qqmusictv"
else -> "com.tencent.qqmusic"
}
}
fun ensureQQMusicBindByStartProcess(isStartProcess: Boolean = true, callback: ((Boolean) -> Unit)? = null) {
// 首先检查QQ音乐是否已安装
if (!isQQMusicInstalled()) {
Log.e(TAG, "QQ音乐App未安装,无法绑定服务")
callback?.invoke(false)
return
}
bindQQMusic({ succeed ->
if (!succeed) {
if (isStartProcess) {
CommonCmd.startQQMusicProcess(context, context.packageName)
try {
CommonCmd.startQQMusicProcess(context, context.packageName)
} catch (e: Exception) {
Log.e(TAG, "启动QQ音乐进程失败: ${e.message}")
callback?.invoke(false)
return@bindQQMusic
}
}
handler.postDelayed({
ensureQQMusicBindByStartProcess(false, callback)

Loading…
Cancel
Save