Androidのメディアプレイヤーで通知内のボタンから再生・停止操作をしたときにIllegalStateExceptionが発生する事象について、解決までに調べたことをまとめました。
※この記事の内容は、MediaSessionを使用した実装が前提となりますので、ご注意ください。
忙しい人向けの結論
MediaSessionを使用して音楽再生機能を実装する場合、以下のようにServiceをManifestに登録するかと思いますが、actionタグの中身が正しく指定されていないとIllegalStateExceptionが発生します。
<service android:name=".MyMediaService">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
※actionタグの中身が間違っていることに2日も気付かなかったのは内緒だ
通知内のボタンから再生状態を操作したい
IllegalStateExceptionが発生する
Activityのボタンからは正常に操作できるのですが、通知内のボタンを押下すると以下のようなエラーが発生します。
java.lang.RuntimeException: Unable to start receiver androidx.media.session.MediaButtonReceiver: java.lang.IllegalStateException: Could not find any Service that handles android.intent.action.MEDIA_BUTTON or implements a media browser service.
要は「メディアボタンの操作を受け付けたけど、処理してくれるServiceがないぞ」と言ってるようです。
MediaButtonReceiverの公式ドキュメントによると、以下の2パターンにおいてIllegalStateExceptionが発生するようです。
- Intent.ACTION_MEDIA_BUTTONを処理できるサービスまたは、MediaBrowserServiceが見つからない場合
- Intent.ACTION_MEDIA_BUTTONを処理できるサービスが複数見つかった場合
今回のエラーは上記の1のパターンに該当しますね。
原因
Activityからは再生・停止操作を受け付けているんだから、通知内のボタンの設定やServiceの起動方法が間違ってる?と思いきや、AndroidManifestの誤記でした。
activityタグやserviceタグのandroid:name属性はエラーチェックしてくれていたので、actionタグも同じと思っていましたが、どうやら違うようです。(そのせいで気付かなかった)
まとめ
actionタグのandroid:name属性は指定を間違えてもエラーチェックしてくれないので気を付けよう!
コード全体はこちらにあります。
参考
ゼロから学ぶメディアプレイヤーの実装(これをベースに作りました)
https://dev.classmethod.jp/articles/how-to-android-media-player/
MediaButtonReceiver
https://developer.android.com/reference/androidx/media/session/MediaButtonReceiver?hl=ja