Skip to content

Commit

Permalink
fix: title pop-up & interfere (#478)
Browse files Browse the repository at this point in the history
  • Loading branch information
HChenX authored Nov 17, 2024
1 parent ec80650 commit 501acda
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 27 deletions.
75 changes: 64 additions & 11 deletions app/src/main/kotlin/statusbar/lyric/hook/module/SystemUILyric.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ import android.graphics.Shader
import android.graphics.Typeface
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.DisplayMetrics
import android.util.TypedValue
import android.view.Gravity
Expand Down Expand Up @@ -420,6 +423,45 @@ class SystemUILyric : BaseHook() {
SystemUISpecial()
}

var playingApp: String = ""
val TITLE_SHOW_READY: Int = 0
val TITLE_SHOW_WAITING: Int = 1
val TITLE_SHOWING: Int = 2
val titleShowHandler: Handler by lazy {
object : Handler(Looper.getMainLooper()) {
var titleData: TitleData = TitleData("", "")

override fun handleMessage(msg: Message) {
when (msg.what) {
TITLE_SHOW_READY -> {
if (titleShowHandler.hasMessages(TITLE_SHOW_WAITING))
titleShowHandler.removeMessages(TITLE_SHOW_WAITING)
titleShowHandler.sendEmptyMessageDelayed(TITLE_SHOW_WAITING, 800)
titleData = msg.obj as TitleData
}

TITLE_SHOW_WAITING -> {
}

TITLE_SHOWING -> {
if (titleShowHandler.hasMessages(TITLE_SHOW_WAITING)
|| titleData.title.isEmpty() || titleData.caller.isEmpty()
) return

if (playingApp.isNotEmpty() && titleData.caller == playingApp) {
"title: ${titleData.title}".log()
this@SystemUILyric.title = titleData.title
}

titleData = TitleData("", "")
}
}
}
}
}

data class TitleData(val caller: String, val title: String)

@SuppressLint("UnspecifiedRegisterReceiverFlag", "MissingPermission")
private fun lyricInit() {
val firstLoad = lyricLayout.parent.isNull()
Expand Down Expand Up @@ -450,31 +492,42 @@ class SystemUILyric : BaseHook() {
themeMode = (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK)
if (config.titleSwitch) {
object : SystemMediaSessionListener(context) {
override fun onTitleChanged(title: String) {
super.onTitleChanged(title)
"title: $title".log()
this@SystemUILyric.title = title
override fun onTitleChanged(caller: String, title: String) {
super.onTitleChanged(caller, title)

val message = Message.obtain()
message.what = TITLE_SHOW_READY
message.obj = TitleData(caller, title);
titleShowHandler.sendMessage(message)
}
}
}
}

if (!firstLoad) return
val lyricReceiver = LyricReceiver(object : LyricListener() {
override fun onStop(lyricData: LyricData) {
if (!isReally) return
if (isHiding) isHiding = false
lastLyric = ""
hideLyric()
}

override fun onUpdate(lyricData: LyricData) {
if (!isReally) return
val lyric = lyricData.lyric
lastLyric = lyric
playingApp = lyricData.extraData.packageName
if (isHiding) return
changeIcon(lyricData.extraData)
changeLyric(lastLyric, lyricData.extraData.delay)
titleShowHandler.sendEmptyMessage(TITLE_SHOWING)
}

override fun onStop(lyricData: LyricData) {
if (!isReally) return
if (playingApp.isNotEmpty()) {
if (lyricData.extraData.packageName.isNotEmpty() &&
playingApp != lyricData.extraData.packageName
) return
}
if (isHiding) isHiding = false
playingApp = ""
lastLyric = ""
hideLyric()
}
})
registerLyricListener(context, BuildConfig.API_VERSION, lyricReceiver)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@ import android.service.notification.NotificationListenerService
open class SystemMediaSessionListener(context: Context) {
private var artist: String? = null
private var mediaSessionManager: MediaSessionManager? = null
private val activeControllers = mutableListOf<MediaController>()
private val activeControllers = mutableMapOf<MediaController, MediaControllerCallback>()

// 监听活跃会话的变化
private val activeSessionsListener = MediaSessionManager.OnActiveSessionsChangedListener { controllers ->
if (controllers?.size == 0) {
if (controllers?.size == 0)
onCleared()
}

// 清理之前的回调
activeControllers.forEach { it.unregisterCallback(mediaControllerCallback) }
activeControllers.forEach { it.key.unregisterCallback(it.value) }
activeControllers.clear()

controllers?.let {
it.forEach { controller ->
activeControllers.add(controller)
controller.registerCallback(mediaControllerCallback)
val callback = MediaControllerCallback(controller)
activeControllers[controller] = callback
controller.registerCallback(callback)
handleMediaController(controller)
}
}
Expand All @@ -41,49 +42,50 @@ open class SystemMediaSessionListener(context: Context) {

private fun handleMediaController(controller: MediaController) {
controller.metadata?.let { metadata ->
displayMediaMetadata(metadata)
displayMediaMetadata(controller.packageName, metadata)
}

controller.playbackState?.let { state ->
onStateChanged(state.state)
onStateChanged(controller.packageName, state.state)
}
}

// MediaController 回调
private val mediaControllerCallback = object : MediaController.Callback() {
private inner class MediaControllerCallback(private val controller: MediaController) :
MediaController.Callback() {
override fun onMetadataChanged(metadata: MediaMetadata?) {
super.onMetadataChanged(metadata)
metadata?.let {
displayMediaMetadata(it)
displayMediaMetadata(controller.packageName, it)
}
}

override fun onPlaybackStateChanged(state: PlaybackState?) {
super.onPlaybackStateChanged(state)
state?.let {
onStateChanged(state.state)
onStateChanged(controller.packageName, state.state)
}
}
}

// 显示媒体元数据
private fun displayMediaMetadata(metadata: MediaMetadata) {
private fun displayMediaMetadata(caller: String, metadata: MediaMetadata) {
val title = metadata.getString(MediaMetadata.METADATA_KEY_TITLE) ?: "Unknown Title"
val artist = metadata.getString(MediaMetadata.METADATA_KEY_ARTIST) ?: "Unknown Artist"
if (this.artist != artist) {
this.artist = artist
onTitleChanged(title)
onTitleChanged(caller, title)
}
}

fun cleanup() {
mediaSessionManager?.removeOnActiveSessionsChangedListener(activeSessionsListener)
activeControllers.forEach { it.unregisterCallback(mediaControllerCallback) }
activeControllers.forEach { it.key.unregisterCallback(it.value) }
}

open fun onTitleChanged(title: String) {}
open fun onTitleChanged(caller: String, title: String) {}

open fun onStateChanged(state: Int) {}
open fun onStateChanged(caller: String, state: Int) {}

open fun onCleared() {}
}

0 comments on commit 501acda

Please sign in to comment.