C
媒体会话控制器
演示了媒体会话 API 的使用。
构建和部署示例
请参阅有关构建和部署 Qt for Android Automotive 示例的具体步骤。
概述
此示例展示了如何使用 Qt 媒体会话 API 来控制在 Android Automotive 上的媒体会话。
媒体会话启动后,应用程序会显示一个包含所有当前活动会话的列表。列表中的每一项代表一个会话,可以通过提供的控件进行操作。
包括 API
我们需要导入两个 Android Automotive 模块:用于媒体会话 API 的 Media 和用于检查通知访问权限的 Base。
import QtAndroidAutomotive.Media import QtAndroidAutomotive.Base
启动监听服务
为了接收有关媒体会话的数据,应用程序是一个启用通知监听。这可以通过在 AndroidManifest.xml 文件中声明由媒体会话 API 提供的通知监听器服务来实现。
<service android:name="org.qtproject.qt.android.mediasession.QtMediaNotificationListener" android:enabled="true" android:exported="true" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService" /> </intent-filter> </service>
默认情况下,应用程序没有访问通知的权限。因此,如果无法访问通知,我们需要引导用户到设置应用,以便他们可以授予访问权限。
if (!hasNotificationAccess()) { notificationsDialog.open() }
列出媒体会话控制器
控制器对象用于控制会话。这些控制器可以从小结MediaSessionManager::activeControllers
属性中获取
ListView { id: sessionsList spacing: 10 model: MediaSessionManager.activeControllers clip: true anchors { left: parent.left top: parent.top right: parent.right bottom: parent.bottom margins: 10 } delegate: MediaControllerItem {} }
在此列表中,每个控制器都由一个 MediaControllerItem
QML 元素表示。
使用控制器
媒体标题和艺术家
示例使用由MediaSessionController::metaData
属性返回的QMediaMetaData。
Text { id: titleText width: parent.width elide: Text.ElideRight color: "#f3f3f4" text: root.modelData.metaData.stringValue(MediaMetaData.Title) } Text { id: artistText color: "#cecfd5" text: root.modelData.metaData.stringValue(MediaMetaData.AlbumArtist) }
控制媒体会话
为了控制媒体,我们有一些按钮,它们使用MediaSessionController::pause
、MediaSessionController::play
、MediaSessionController::skipToNext
和MediaSessionController::skipToPrevious
方法。
这些控件是否有可用性由每个会话单独定义。可以使用MediaSessionController::availableActions
属性检测控制功能的可用性。
MediaControlButton { id: prevButton onClicked: root.modelData.skipToPrevious() visible: root.modelData.availableActions & MediaSessionController.SkipToPreviousAction width: buttonRow.buttonSize height: buttonRow.buttonSize icon.source: "res/previous.png" } MediaControlButton { id: playButton onClicked: { if (playing) root.modelData.pause() else root.modelData.play() } readonly property bool playing: root.modelData.playbackState === MediaSessionController.PlayingState visible: root.modelData.availableActions & (playing ? MediaSessionController.PauseAction : MediaSessionController.PlayAction) width: buttonRow.buttonSize height: buttonRow.buttonSize icon.source: { if (root.modelData.playbackState === MediaSessionController.PlayingState) { return "res/pause.png"; } else { return "res/play.png"; } } } MediaControlButton { id: nextButton onClicked: root.modelData.skipToNext() visible: root.modelData.availableActions & MediaSessionController.SkipToNextAction width: buttonRow.buttonSize height: buttonRow.buttonSize icon.source: "res/next.png" } MediaControlButton { id: stopButton onClicked: root.modelData.stop() visible: root.modelData.availableActions & MediaSessionController.StopAction width: buttonRow.buttonSize height: buttonRow.buttonSize icon.source: "res/stop.png" }
在媒体内查找位置
在通过媒体查找的过程中,示例提供了一个使用滑动条的例子,它通过MediaSessionController::position属性读取并控制当前播放位置,并通过MediaSessionController::duration属性读取媒体的长度。
Slider { id: progressSlider onMoved: { // Position is set in milliseconds: root.modelData.position = value * 1000 } width: parent.width from: 0 // Duration and position are reported in milliseconds, converting to seconds to: (root.modelData.duration / 1000) value: (root.modelData.position / 1000) enabled: root.modelData.availableActions & MediaSessionController.PositionAction }
为了完整地显示播放时长和位置,示例中包含两个文本元素。一个用于显示当前位置,另一个用于显示媒体的长度。这些值直接从上面实现的滑动条中读取并格式化为分钟和秒来显示。
Text { id: progressText readonly property string minutes: "%1".arg(parseInt(progressSlider.value / 60)).padStart(2, '0') readonly property string seconds: "%1".arg(parseInt(progressSlider.value % 60)).padStart(2, '0') color: "#cecfd5" text: "%1:%2".arg(minutes).arg(seconds) verticalAlignment: Text.AlignVCenter anchors { left: parent.left leftMargin: rootColumn.spacing verticalCenter: parent.verticalCenter } } Text { id: durationText readonly property string minutes: "%1".arg(parseInt(progressSlider.to / 60)).padStart(2, '0') readonly property string seconds: "%1".arg(parseInt(progressSlider.to % 60)).padStart(2, '0') color: "#cecfd5" text: "%1:%2".arg(minutes).arg(seconds) verticalAlignment: Text.AlignVCenter anchors { right: parent.right rightMargin: rootColumn.spacing verticalCenter: parent.verticalCenter } }
在某些Qt许可下可用。
了解更多。