识别音频流
创造优秀音频体验的第一步是了解您的应用程序将使用的音频流类型。
Android 系统保持相互独立的音频流通道来播放音乐,报警,通知,来电铃声,系统声音,呼叫(通话)音量,和 DTMF 音调(键盘拨号)。
这样做主要是为了使用户能够独立地控制每个流的音量。
多数的流仅限于系统事件,所以,除非您的应用程序是要更换闹钟,否则几乎可以肯定的是使用 STREAM_MUSIC 音频流。
使用硬件音量按键来控制应用程序的音量
默认情况下,按音量键控制修改当前获得焦点的音频流的音量。假如您的应用程序当前不是正在播放音乐,或者没有运行,那么音量键将会调整振铃的音量。
如果您有一个游戏或音乐应用程序,当用户点击音量键的时候,即使他们目前正在浏览歌曲,或者没有停留在当前的音乐游戏的位置,他们仍然希望控制游戏或音乐的音量。
您可以通过接收音量控制键的按键消息来修改当前的音频流音量。不过不用那么麻烦 ,Android 已经提供了方便的 setVolumeControlStream() 方法来根据您指定的音频流来自动调节音量。
首先确定您的应用程序将使用的音频流,然后通过 setVolumeControlStream 方法设置其为当前焦点的音频流。
这个方法应该被及早调用,并且在生命周期中只需要调用一次即可,所以通常应在 Activity 或者 Fragment 的 OnCreate() 内 调用。
这将确保只要你的应用程序是可见状态的,音量控制功能就是用户所期望的效果(即控制当前应用程序的音量)。
代码示例:
setVolumeControlStream(AudioManager.STREAM_MUSIC);
从现在开始,按设备上的音量键将影响您指定的(示例“音乐”)的音频流。
使用硬件播放控制按键来控制应用程序的音频播放
很多手机和许多无线耳机都附带有媒体播放控制按钮,如播放,暂停,停止,跳过。每当用户按下这些硬件键,系统就会广播 ACTION_MEDIA_BUTTON 动作。
为了响应媒体按钮的点击事件,您需要注册 BroadcastReceiver 来监听广播。
代码示例:
<receiver android:name=".RemoteControlReceiver"> <intent-filter> <action android:name="android.intent.action.MEDIA_BUTTON" /> </intent-filter> </receiver>
Receiver 中需要知道到底是按下了哪个键的具体信息,Intent 中包括了 EXTRA_KEY_EVENT 键值,可以通过它来取得KeyEvent 类型的值 ,KeyEvent中的KEYCODE_MEDIA_*静态常量表示了所有的媒体按钮类型,如 KEYCODE_MEDIA_PLAY_PAUSE 和 KEYCODE_MEDIA_NEXT 等等。
代码示例:
public class RemoteControlReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) { KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); if (KeyEvent.KEYCODE_MEDIA_PLAY == event.getKeyCode()) { // Handle key press. // 处理播放按键的消息 } } } }
因为多个应用程序可能会接听和响应媒体按键消息,您必须以编程方式控制您的应用程序何时应该接受媒体按钮事件。
在您的应用程序中可以使用 AudioManager 来注册和取消注册媒体按钮的事件接收器,注册时,使用您的专用事件接收器。
示例代码 :
AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE); ... // Start listening for button presses 开始 监 听 am.registerMediaButtonEventReceiver(RemoteControlReceiver); ... // Stop listening for button presses 取消 监 听 am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
通常情况下,应用程序在失去焦点或不在屏幕显示隐藏到后台的时候, 应注销其大部分的接听器(如在 onStop() 回调函数中) 。
然而,对于媒体播放应用程序却没有这么简单,事实上,最重要的是,当您的应用程序是处于不可见的状态时,此时不能由屏幕上的 UI 控制,但是仍然需要响应媒体播放控制按钮(最典型的就是后台播放音乐) 。
所以,一个更好的方法是:当您的应用程序获得和失去音频焦点的时候分别注册和注销媒体按钮的事件接收器,而不仅仅是依赖于应用程序的界面状态 。
具体方案请参考下一节课程。
参考文摘:
https://developer.android.com/training/managing-audio/volume-playback.html