メディアボタンとは、Android デバイスや周辺デバイスにあるハードウェア ボタンのことです。たとえば、Bluetooth ヘッドセットの一時停止 / 再生ボタンなどです。ユーザーがメディアボタンを押すと、そのボタン特有の「キーコード」を含む KeyEvent
が Android により生成されます。メディアボタン KeyEvent のキーコードは、KEYCODE_MEDIA
で始まる名前(たとえば、KEYCODE_MEDIA_PLAY
)の定数です。
アプリは、次の順序で 3 つのケースでメディアボタン イベントを処理できるようにする必要があります。 優先度:
- アプリの UI アクティビティが表示されている場合
- UI アクティビティが非表示で、アプリのメディア セッションがアクティブの場合
- UI アクティビティが非表示で、アプリのメディア セッションが非アクティブであり再起動を必要とする場合
フォアグラウンド アクティビティでのメディアボタンの処理
フォアグラウンド アクティビティが onKeyDown()
でメディアボタンのキーイベントを受け取る
メソッドを呼び出します。実行中の Android のバージョンに応じて、システムがイベントを
メディア コントローラ:
- Android 5.0(API レベル 21)以降を実行している場合は、
FLAG_HANDLES_MEDIA_BUTTONS
MediaBrowserCompat.ConnectionCallback.onConnected
。これにより、 自動的にメディア コントローラのdispatchMediaButtonEvent()
, これにより、キーコードがメディア セッション コールバックに変換されます。 - Android 5.0(API レベル 21)より前では、
onKeyDown()
を変更して、 できます。 (詳しくは、アクティブなメディア セッションでのメディアボタンの処理をご覧ください)。 次のコード スニペットは、 ディスパッチ MediaButtonEvent() を呼び出します。true
を必ず返品してください。 イベントが処理されたことを示します。Kotlin
fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { return super.onKeyDown(keyCode, event) } when (keyCode) { KeyEvent.KEYCODE_MEDIA_PLAY -> { yourMediaController.dispatchMediaButtonEvent(event) return true } } return super.onKeyDown(keyCode, event) }
Java
@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 でメディア セッションを検索するには、次の 2 つの方法があります。
Android 8.0(API レベル 26)以降を実行している場合、システムは MediaSession でローカルに音声を再生した最後のアプリを見つけます。セッションが Android はイベントを直接送信します。それ以外の場合、 セッションがアクティブではなくメディアボタン レシーバーがある場合、Android はイベントを送信します。 レシーバーに送信されます。これによりセッションが再開され、イベントを受信できるようになります。 (詳しくは、メディアボタンを使用して非アクティブなメディア セッションを再起動するをご覧ください)。 セッションにメディアボタン レシーバーがない場合、システムはメディアを破棄します。 イベントが発生し、何も起こりません。ロジックを以下に示します。 図:
Android 8.0(API レベル 26)より前では、システムはイベントの送信を アクティブなメディア セッション。アクティブなメディア セッションが複数ある場合、Android は 再生準備中(バッファリング/接続中)中のメディア セッションを選択します。 「再生中」、または「一時停止」です。(参照: アクティブなメディア セッションでのメディアボタンの処理 をご覧ください)。アクティブな 直近のアクティブなセッションにイベントを送信しようとします。 (詳しくは、メディアボタンを使用して非アクティブなメディア セッションを再起動するをご覧ください)。 このロジックを次の図に示します。
アクティブなメディア セッションでのメディアボタンの処理
Android 5.0(API レベル 21)以降では、Android は以下を呼び出して、メディア ボタン イベントをアクティブなメディア セッションに自動的にディスパッチします。
onMediaButtonEvent()
。
デフォルトでは、このコールバックによって、KeyEvent はキーコードに対応する適切なメディア セッション コールバック メソッドに変換されます。
Android 5.0(API レベル 21)より前の Android では、インテントをブロードキャストすることでメディアボタン イベントを処理します。
ACTION_MEDIA_BUTTON
アクションに置き換えます。アプリは
BroadcastReceiver を使用してこれらのインテントをインターセプトします。「
MediaButtonReceiver
トレーニング用のクラスは
できます。これは、Terraform のコンビニエンス クラスです。
Android
media-compat ライブラリ
ACTION_MEDIA_BUTTON
を処理し、受け取ったインテントを
適切な MediaSessionCompat.Callback
メソッド呼び出し。
MediaButtonReceiver
は存続期間の短い BroadcastReceiver で、着信を転送
インテントを、メディア セッションを管理しているサービスに渡します。「新規顧客の獲得」目標を
Android 5.0 より前のシステムでは、メディアボタンを含める必要があります。
MEDIA_BUTTON
インテント フィルタを使用して、マニフェストの MediaButtonReceiver
をオーバーライドできます。
<receiver android:name="android.support.v4.media.session.MediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
BroadcastReceiver
により、インテントはサービスに転送されます。インテントを解析する
次に、メディア セッションへのコールバックを生成して、サービスの onStartCommand()
に MediaButtonReceiver.handleIntent()
メソッドを含めます。
これにより、キーコードが適切なセッション コールバック メソッドに変換されます。
Kotlin
private val mediaSessionCompat: MediaSessionCompat = ... override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { MediaButtonReceiver.handleIntent(mediaSessionCompat, intent) return super.onStartCommand(intent, flags, startId) }
Java
private MediaSessionCompat mediaSessionCompat = ...; public int onStartCommand(Intent intent, int flags, int startId) { MediaButtonReceiver.handleIntent(mediaSessionCompat, intent); return super.onStartCommand(intent, flags, startId); }
メディアボタンを使用した非アクティブなメディア セッションの再起動
Android により、最後にアクティブだったメディア セッションの特定ができた場合は、ACTION_MEDIA_BUTTON
インテントがマニフェストに登録されたコンポーネント(サービスや BroadcastReceiver
など)に送信され、そのセッションの再起動が試みられます。
これにより、UI が表示されていない状態(ほとんどの音声アプリが該当するケース)でアプリの再生を再開できます。
MediaSessionCompat
を使用すると、この動作は自動的に有効になります。もし
Android フレームワークの MediaSession
またはサポート ライブラリ 24.0.0 ~
25.1.1 メディアボタンでゲームを再起動できるようにするには、setMediaButtonReceiver
を呼び出す必要がある
応答がありません。
Android 5.0(API レベル 21)以降では、次の方法でこの動作を無効にできます。 null のメディアボタン レシーバーを設定する場合:
Kotlin
// Create a MediaSessionCompat mediaSession = MediaSessionCompat(context, LOG_TAG) mediaSession.setMediaButtonReceiver(null)
Java
// Create a MediaSessionCompat mediaSession = new MediaSessionCompat(context, LOG_TAG); mediaSession.setMediaButtonReceiver(null);
メディアボタン ハンドラのカスタマイズ
onMediaButtonEvent()
のデフォルトの動作では、キーコードが抽出され、メディア セッションの現在の状態とサポートされているアクションのリストから、呼び出されるメソッドが決定されます。たとえば、KEYCODE_MEDIA_PLAY
なら onPlay()
が呼び出されます。
すべてのアプリで一貫したメディアボタン エクスペリエンスを提供するには、
特定の目的のためにのみ逸脱します。メディアボタンが
必要な場合は、コールバックの
onMediaButtonEvent()
メソッドを呼び出し、次を使用して KeyEvent
を抽出します。
intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT)
,
自分でイベントを処理し、true
を返します。
概要
Android のすべてのバージョンでメディアボタン イベントを適切に処理するには、
FLAG_HANDLES_MEDIA_BUTTONS
を指定する
設定することもできます。
また、サポートする Android のバージョンによっては、 次の要件も満たす必要があります
Android 5.0 以降で実行する場合:
- メディア コントローラ
onConnected()
コールバックからMediaControllerCompat.setMediaController()
を呼び出す - アクティブでないセッションをメディアボタンで再開できるようにするには、以下を呼び出して
MediaButtonReceiver
を動的に作成します。setMediaButtonReceiver()
とPendingIntent
を渡す
Android 5.0 より前のシステムで実行する場合:
- アクティビティの
onKeyDown()
をオーバーライドしてメディアボタンを処理する MediaButtonReceiver
をアプリのマニフェストに追加して静的に作成する