音声出力の変更の処理
コレクションでコンテンツを整理
必要に応じて、コンテンツの保存と分類を行います。
ユーザーは、オーディオ アプリの音量を調整できることを期待しています。標準の動作には、音量コントロール(デバイス上のボタンやノブ、UI のスライダー)を使用できることや、ヘッドフォンなどの周辺機器が使用中に接続が切断された場合に突然大音量で再生されないようにすることが含まれます。
音量コントロールの使用
ユーザーが音楽アプリやゲームアプリで音量キーを押したら、曲間でプレーヤーの再生が一時停止されていたり、ゲームの現在の場所には音楽がなかったりした場合でも、音量を変更するようにします。
Android では、音楽、アラーム、通知、着信音、システム音、通話音量、DTMF トーンの再生に、個別の音声ストリームが使用されます。これにより、ユーザーは各ストリームの音量を個別に制御できます。
デフォルトでは、音量コントロールを押すと、アクティブな音声ストリームの音量が変更されます。アプリで何も再生していない場合は、音量ボタンを押すと音楽(Android 9 より前では着信音)の音量が調整されます。
アラーム以外のアプリでは、用途を AudioAttributes.USAGE_MEDIA
に指定して音声を再生します。
音量コントロールで正しいストリームを調整するには、setVolumeControlStream()
を呼び出す際に、AudioAttributes.getVolumeControlStream
から取得できる属性に一致するストリーム タイプを渡します。
Kotlin
setVolumeControlStream(AudioManager.STREAM_MUSIC)
Java
setVolumeControlStream(AudioManager.STREAM_MUSIC);
この呼び出しは、アプリのライフサイクルで、通常はメディアを制御するアクティビティまたはフラグメントの onResume()
メソッドから行います。これにより、ターゲットのアクティビティまたはフラグメントが表示されるたびに、音量コントロールが STREAM_MUSIC
に接続されます。
プログラムによるストリーム音量の制御
使う機会はまれですが、音声ストリームの音量をプログラムで設定できます。たとえば、アプリで既存の UI を置き換える場合などです。これは、Android AudioManager
により同じタイプの音声ストリームがすべて 1 つにミックスされるため、推奨されません。以下のメソッドでは、そのストリームを使用するすべてのアプリの音量が変更されます。これらの使用は避けてください。
固定音量デバイスへの対応
一部のデバイス(Chromebook や Android Automotive OS 搭載の自動車など)では、音量コントロールはありますが、アプリで前述の AudioManager
メソッドを使用して音声ストリームのレベルを変更することはできません。このようなデバイスを「固定音量」デバイスと呼びます。アプリが固定音量デバイスで実行されているかどうかを確認するには、isVolumeFixed()
を呼び出します。
オーディオ アプリには、同じストリームで再生される他のアプリと出力音量のバランスを取る機能を付けるようにします。固定音量デバイスで実行されるアプリでは、固有の音量コントロールを適切な setVolume()
メソッドに接続するようにします。
突然の大音量再生の防止
ユーザーは、さまざまな方法で Android デバイスのオーディオを聴くことができます。ほとんどのデバイスは内蔵スピーカーと有線ヘッドセット用のヘッドフォン端子を備えており、Bluetooth 接続や A2DP オーディオをサポートするものも少なくありません。
ヘッドセットが取り外されたり、Bluetooth デバイスが切断されたりすると、音声ストリームは自動的に内蔵スピーカーにルート変更されます。大音量で音楽を聴いていた場合は、周囲を驚かせる可能性があります。
ユーザーは通常、オンスクリーンの再生コントロールを備えた音楽プレーヤーは、このような場合に再生を一時停止するものと考えています。その他のアプリ(コントロールを備えていないゲームなど)では、そのまま再生を続けます。ユーザーは、デバイスのハードウェア コントロールで音量を調節できます。
音声出力が内蔵スピーカーに戻ると、システムにより ACTION_AUDIO_BECOMING_NOISY
インテントがブロードキャストされます。BroadcastReceiver
を作成して、音声を再生するときは必ずこのインテントをリッスンするようにします。レシーバは次のようになります。
Kotlin
private class BecomingNoisyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == AudioManager.ACTION_AUDIO_BECOMING_NOISY) {
// Pause the playback
}
}
}
Java
private class BecomingNoisyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
// Pause the playback
}
}
}
このレシーバは、再生を開始するときに登録し、再生を停止するときに登録を解除します。このガイドの説明に沿ってアプリを設計する場合、これらの呼び出しはメディア セッション コールバック onPlay()
と onStop()
で行います。
Kotlin
private val intentFilter = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)
private val myNoisyAudioStreamReceiver = BecomingNoisyReceiver()
private val callback = object : MediaSessionCompat.Callback() {
override fun onPlay() {
registerReceiver(myNoisyAudioStreamReceiver, intentFilter)
}
override fun onStop() {
unregisterReceiver(myNoisyAudioStreamReceiver)
}
}
Java
private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
private BecomingNoisyReceiver myNoisyAudioStreamReceiver = new BecomingNoisyReceiver();
MediaSessionCompat.Callback callback = new
MediaSessionCompat.Callback() {
@Override
public void onPlay() {
registerReceiver(myNoisyAudioStreamReceiver, intentFilter);
}
@Override
public void onStop() {
unregisterReceiver(myNoisyAudioStreamReceiver);
}
}
このページのコンテンツやコードサンプルは、コンテンツ ライセンスに記載のライセンスに従います。Java および OpenJDK は Oracle および関連会社の商標または登録商標です。
最終更新日 2025-07-27 UTC。
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["必要な情報がない","missingTheInformationINeed","thumb-down"],["複雑すぎる / 手順が多すぎる","tooComplicatedTooManySteps","thumb-down"],["最新ではない","outOfDate","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["サンプル / コードに問題がある","samplesCodeIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-07-27 UTC。"],[],[],null,["# Handling changes in audio output\n\nUsers expect to be able to control the volume of an audio app. Standard behavior\nincludes the ability to use the volume controls (either buttons or knobs on the\ndevice or sliders in the UI), and to avoid suddenly playing out loud if a\nperipheral like headphones is disconnected while in use.\n\nUsing the volume controls\n-------------------------\n\nWhen a user presses a volume key in a game or music app the volume should\nchange, even if the player is paused between songs or there's no music for the\ncurrent game location.\n\nAndroid uses separate audio streams for playing music, alarms,\nnotifications, the incoming call ringer, system sounds, in-call volume, and DTMF\ntones. This allows users to control the volume of each stream independently.\n\nBy default, pressing the volume control modifies the volume of the active audio\nstream. If your app isn't currently playing anything, hitting the volume keys\nadjusts the music volume (or the ringer volume before Android 9).\n\nUnless your app is an alarm clock, you should play audio with usage\n[AudioAttributes.USAGE_MEDIA](/reference/android/media/AudioAttributes#USAGE_MEDIA).\n\nTo ensure that volume controls adjust\nthe correct stream, you should call\n[setVolumeControlStream()](/reference/android/app/Activity#setVolumeControlStream(int))\npassing in the stream type matching your attributes that you can retrieve from\n[AudioAttributes.getVolumeControlStream](/reference/android/media/AudioAttributes#getVolumeControlStream()). \n\n### Kotlin\n\n```kotlin\nsetVolumeControlStream(AudioManager.STREAM_MUSIC)\n```\n\n### Java\n\n```java\nsetVolumeControlStream(AudioManager.STREAM_MUSIC);\n```\n\nMake this call in your app's lifecycle, typically from the `onResume()`\nmethod of the activity or fragment that controls your media. This connects\nthe volume controls to `STREAM_MUSIC` whenever the target activity or fragment\nis visible.\n\n### Controlling stream volume programmatically\n\nIn rare cases, you can set the volume of an audio stream programmatically. For\nexample, when your app replaces an existing UI. This is not recommended because\nthe Android `AudioManager` mixes all audio streams of the same type together.\nThese methods change the volume of every app that uses the stream. Avoid using\nthem:\n\n- [adjustStreamVolume()](/reference/android/media/AudioManager#adjustStreamVolume(int, int, int))\n- [adjustSuggestedStreamVolume()](/reference/android/media/AudioManager#adjustSuggestedStreamVolume(int, int, int))\n- [adjustVolume()](/reference/android/media/AudioManager#adjustVolume(int, int))\n- [setStreamVolume()\n setStreamVolume()](/reference/android/media/AudioManager#setStreamVolume(int, int, int))\n- [setStreamSolo()](/reference/android/media/AudioManager#setStreamSolo(int, boolean))\n- [setStreamMute()](/reference/android/media/AudioManager#setStreamMute(int, boolean))\n\nWorking with fixed-volume devices\n---------------------------------\n\nSome devices (like Chromebooks and Android Automotive OS cars) have volume\ncontrols but don't allow apps to use the `AudioManager` methods described\nearlier to change the level of an audio stream. These are called *fixed-volume*\ndevices. You can discover if your app is running on a fixed-volume device by\ncalling [`isVolumeFixed()`](/reference/android/media/AudioManager#isVolumeFixed()).\n\nAn audio app should provide the ability to balance\nits output volume with other apps that might be playing on the same stream.\nOn *fixed-volume* devices, the app should connect its own volume controls to the\nappropriate `setVolume()` method:\n\n| Player | Method |\n|-------------|---------------------------------------------------------------------------------------------------------------------------------|\n| AudioTrack | [AudioTrack.setVolume()](/reference/android/media/AudioTrack#setVolume(float)) |\n| MediaPlayer | [MediaPlayer.setVolume()](/reference/android/media/MediaPlayer#setVolume(float, float)) |\n| ExoPlayer | Use `SimpleExoPlayer.setVolume()` which sets the volume of the underlying AudioTrack. |\n| Web | Set the [`volume`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/volume) property of the `HTMLMediaElement` |\n\nDon't be noisy\n--------------\n\nUsers have a number of alternatives when it comes to enjoying the audio from\ntheir Android devices. Most devices have a built-in speaker, headphone jacks for\nwired headsets, and many also feature Bluetooth connectivity and support for\nA2DP audio.\n\nWhen a headset is unplugged or a Bluetooth device disconnected, the audio stream\nautomatically reroutes to the built-in speaker. If you listen to music at a high\nvolume, this can be a noisy surprise.\n\nUsers usually expect apps that include a music player with onscreen playback\ncontrols to pause playback in this case. Other apps, like games that don't\ninclude controls, should keep playing. The user can adjust the volume with the\ndevice's hardware controls.\n\nWhen audio output switches back to the built-in speaker the system broadcasts an [ACTION_AUDIO_BECOMING_NOISY](/reference/android/media/AudioManager#ACTION_AUDIO_BECOMING_NOISY)\nintent. You should create a [BroadcastReceiver](/reference/android/content/BroadcastReceiver)\nthat listens for this intent whenever you're playing audio. Your receiver should look like this: \n\n### Kotlin\n\n```kotlin\nprivate class BecomingNoisyReceiver : BroadcastReceiver() {\n\n override fun onReceive(context: Context, intent: Intent) {\n if (intent.action == AudioManager.ACTION_AUDIO_BECOMING_NOISY) {\n // Pause the playback\n }\n }\n}\n```\n\n### Java\n\n```java\nprivate class BecomingNoisyReceiver extends BroadcastReceiver {\n @Override\n public void onReceive(Context context, Intent intent) {\n if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {\n // Pause the playback\n }\n }\n}\n```\n\nRegister the receiver when you begin playback, and unregister it when you stop.\nIf you design your app as we describe in this guide, these calls should appear\nin the `onPlay()` and `onStop()` media session callbacks. \n\n### Kotlin\n\n```kotlin\nprivate val intentFilter = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)\nprivate val myNoisyAudioStreamReceiver = BecomingNoisyReceiver()\n\nprivate val callback = object : MediaSessionCompat.Callback() {\n\n override fun onPlay() {\n registerReceiver(myNoisyAudioStreamReceiver, intentFilter)\n }\n\n override fun onStop() {\n unregisterReceiver(myNoisyAudioStreamReceiver)\n }\n}\n```\n\n### Java\n\n```java\nprivate IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);\nprivate BecomingNoisyReceiver myNoisyAudioStreamReceiver = new BecomingNoisyReceiver();\n\nMediaSessionCompat.Callback callback = new\nMediaSessionCompat.Callback() {\n @Override\n public void onPlay() {\n registerReceiver(myNoisyAudioStreamReceiver, intentFilter);\n }\n\n @Override\n public void onStop() {\n unregisterReceiver(myNoisyAudioStreamReceiver);\n }\n}\n```"]]