是否可以获得currently-playing-song的信息?

Is it possible to get currently-playing-song information?

背景

我想看看我是否可以获得有关当前播放歌曲的信息,以便能够显示有关它的更多信息,或者只显示我获得的信息。

我想检查一下,因为我注意到在名为“Musicolet”的流行音乐播放器应用程序上有一个“广播专辑封面”的设置 (here)。当然它只是说“专辑封面”,但它也说它是为“第 3 方”准备的。所以我想调查一下是否可行。

问题

不确定是否可行。我看到关于它的相互矛盾的答案。

我发现了什么

我发现了一些有趣的链接:

  1. 我还在 Whosebug (here) 上发现了一个关于获取它的问题,但它缺少一些关键代码。
  2. 另一方面,我发现另一个 post 说这不是官方的,你可能做不到,here
  3. 我注意到 Spotify 有(或仍然有?)类似的东西(here,除了我在那里看不到专辑封面),但它有点旧。
  4. 我还发现了一个有趣的界面 RemoteControlClient.OnMetadataUpdateListener (from here), but couldn't find any sample or tutorial about it, except perhaps this one 来自 XDA。

当然,我尝试使用从这些链接中找到的提示,但未能真正发挥作用。

所以也许以前是不可能的,后来是可以的。但出于某种原因,我没有看到 sample/tutorial 如何使用它,包括在文档中。

我认为如果可能的话,它需要通知访问,因为它与从音乐播放器的通知中读取当前正在播放的音乐差不多。

问题

  1. 是否可以注册到歌曲播放时间的回调(也可以随时查询)并获取相关信息?

    含义song-title、album-name、file-path/uri、album-art...

  2. 如果可能的话,怎么做?它需要什么?

  3. 如果不可能,有什么解决方法吗?适用于某些应用程序的任何东西?也许通知中存在一些更正式的东西,我可以检测到它是这种类型,并获取这些信息?

您需要有通知侦听器服务,否则第三方应用无法访问媒体会话。

在某处声明服务:

import android.service.notification.NotificationListenerService

class NotiService : NotificationListenerService()

将其添加到清单:

<service android:name=".service.NotiService"
    android:label="Enable media controls"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

然后你可以将它作为参数传递给 getActiveMediaSessions inside Activity:

val m = getSystemService<MediaSessionManager>()!!
val component = ComponentName(this, NotiService::class.java)
val sessions = m.getActiveSessions(component)
Log.d("Sessions", "count: ${sessions.size}")
sessions.forEach {
    Log.d("Sessions", "$it -- " + (it?.metadata?.keySet()?.joinToString()))
    Log.d("Sessions", "$it -- " + (it?.metadata?.getString(MediaMetadata.METADATA_KEY_TITLE)))
}

现在导航到系统设置 -> 通知访问并为 NotiService 启用它,它应该 运行 没有问题。