iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
0
Mobile Development

Android 音樂播放器自己來系列 第 22

播放介面實作(7) - Widget 頁面(控制)

  • 分享至 

  • xImage
  •  

昨天實作了顯示功能,今天來實作切換上下一首和播放暫停的功能,在 metaChanged 時,再額外對個別的 UI 元件設定 PendingIntent,previous 按鈕設定 PendingIntent,裡面的 action 就帶入 SKIP_PREVIOUS 的事件,play 和 next 就分別帶入對應的事件。在點擊 cover 時,則是會打開 App 。

private fun setPendingIntent(remoteViews: RemoteViews, context: Context) {
        remoteViews.setOnClickPendingIntent(
            R.id.previous,
            buildPendingIntent(context, WidgetConstants.WidgetAction.SKIP_PREVIOUS.name)
        )

        remoteViews.setOnClickPendingIntent(
            R.id.play,
            buildPendingIntent(context, WidgetConstants.WidgetAction.PLAY_PAUSE.name)
        )

        remoteViews.setOnClickPendingIntent(
            R.id.next,
            buildPendingIntent(context, WidgetConstants.WidgetAction.SKIP_NEXT.name)
        )

        remoteViews.setOnClickPendingIntent(R.id.cover, buildContentIntent(context))
    }

可以看到這邊要送事件的目標是 MusicService,在 MusicService 就還需要再額外設定收事件,做對應的操作。

private fun buildPendingIntent(context: Context, action: String): PendingIntent? {
        val intent = Intent(context, MusicService::class.java)
        intent.action = action
        return intent.asServicePendingIntent(context, PendingIntent.FLAG_UPDATE_CURRENT)
    }

cover 點擊這邊比較單純,就是開起首頁 MainActivity。

private fun buildContentIntent(context: Context): PendingIntent {
        val intent = Intent(context, MainActivity::class.java)
        return PendingIntent.getActivity(
            context, 0,
            intent, PendingIntent.FLAG_UPDATE_CURRENT
        )
    }

在 MusicService 內多加入 onStartCommand,收到 intent 後判斷對應的 action,播放、上一首、下一首。

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        handleIntent(intent)
        return Service.START_NOT_STICKY
    }

    private fun handleIntent(intent: Intent?) {
        intent ?: return

        when (WidgetConstants.WidgetAction.values().find { it.name == intent.action }) {
            WidgetConstants.WidgetAction.PLAY_PAUSE -> handlePlayPause()
            WidgetConstants.WidgetAction.SKIP_NEXT -> handleSkipNext()
            WidgetConstants.WidgetAction.SKIP_PREVIOUS -> handleSkipPrevious()
        }
    }

在 MusicService 內有 mediaSession,透過 mediaSession 可以拿到 transportControls(播放器架構實作 (3) - MediaSession 實作),可以知道現在的播放狀態,並且可以去執行下一首、上一首。

private fun handlePlayPause() {
        if (mediaSession.controller.playbackState.isPlaying) {
            mediaSession.controller.transportControls.pause()
        } else {
            mediaSession.controller.transportControls.play()
        }
    }

    private fun handleSkipNext() {
        mediaSession.controller.transportControls.skipToNext()
    }

    private fun handleSkipPrevious() {
        mediaSession.controller.transportControls.skipToPrevious()
    }

成果圖:

https://i.imgur.com/NN0JXXp.gif

程式碼在這,分支名稱(day22_widget_action_function): Fancy/day22_widget_action_function


上一篇
播放介面實作(6) - Widget 頁面(顯示資訊)
下一篇
播放介面實作(8) - Shortcut 基礎
系列文
Android 音樂播放器自己來30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言