用户希望能够控制音频应用的音量。标准行为 包括使用音量控件(设备上的按钮或旋钮) 设备或滑块),并避免在音乐播放时 使用时,耳机等外围设备会断开连接。
使用音量控件
用户按游戏或音乐应用中的音量键时,音量应 即使播放器在歌曲间暂停或播放时没有音乐, 当前游戏位置。
Android 会使用单独的音频流来播放音乐、闹钟和 通知、来电铃声、系统提示音、通话音量和 DTMF 音调。这样,用户就可以独立控制每个音频流的音量。
默认情况下,按音量控件可调节当前音频的音量 。如果您的应用当前未播放任何内容,请按音量键 调节音乐音量(在 Android 9 之前,调节铃声音量)。
除非您的应用是闹钟,否则您应播放与使用情况相关的音频
AudioAttributes.USAGE_MEDIA
。
为了确保音量控件能够调节
正确的流,则应调用
setVolumeControlStream()
传入与属性匹配的流类型,您可以从中检索
AudioAttributes.getVolumeControlStream
。
Kotlin
setVolumeControlStream(AudioManager.STREAM_MUSIC)
Java
setVolumeControlStream(AudioManager.STREAM_MUSIC);
在应用的生命周期(通常从 onResume()
中)发出此调用
方法。这会将
每当目标 activity 或 fragment 将音量控制为 STREAM_MUSIC
可见。
以编程方式控制音频流音量
在极少数情况下,您可以通过编程方式设置音频流的音量。对于
例如,当应用替换现有界面时。我们不建议这样做,因为
Android AudioManager
会将所有相同类型的音频流混合在一起。
以下方法会改变使用该音频流的每个应用的音量。避免使用
:
adjustStreamVolume()
adjustSuggestedStreamVolume()
adjustVolume()
setStreamVolume() setStreamVolume()
setStreamSolo()
setStreamMute()
使用固定音量设备
某些设备(例如 Chromebook)具有音量控件,但不允许应用使用 AudioManager
方法更改音频流的音量。这些称为
固定音量设备。您可以查看
应用正在通过调用 isVolumeFixed()
在固定音量设备上运行。
音频应用应该能够
与可能在同一音频流中播放的其他应用的输出音量相同。
在固定音量设备上,应用应将自己的音量控件连接到
下表中相应的 setVolume()
方法:
球手 | 方法 |
---|---|
AudioTrack | AudioTrack.setVolume() |
MediaPlayer | MediaPlayer.setVolume() |
ExoPlayer | 使用 SimpleExoPlayer.setVolume() 设置底层 AudioTrack 的音量。 |
不要发出噪音
用户可通过多种选择来欣赏 Android 设备的用户。大部分设备都有内置扬声器和耳机插孔 有线耳机,很多还具有蓝牙连接功能,并且支持 A2DP 音频。
当耳机被拔出或蓝牙设备断开连接时,音频流 自动路由到内置扬声器。如果您以较高的音量听音乐 这可能有点令人惊讶
用户通常希望应用包含支持屏幕播放的音乐播放器 用于暂停播放的控件。其他应用,例如 包含控件,应继续播放。用户可以使用 设备的硬件控件
当音频输出切换回内置扬声器时,系统会广播 ACTION_AUDIO_BECOMING_NOISY
intent。您应该创建一个 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); } }