|
|
|
@ -8,8 +8,6 @@ import android.os.Handler |
|
|
|
import android.os.Looper |
|
|
|
import android.util.Log |
|
|
|
import com.tencent.qqmusic.third.api.contract.* |
|
|
|
import java.text.SimpleDateFormat |
|
|
|
import java.util.* |
|
|
|
|
|
|
|
/** |
|
|
|
* QQ音乐单例管理器 |
|
|
|
@ -23,11 +21,6 @@ class QQMusicSingleton private constructor() { |
|
|
|
private const val KEY_OPEN_ID = "open_id" |
|
|
|
private const val KEY_OPEN_TOKEN = "open_token" |
|
|
|
private const val KEY_EXPIRE_TIME = "expire_time" |
|
|
|
private const val LOGIN_WAIT_DELAY_MS = 30000L |
|
|
|
// 添加搜索重试相关常量 |
|
|
|
private const val SEARCH_TIMEOUT_MS = 10000L |
|
|
|
private const val MAX_RETRY_COUNT = 1 |
|
|
|
private const val RETRY_DELAY_MS = 1000L |
|
|
|
|
|
|
|
@Volatile |
|
|
|
private var INSTANCE: QQMusicSingleton? = null |
|
|
|
@ -53,9 +46,9 @@ class QQMusicSingleton private constructor() { |
|
|
|
*/ |
|
|
|
fun initialize(context: Context) { |
|
|
|
this.context = context |
|
|
|
this.sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) |
|
|
|
loadSavedLoginInfo() |
|
|
|
Log.d(TAG, "QQ音乐单例初始化完成") |
|
|
|
// this.sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) |
|
|
|
// loadSavedLoginInfo() |
|
|
|
// Log.d(TAG, "QQ音乐单例初始化完成") |
|
|
|
} |
|
|
|
/** |
|
|
|
* 检查QQ音乐App是否已安装 |
|
|
|
@ -87,58 +80,54 @@ class QQMusicSingleton private constructor() { |
|
|
|
* 检查是否已登录且未过期 |
|
|
|
*/ |
|
|
|
fun isLoggedIn(): Boolean { |
|
|
|
if (currentLoginResult == null){ |
|
|
|
loadSavedLoginInfo() |
|
|
|
if (currentLoginResult == null){ |
|
|
|
return false |
|
|
|
} |
|
|
|
return true |
|
|
|
}else{ |
|
|
|
return true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 获取当前登录信息 |
|
|
|
*/ |
|
|
|
fun getCurrentLoginInfo(): LoginResult? { |
|
|
|
return if (isLoggedIn()) currentLoginResult else null |
|
|
|
return loginManager != null && loginManager!!.isLogined |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 登录接口 |
|
|
|
*/ |
|
|
|
fun login(callback: (Result<LoginResult>) -> Unit) { |
|
|
|
fun login(callback: (Result<Unit>) -> Unit) { |
|
|
|
if (!isQQMusicInstalled()){ |
|
|
|
callback(Result.failure(Exception("未安装QQ音乐软件,请先安装QQ音乐软件"))) |
|
|
|
return |
|
|
|
} |
|
|
|
val currentActivity = context |
|
|
|
val currentContext = context |
|
|
|
// 先检查是否已经登录且未过期 |
|
|
|
if (isLoggedIn()) { |
|
|
|
Log.d(TAG, "用户已登录且未过期,直接返回登录信息") |
|
|
|
ensureMusicManager(currentActivity!!) |
|
|
|
callback(Result.success(currentLoginResult!!)) |
|
|
|
ensureMusicManager(currentContext!!,object: QQMusicManager. BindCallback{ |
|
|
|
override fun onSuccess() { |
|
|
|
callback(Result.success(Unit)) |
|
|
|
} |
|
|
|
|
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
callback(Result.failure(Exception("no logined $errorMessage"))) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (currentActivity == null) { |
|
|
|
if (currentContext == null) { |
|
|
|
callback(Result.failure(Exception("Activity not available"))) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
Log.d(TAG, "开始新的登录流程") |
|
|
|
loginManager = QQMusicLoginManager(currentActivity) |
|
|
|
loginManager = QQMusicLoginManager(currentContext) |
|
|
|
loginManager?.startLogin(object : QQMusicLoginManager.LoginCallback { |
|
|
|
override fun onSuccess(openId: String, openToken: String, expireTime: String) { |
|
|
|
override fun onSuccess() { |
|
|
|
handler.post { |
|
|
|
ensureMusicManager(currentActivity!!) |
|
|
|
val result = LoginResult(openId, openToken, expireTime) |
|
|
|
currentLoginResult = result |
|
|
|
saveLoginInfo(result) |
|
|
|
Log.d(TAG, "登录成功并已保存: $result") |
|
|
|
callback(Result.success(result)) |
|
|
|
ensureMusicManager(currentContext,object: QQMusicManager. BindCallback{ |
|
|
|
override fun onSuccess() { |
|
|
|
callback(Result.success(Unit)) |
|
|
|
} |
|
|
|
|
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
callback(Result.failure(Exception("no logined $errorMessage"))) |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -164,8 +153,16 @@ class QQMusicSingleton private constructor() { |
|
|
|
// 先检查是否已经登录且未过期 |
|
|
|
if (isLoggedIn()) { |
|
|
|
Log.d(TAG, "用户已登录且未过期,直接返回登录信息") |
|
|
|
ensureMusicManager(currentActivity!!) |
|
|
|
callback(Result.success(currentLoginResult!!)) |
|
|
|
ensureMusicManager(currentActivity!!,object: QQMusicManager. BindCallback{ |
|
|
|
override fun onSuccess() { |
|
|
|
callback(Result.success(currentLoginResult!!)) |
|
|
|
} |
|
|
|
|
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
callback(Result.failure(Exception("no logined $errorMessage"))) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
return |
|
|
|
}else{ |
|
|
|
callback(Result.failure(Exception("no logined"))) |
|
|
|
@ -190,128 +187,11 @@ 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, 1, callback) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 带重试的搜索实现 |
|
|
|
*/ |
|
|
|
private fun searchWithRetry( |
|
|
|
keyword: String, |
|
|
|
searchType: Int, |
|
|
|
retryCount: Int, |
|
|
|
callback: (Result<List<Map<String, Any?>>>) -> Unit |
|
|
|
) { |
|
|
|
val currentActivity = context |
|
|
|
if (currentActivity == null) { |
|
|
|
callback(Result.failure(Exception("Activity not available"))) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// 检查登录状态 |
|
|
|
if (!isLoggedIn()) { |
|
|
|
Log.d(TAG, "搜索前检测到未登录,开始自动登录") |
|
|
|
login { loginResult -> |
|
|
|
if (loginResult.isSuccess) { |
|
|
|
Log.d(TAG, "自动登录成功,等待QQ音乐服务连接...") |
|
|
|
handler.postDelayed({ |
|
|
|
Log.d(TAG, "等待完成,开始搜索") |
|
|
|
performSearchWithTimeout(keyword, searchType, retryCount, callback) |
|
|
|
}, LOGIN_WAIT_DELAY_MS) |
|
|
|
} else { |
|
|
|
callback(Result.failure(Exception("自动登录失败: ${loginResult.exceptionOrNull()?.message}"))) |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
performSearchWithTimeout(keyword, searchType, retryCount, callback) |
|
|
|
} |
|
|
|
executeSearchbackAction("搜索歌曲",0,2) { musicManager, searchCallback -> |
|
|
|
musicManager.searchSongs(keyword,searchType,searchCallback) |
|
|
|
}(callback) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 执行带超时的搜索操作 |
|
|
|
*/ |
|
|
|
private fun performSearchWithTimeout( |
|
|
|
keyword: String, |
|
|
|
searchType: Int, |
|
|
|
retryCount: Int, |
|
|
|
callback: (Result<List<Map<String, Any?>>>) -> Unit |
|
|
|
) { |
|
|
|
val currentActivity = context ?: return |
|
|
|
val searchKey = "${keyword}_${System.currentTimeMillis()}" |
|
|
|
var completed = false |
|
|
|
|
|
|
|
Log.d(TAG, "开始搜索: $keyword (第${retryCount + 1}次)") |
|
|
|
|
|
|
|
// 设置超时 |
|
|
|
val timeoutRunnable = Runnable { |
|
|
|
if (!completed) { |
|
|
|
completed = true |
|
|
|
searchTimeouts.remove(searchKey) |
|
|
|
Log.w(TAG, "搜索超时: $keyword") |
|
|
|
|
|
|
|
if (retryCount < MAX_RETRY_COUNT) { |
|
|
|
Log.d(TAG, "准备重试: ${retryCount + 1}/$MAX_RETRY_COUNT") |
|
|
|
handler.postDelayed({ |
|
|
|
searchWithRetry(keyword, searchType, retryCount + 1, callback) |
|
|
|
}, RETRY_DELAY_MS) |
|
|
|
} else { |
|
|
|
callback(Result.failure(Exception("搜索超时,已重试${MAX_RETRY_COUNT}次"))) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
searchTimeouts[searchKey] = timeoutRunnable |
|
|
|
handler.postDelayed(timeoutRunnable, SEARCH_TIMEOUT_MS) |
|
|
|
|
|
|
|
ensureMusicManager(currentActivity) |
|
|
|
musicManager?.searchSongs(keyword, searchType, object : QQMusicManager.SearchCallback { |
|
|
|
override fun onSuccess(songs: List<Map<String, Any?>>) { |
|
|
|
handler.post { |
|
|
|
if (!completed) { |
|
|
|
completed = true |
|
|
|
searchTimeouts.remove(searchKey)?.let { handler.removeCallbacks(it) } |
|
|
|
Log.d(TAG, "搜索成功: 找到 ${songs.size} 首歌曲") |
|
|
|
callback(Result.success(songs)) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
handler.post { |
|
|
|
if (!completed) { |
|
|
|
completed = true |
|
|
|
searchTimeouts.remove(searchKey)?.let { handler.removeCallbacks(it) } |
|
|
|
Log.e(TAG, "搜索失败: code=$errorCode, message=$errorMessage") |
|
|
|
|
|
|
|
// 如果是登录相关错误,清除本地登录信息 |
|
|
|
if (errorMessage.contains("登录") || errorMessage.contains("授权")) { |
|
|
|
Log.d(TAG, "检测到登录相关错误,清除本地登录信息") |
|
|
|
logout() |
|
|
|
} |
|
|
|
|
|
|
|
// 网络相关错误才重试 |
|
|
|
if (retryCount < MAX_RETRY_COUNT && |
|
|
|
(errorMessage.contains("网络") || errorMessage.contains("超时") || |
|
|
|
errorMessage.contains("连接") || errorCode == -1)) { |
|
|
|
Log.d(TAG, "网络错误,准备重试: ${retryCount + 1}/$MAX_RETRY_COUNT") |
|
|
|
if (errorCode == -1){ |
|
|
|
musicManager?.bindQQMusicApiService() |
|
|
|
} |
|
|
|
handler.postDelayed({ |
|
|
|
searchWithRetry(keyword, searchType, retryCount + 1, callback) |
|
|
|
}, RETRY_DELAY_MS) |
|
|
|
} else { |
|
|
|
callback(Result.failure(Exception("搜索失败: $errorMessage"))) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 播放歌曲列表(带自动登录检查) |
|
|
|
@ -321,8 +201,8 @@ class QQMusicSingleton private constructor() { |
|
|
|
index: Int = 0, |
|
|
|
callback: (Result<Unit>) -> Unit |
|
|
|
) { |
|
|
|
Log.e(TAG, "播放音乐列表: $songMids") |
|
|
|
executePlaybackAction("播放列表") { musicManager, playCallback -> |
|
|
|
executePlaybackAction("播放列表",0,2) { musicManager, playCallback -> |
|
|
|
Log.d(TAG, "播放歌曲:${songMids[index]}") |
|
|
|
musicManager.playSongs(songMids, index,playCallback) |
|
|
|
}(callback) |
|
|
|
} |
|
|
|
@ -331,7 +211,7 @@ class QQMusicSingleton private constructor() { |
|
|
|
* 播放音乐 |
|
|
|
*/ |
|
|
|
fun playMusic(callback: (Result<Unit>) -> Unit) { |
|
|
|
executePlaybackAction("播放") { musicManager, playCallback -> |
|
|
|
executePlaybackAction("播放",0,2) { musicManager, playCallback -> |
|
|
|
musicManager.playMusic(playCallback) |
|
|
|
}(callback) |
|
|
|
} |
|
|
|
@ -386,11 +266,12 @@ class QQMusicSingleton private constructor() { |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 恢复播放 |
|
|
|
*/ |
|
|
|
fun resumeMusic(callback: (Result<Unit>) -> Unit) { |
|
|
|
executePlaybackAction("恢复播放") { musicManager, playCallback -> |
|
|
|
executePlaybackAction("恢复播放",0,0) { musicManager, playCallback -> |
|
|
|
musicManager.resumeMusic(playCallback) |
|
|
|
}(callback) |
|
|
|
} |
|
|
|
@ -399,7 +280,7 @@ class QQMusicSingleton private constructor() { |
|
|
|
* 停止音乐 |
|
|
|
*/ |
|
|
|
fun stopMusic(callback: (Result<Unit>) -> Unit) { |
|
|
|
executePlaybackAction("停止") { musicManager, playCallback -> |
|
|
|
executePlaybackAction("停止",0,0) { musicManager, playCallback -> |
|
|
|
musicManager.stopMusic(playCallback) |
|
|
|
}(callback) |
|
|
|
} |
|
|
|
@ -408,7 +289,7 @@ class QQMusicSingleton private constructor() { |
|
|
|
* 下一首 |
|
|
|
*/ |
|
|
|
fun skipToNext(callback: (Result<Unit>) -> Unit) { |
|
|
|
executePlaybackAction("下一首") { musicManager, playCallback -> |
|
|
|
executePlaybackAction("下一首",0,0) { musicManager, playCallback -> |
|
|
|
musicManager.skipToNext(playCallback) |
|
|
|
}(callback) |
|
|
|
} |
|
|
|
@ -417,7 +298,7 @@ class QQMusicSingleton private constructor() { |
|
|
|
* 上一首 |
|
|
|
*/ |
|
|
|
fun skipToPrevious(callback: (Result<Unit>) -> Unit) { |
|
|
|
executePlaybackAction("上一首") { musicManager, playCallback -> |
|
|
|
executePlaybackAction("上一首",0,0) { musicManager, playCallback -> |
|
|
|
musicManager.skipToPrevious(playCallback) |
|
|
|
}(callback) |
|
|
|
} |
|
|
|
@ -443,60 +324,20 @@ class QQMusicSingleton private constructor() { |
|
|
|
/** |
|
|
|
* 获取播放时间 |
|
|
|
*/ |
|
|
|
fun getPlayTime(callback: (Result<PlayTimeInfo>) -> Unit) { |
|
|
|
val currentActivity = context |
|
|
|
if (currentActivity == null) { |
|
|
|
callback(Result.failure(Exception("Activity not available"))) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
ensureMusicManager(currentActivity) |
|
|
|
musicManager?.getPlayTime(object : QQMusicManager.InfoCallback { |
|
|
|
override fun onSuccess(data: Map<String, Any?>) { |
|
|
|
handler.post { |
|
|
|
val totalTime = data["totalTime"] as? Long ?: 0L |
|
|
|
val currentTime = data["currentTime"] as? Long ?: 0L |
|
|
|
val playTimeInfo = PlayTimeInfo(totalTime, currentTime) |
|
|
|
Log.d(TAG, "获取播放时间成功: $playTimeInfo") |
|
|
|
callback(Result.success(playTimeInfo)) |
|
|
|
} |
|
|
|
} |
|
|
|
fun getPlayTime(callback: (Result<Map<String, Any?>>) -> Unit) { |
|
|
|
executeInfoAction("获取播放时间") { musicManager, infoCallback -> |
|
|
|
musicManager.getPlayTime(infoCallback) |
|
|
|
}(callback) |
|
|
|
|
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
handler.post { |
|
|
|
Log.e(TAG, "获取播放时间失败: $errorMessage") |
|
|
|
callback(Result.failure(Exception("获取播放时间失败: $errorMessage"))) |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 同步当前播放信息 - 统一接口 |
|
|
|
*/ |
|
|
|
fun syncCurrentPlayInfo(callback: (Result<Map<String, Any?>>) -> Unit) { |
|
|
|
val currentcontext = context |
|
|
|
if (currentcontext == null) { |
|
|
|
callback(Result.failure(Exception("Activity not available"))) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
ensureMusicManager(currentcontext) |
|
|
|
musicManager?.syncCurrentPlayInfo(object : QQMusicManager.InfoCallback { |
|
|
|
override fun onSuccess(data: Map<String, Any?>) { |
|
|
|
handler.post { |
|
|
|
Log.d(TAG, "同步播放信息成功") |
|
|
|
callback(Result.success(data)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
handler.post { |
|
|
|
Log.e(TAG, "同步播放信息失败: $errorMessage") |
|
|
|
callback(Result.failure(Exception("同步播放信息失败: $errorMessage"))) |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
executeInfoAction("同步当前播放信息") { musicManager, infoCallback -> |
|
|
|
musicManager.syncCurrentPlayInfo(infoCallback) |
|
|
|
}(callback) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
@ -561,14 +402,81 @@ class QQMusicSingleton private constructor() { |
|
|
|
} |
|
|
|
|
|
|
|
// 私有辅助方法 |
|
|
|
private fun ensureMusicManager(context: Context) { |
|
|
|
private fun ensureMusicManager(context: Context,callback: QQMusicManager. BindCallback) { |
|
|
|
if (musicManager == null) { |
|
|
|
musicManager = QQMusicManager(context) |
|
|
|
musicManager!!.bindQQMusicApiService(callback) |
|
|
|
}else{ |
|
|
|
if(!musicManager!!.isConnected) { //未连接 |
|
|
|
musicManager?.bindQQMusicApiService(callback) |
|
|
|
}else{ |
|
|
|
callback.onSuccess() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun executeSearchbackAction( |
|
|
|
actionName: String, |
|
|
|
curragain:Int, |
|
|
|
allagain:Int, |
|
|
|
action: (QQMusicManager, QQMusicManager.SearchCallback) -> Unit |
|
|
|
): (callback: (Result<List<Map<String, Any?>>>) -> Unit) -> Unit { |
|
|
|
return lambda@{ callback -> |
|
|
|
|
|
|
|
if (!isQQMusicInstalled()){ |
|
|
|
callback(Result.failure(Exception("未安装QQ音乐软件,请先安装QQ音乐软件"))) |
|
|
|
return@lambda |
|
|
|
} |
|
|
|
|
|
|
|
val currentActivity = context |
|
|
|
if (currentActivity == null) { |
|
|
|
callback(Result.failure(Exception("Activity not available"))) |
|
|
|
return@lambda |
|
|
|
} |
|
|
|
Log.d(TAG, "开始 ${actionName}") |
|
|
|
ensureMusicManager(currentActivity,object: QQMusicManager. BindCallback{ |
|
|
|
override fun onSuccess(){ |
|
|
|
action(musicManager!!, object : QQMusicManager.SearchCallback { |
|
|
|
override fun onSuccess(songs: List<Map<String, Any?>>) { |
|
|
|
Log.d(TAG, "${actionName} 成功") |
|
|
|
handler.post { |
|
|
|
callback(Result.success(songs)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
Log.d(TAG, "失败 ${actionName} 成功") |
|
|
|
if (allagain > 0 && curragain < allagain){ //重试机制 |
|
|
|
executeSearchbackAction(actionName,curragain+1,allagain,action) |
|
|
|
}else{ |
|
|
|
handler.post { |
|
|
|
callback(Result.failure(Exception("$actionName 失败: $errorMessage"))) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
if (allagain > 0 && curragain < allagain){ //重试机制 |
|
|
|
executeSearchbackAction(actionName,curragain+1,allagain,action) |
|
|
|
}else{ |
|
|
|
handler.post { |
|
|
|
callback(Result.failure(Exception("$actionName 失败: $errorMessage"))) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun executePlaybackAction( |
|
|
|
actionName: String, |
|
|
|
curragain:Int, |
|
|
|
allagain:Int, |
|
|
|
action: (QQMusicManager, QQMusicManager.PlayCallback) -> Unit |
|
|
|
): (callback: (Result<Unit>) -> Unit) -> Unit { |
|
|
|
return lambda@{ callback -> |
|
|
|
@ -583,30 +491,42 @@ class QQMusicSingleton private constructor() { |
|
|
|
callback(Result.failure(Exception("Activity not available"))) |
|
|
|
return@lambda |
|
|
|
} |
|
|
|
Log.d(TAG, "开始 ${actionName}") |
|
|
|
ensureMusicManager(currentActivity,object: QQMusicManager. BindCallback{ |
|
|
|
override fun onSuccess(){ |
|
|
|
action(musicManager!!, object : QQMusicManager.PlayCallback { |
|
|
|
override fun onSuccess() { |
|
|
|
Log.d(TAG, "${actionName}成功") |
|
|
|
handler.post { |
|
|
|
callback(Result.success(Unit)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ensureMusicManager(currentActivity) |
|
|
|
action(musicManager!!, object : QQMusicManager.PlayCallback { |
|
|
|
override fun onSuccess() { |
|
|
|
handler.post { |
|
|
|
Log.d(TAG, "${actionName}成功") |
|
|
|
callback(Result.success(Unit)) |
|
|
|
} |
|
|
|
} |
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
if (allagain > 0 && curragain < allagain){ //重试机制 |
|
|
|
executePlaybackAction(actionName,curragain+1,allagain,action) |
|
|
|
}else{ |
|
|
|
handler.post { |
|
|
|
Log.e(TAG, "${actionName}失败: $errorCode $errorMessage") |
|
|
|
if (errorCode == -1){ |
|
|
|
musicManager?.bindQQMusicApiService() |
|
|
|
callback(Result.failure(Exception("播放失败: $errorMessage"))) |
|
|
|
} else if (errorCode == 1030) { |
|
|
|
callback(Result.success(Unit)) |
|
|
|
}else{ |
|
|
|
callback(Result.failure(Exception("播放失败: $errorMessage"))) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
handler.post { |
|
|
|
Log.e(TAG, "播放失败: $errorCode $errorMessage") |
|
|
|
if (errorCode == -1){ |
|
|
|
musicManager?.bindQQMusicApiService() |
|
|
|
callback(Result.failure(Exception("播放失败: $errorMessage"))) |
|
|
|
} else if (errorCode == 1030) { |
|
|
|
callback(Result.success(Unit)) |
|
|
|
}else{ |
|
|
|
callback(Result.failure(Exception("播放失败: $errorMessage"))) |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
callback(Result.failure(Exception("$actionName 失败: $errorMessage"))) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -615,26 +535,36 @@ class QQMusicSingleton private constructor() { |
|
|
|
action: (QQMusicManager, QQMusicManager.InfoCallback) -> Unit |
|
|
|
): (callback: (Result<Map<String, Any?>>) -> Unit) -> Unit { |
|
|
|
return lambda@{ callback -> |
|
|
|
if (!isQQMusicInstalled()){ |
|
|
|
callback(Result.failure(Exception("未安装QQ音乐软件,请先安装QQ音乐软件"))) |
|
|
|
return@lambda |
|
|
|
} |
|
|
|
val currentcontext = context |
|
|
|
if (currentcontext == null) { |
|
|
|
callback(Result.failure(Exception("Activity not available"))) |
|
|
|
return@lambda |
|
|
|
} |
|
|
|
|
|
|
|
ensureMusicManager(currentcontext) |
|
|
|
action(musicManager!!, object : QQMusicManager.InfoCallback { |
|
|
|
override fun onSuccess(data: Map<String, Any?>) { |
|
|
|
handler.post { |
|
|
|
Log.d(TAG, "${actionName}成功") |
|
|
|
callback(Result.success(data)) |
|
|
|
} |
|
|
|
} |
|
|
|
ensureMusicManager(currentcontext,object: QQMusicManager. BindCallback{ |
|
|
|
override fun onSuccess(){ |
|
|
|
action(musicManager!!, object : QQMusicManager.InfoCallback { |
|
|
|
override fun onSuccess(data: Map<String, Any?>) { |
|
|
|
handler.post { |
|
|
|
Log.d(TAG, "${actionName}成功") |
|
|
|
callback(Result.success(data)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
handler.post { |
|
|
|
Log.e(TAG, "${actionName}失败: $errorMessage") |
|
|
|
callback(Result.failure(Exception("${actionName}失败: $errorMessage"))) |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
override fun onError(errorCode: Int, errorMessage: String) { |
|
|
|
handler.post { |
|
|
|
Log.e(TAG, "${actionName}失败: $errorMessage") |
|
|
|
callback(Result.failure(Exception("${actionName}失败: $errorMessage"))) |
|
|
|
} |
|
|
|
callback(Result.failure(Exception("$actionName 失败: $errorMessage"))) |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|