Android - Audio Focus とは何か

こんにちは、masm11 です。

私のスマホは Android です。これを使ってアプリを作ることもあります。 今回は Android で音楽アプリを作ろうと思ったらきっと避けては通れない "Audio Focus" について説明したいと思います。

Audio Focus とは

どのアプリが音を鳴らしているかを、アプリたちの助けを借りながら、Android OS が管理する仕組みです。

例えば、音楽アプリを2つ起動して、両方のアプリで音楽を再生してもあまり嬉しくありませんね。 後から再生したら、前再生していたアプリが止まってくれると嬉しいです。

例えば、アプリがちょっとの間音を鳴らしたい時、音楽アプリが音を小さくしてくれると助かる、 なんてこともあります。

そういったことを管理してくれる機能、また、どのアプリが音を鳴らしているか、を Audio Focus と呼びます。

では、実際のコードを見ていきます。 サンプルは↓こちらに用意してありますので、これを見ながら説明していきます。

https://github.com/masm11/audio-focus-sample/blob/master/app/src/main/java/com/example/myapplication/MainActivity.kt

基本の使い方

https://github.com/masm11/audio-focus-sample/blob/master/app/src/main/java/com/example/myapplication/MainActivity.kt#L47-L54

L50 で、「Audio Focus をくれ!」という情報を元に AudioFocusRequest を作り、 それを L51 で AudioManager#requestAudioFocus() に渡しています。 この処理をこちらのアプリが音を鳴らす前に実行します。

基本的にはこれだけです。

ただ、Audio Focus を持っているということは、 他のアプリが「Audio Focus をくれ!」と言い、 こちらのアプリが再生を中断する場合もあり得る、ということです。 そういう場合に備えて、通常は callback を用意しておき、 builder に渡します。 今回はそこまでしていません。

Spotify とかで音楽を再生している状態で、 このアプリを起動し、GAIN をタップすると、 Spotify は即座に再生を中止します。

ちょっとの間音を鳴らす場合

次は、相手アプリの再生を止めるほどではなく、 ちょっとの間ボリュームを下げておいてくれたらいい場合です。

https://github.com/masm11/audio-focus-sample/blob/master/app/src/main/java/com/example/myapplication/MainActivity.kt#L56-L63

AUDIOFOCUS_GAIN が AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK になりました。

weblio によると、duck には「ひょいとかがむ」という意味もあるようです。 ボリュームをちょっと下げるのにイメージが似てますかね。 あと、may なので、duck してもいいし、なんなら再生を止めてくれもいい、という感じですかね。

これを元に戻すのが↓こちらです。

https://github.com/masm11/audio-focus-sample/blob/master/app/src/main/java/com/example/myapplication/MainActivity.kt#L65-L71

AudioManager#requestAudioFocus() に渡した req を持っておき、 それを L69 で AudioManager#abandonAudioFocusRequest() に渡しています。 こうすることで、duck していたアプリのボリュームが元に戻ります。

Spotify で音楽を再生している状態で、 このアプリを起動し、MAY DUCK をタップするとボリュームが小さくなり、 ABANDON をタップすると元に戻ります。

PayPay

何故ここに PayPay が出てくるか、おわかりでしょうか…?

PayPay では時々キャンペーンをしていますね。 「スクラッチチャーンス!」タップして「シャカシャカ」という音と共に くじの結果が表示されます。

ところが、その時、音楽を再生していると、ボリュームが小さくなったままに なってしまいます。PayPay アプリを終了すると元に戻ります。

これは Android 用 PayPay アプリがちゃんと abandon していないためだと思われます。 是非修正して欲しいものですね!

ではまた!