如果你的APP要播放一个音频文件,那么让你的用户可以按照用户预期的动作来控制这个音频的播放时非常重要的。为了达到最好的用户体验,你的APP需要管理当前的音频播放,保证不是有多个应用在同一时间都在播放音频。一个好的用户体验是要可预期的。如果你的APP可以播放音频,那么用户必须可以来通过一些设备的软件或者硬件来控制你的APP播放音频的音量大小,如蓝牙耳机,头戴耳机等等。
同样的,在合适的地方,播放,暂停,停止,跳过,前一首这些操作按钮,在你的APP中使用的时候,都应该执行的各自恰当的播放控制动作。
确定要使用的音频流
要创建一个可预期控制的音频播放体验,首先要明白你的APP要使用的音频流。
android平台包含了一个单独的音频流用来播放音乐,闹钟,通知,来电铃声,系统声音,来电通话,双音多频铃声。这么做的首要目的是要让用户可以分别独立的控制每一个音频流的音量。
绝大部分音频流都是仅仅限制被被系统事件使用,所以除非你的APP要代替闹铃,你的APP才能用STREAM_MUSIC流来播放音频。
使用硬件声音播放控制按钮来控制你的APP播放音频的音量大小
默认的,按硬件的控制按钮会改变当前活动的音频流的大小。如果你的APP当前什么也没有播放,当前的的音量控制键按下的时候被调整到用来调节铃声的音量。
如果当前你在使用一个音乐或者游戏APP,那么这个时候用户最希望的结果是当他按下音量控制按键的时候,调整的是音乐或者游戏APP的声音大小,即使用户现在也在听一个歌曲或者说游戏APP根本没放音乐。
你也许想尝试采用监听音量控制按钮的办法来根据用户的按下来调整你的APP使用的音频流的音量大小。忍住这么做的冲动,不要这么来。android提供了setVolumeControlStream()方法来方便的直接管理针对你指定的音频流时候的按钮按下操作。
首先确定出你的APP使用的音频流,你需要把这个音频流设定为要使用的音频流,你要在activity的声明周期的开始的初期设置它。因为这样的话你就只需要设置一次,所以最好是在onCreate函数里面设置(Activity或者是
Fragment 里面播放音频
)。这样就保证了当你的APP显示出来的时候,音量控制按钮可以按照用户预期的工作。
setVolumeControlStream(AudioManager.STREAM_MUSIC);
从这一点向前看,当activity或者fragment显示出来的时候,按下音量按钮影响的是你指定的音频流(上面这个例子里面就是“音乐”)。
使用硬件的播放控制按钮来控制你的APP的音频播放与停止
多媒体控制播放按钮,如播放,暂停,停止,跳过或者前一首,在许多的有线,或者无线耳机上都有这个按钮。当用户按下这类设备上的按钮的时候,系统会广播一个带有ACTION_MEDIA_BUTTON动作的intent.
为了对这个这个按钮动作做出响应,你的程序需要在manifest里面注册对这个广播的接收,来监听上面的广播:
在这个receiver里面需要指出了那个action会触发这个广播。intent里面有EXTRA_KEY_EVENT这个数据,这个里面可以是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.
}
}
}
}
因为会有很多个程序都会想要监听这个按钮,你必须通过编程的方式来控制你的程序监听到这个按钮的广播。
下面的代码可以用来注册和注销你的APP对这个广播的监听,用AudioManager实现
。当注册时候,你的这个广播接收器是独有的可以接收这个多媒体按钮的接收器。
AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
...
// Start listening for button presses
am.registerMediaButtonEventReceiver(RemoteControlReceiver);
...
// Stop listening for button presses
am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
一般来说,当APP不可见或者暂停的时候,要取消对广播监听的注册。但是事实上并不是那么简单对于多媒体的APP而言,当你的APP不可见的时候,用户无法操作UI来控制的时候,可能依然需要对多媒体按钮做出反应。
一个好的办法是,在你的APP需要控制的时候,注册对这个广播的接收,不需要的时候,注销对这个广播的接收,这个下一节里面讲述。