android音視頻指南-響應媒體按鈕

翻譯自:Responding to media buttonshtml


媒體按鈕是Android設備和其餘外圍設備上的硬件按鈕,例如藍牙耳機上的暫停/播放按鈕。當用戶按下媒體按鈕時,Android會生成一個KeyEvent,其中包含一個識別按鈕的密鑰代碼。media button KeyEvents的關鍵代碼是以KEYCODE_MEDIA開頭的常量(例如,KEYCODE_MEDIA_PLAY)。java

應用程序應該可以在三種狀況下處理媒體按鈕事件,按優先順序排列:android

  • 當應用程序的UI活動可見時
  • 當UI活動隱藏且應用程序的媒體會話處於活動狀態時
  • 當UI活動被隱藏,應用程序的媒體會話不活躍,須要從新啓動時

處理前臺活動中的媒體按鈕

前臺活動在其onKeyDown()方法中接收media button key事件。根據Android的運行版本,系統有兩種方式將事件路由到媒體控制器:bash

  • 若是你運行的是安卓5.0 (API level 21)或更高版本,調用FLAG_HANDLES_MEDIA_BUTTONS MediaBrowserCompat.ConnectionCallback.onConnected。這將自動調用您的媒體控制器的dispatchMediaButtonEvent(),它將關鍵代碼轉換爲媒體會話回調。
  • 在Android 5.0 (API level 21)以前,您須要修改onKeyDown()來本身處理事件。(有關詳細信息,請參閱Handling media buttons in an active media session。)下面的代碼片斷展現瞭如何截獲關鍵代碼並調用dispatchMediaButtonEvent()。確保返回true以指示事件已處理:
@Override
    boolean onKeyDown(int keyCode, KeyEvent event) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
              return super.onKeyDown(keyCode, event);
            }
            switch (keyCode) {
              case KeyEvent.KEYCODE_MEDIA_PLAY:
                      yourMediaController.dispatchMediaButtonEvent(event);
                      return true;
            }
            return super.onKeyDown(keyCode, event);
    }
複製代碼

尋找媒體會話

若是前臺活動不處理事件,Android將嘗試找到一個能夠處理它的媒體會話。一樣,根據Android的運行版本,有兩種方法能夠搜索媒體會話:session

  • 若是你運行的是安卓8.0 (API level 26)或更高版本,系統會試圖找到最後一個帶有本地播放音頻的MediaSession的應用。若是會話仍然是活動的,Android會將事件直接發送到它。不然,若是會話不是活動的,而且它有一個mediabutton接收器,Android將事件發送給接收器,接收器將從新啓動會話,所以它能夠接收事件。(有關詳細信息,請參閱Using media buttons to restart an inactive media session 。)若是會話沒有媒體按鈕接收器,系統將丟棄媒體按鈕事件,而且什麼也不會發生。邏輯以下圖所示:
  • 在Android 8.0 (API級別26)以前,系統嘗試將事件發送到活動媒體會話。若是有多個活動媒體會話,Android會嘗試選擇準備播放(緩衝/鏈接)、播放或暫停的媒體會話,而不是中止的。(有關更多細節,請參見 Handling media buttons in an active media session。)若是沒有活動會話,Android會嘗試將事件發送到最近的活動會話。(有關詳細信息,請參閱使用Using media buttons to restart an inactive media session。)邏輯以下圖所示:

處理活動媒體會話中的媒體按鈕

在Android 5.0 (API level 21)及更高版本上,Android經過調用onMediaButtonEvent()自動將媒體按鈕事件分派給您的活動媒體會話。默認狀況下,此回調將KeyEvent轉換爲與密鑰代碼匹配的適當的媒體會話回調方法。app

在Android 5.0 (API level 21)以前,Android經過使用ACTION_MEDIA_BUTTON操做廣播一個意圖來處理媒體按鈕事件。你的應用程序必須註冊一個廣播接收器來攔截這些意圖。MediaButtonReceiver類是專門爲此目的設計的。它是Android media-compat庫中的一個方便類,它處理ACTION_MEDIA_BUTTON並將傳入的意圖轉換爲適當的MediaSessionCompat.Callback方法調用。框架

MediaButtonReceiver是一個短命的廣播接收器。它將傳入的意圖轉發給管理媒體會話的服務。若是你想在Android 5.0以前在系統中使用媒體按鈕,你必須在清單中包括MediaButtonReceiverMEDIA_BUTTON意圖過濾器。ide

<receiver android:name="android.support.v4.media.session.MediaButtonReceiver" >
   <intent-filter>
     <action android:name="android.intent.action.MEDIA_BUTTON" />
   </intent-filter>
 </receiver>
複製代碼

廣播接收器將意圖轉發給您的服務。要解析意圖並生成對媒體會話的回調,請在服務的onStartCommand()中包含MediaButtonReceiver.handleIntent()方法。這將把關鍵代碼轉換爲適當的會話回調方法。函數

private MediaSessionCompat mMediaSessionCompat = ...;

public int onStartCommand(Intent intent, int flags, int startId) {
  MediaButtonReceiver.handleIntent(mMediaSessionCompat, intent);
  return super.onStartCommand(intent, flags, startId);
}
複製代碼

注意:若是您沒有MediaBrowserServiceCompat,您還能夠向任何服務添加ACTION_MEDIA_BUTTON意圖過濾器。有關更多信息,請參閱MediaButtonReceiver文檔。ui

使用媒體按鈕從新啓動非活動的媒體會話

若是Android可以識別最後一個活動媒體會話,它會試圖經過發送一個ACTION_MEDIA_BUTTON意圖到一個聲明註冊的組件(如服務或廣播接收器)來從新啓動會話。

這可讓你的應用在UI不可見時重啓回放,這是大多數音頻應用的狀況。

當您使用MediaSessionCompat時,將自動啓用此行爲。若是你使用Android框架的MediaSession或者Support Library 24.0.0到25.1.1,你必須調用setMediaButtonReceiver,讓媒體按鈕從新啓動一個非活動的媒體會話。

你能夠經過設置一個空媒體按鈕接收器,在Android 5.0 (API級別21)或更高版本中禁用此行爲:

// Create a MediaSessionCompat
mMediaSession = new MediaSessionCompat(context, LOG_TAG);
mMediaSession.setMediaButtonReceiver(null);
複製代碼

注意:對於在Android 5.0 (API level 21)以前的系統中運行的應用程序,您註冊以處理活動會話的媒體按鈕的MediaButtonReceiver也會在會話不活動時接收媒體按鈕事件。沒法禁用此行爲。

定製媒體按鈕處理程序

onMediaButtonEvent()的默認行爲提取關鍵代碼並使用媒體會話的當前狀態和支持的操做列表來肯定調用哪一個方法。例如,KEYCODE_MEDIA_PLAY調用onPlay()

爲了在全部應用程序中提供一致的媒體按鈕體驗,您應該使用默認行爲,而且只爲了特定的目的而偏離。若是媒體按鈕須要自定義處理,重寫回調函數的onMediaButtonEvent()方法,使用intent.getparcelableextra (Intent.EXTRA_KEY_EVENT)提取KeyEvent,本身處理事件,並返回true

總結

要正確處理Android全部版本中的媒體按鈕事件,必須在建立媒體會話時指定FLAG_HANDLES_MEDIA_BUTTONS

此外,根據您計劃支持的Android版本,您還必須知足如下要求:

運行Android 5.0或更高版本時:

  • 從媒體控制器onConnected()回調中調用MediaControllerCompat.setMediaController()
  • 要容許媒體按鈕從新啓動非活動會話,能夠經過調用setMediaButtonReceiver()並傳遞PendingIntent動態建立MediaButtonReceiver

當系統運行時間早於Android 5.0時:

  • 重寫活動的onKeyDown()以處理媒體按鈕
  • 靜態建立一個MediaButtonReceiver經過添加它到應用程序的清單
相關文章
相關標籤/搜索