Training—Managing Audio Playback
閱讀:https://developer.android.com/training/managing-audio/index.html
?
系統將音頻流分為了很多種:stream for playing music, alarms, notifications, the incoming call ringer, system sounds, in-call volume, and DTMF tones.
默認情況下,音量調整按鈕控制當前正在活動的音頻流。
setVolumeControlStream(AudioManager.STREAM_MUSIC);使用上面的方法,就能讓物理按鍵對當前聲明的音頻流的聲音大小進行控制。
用戶的一些暫停播放等操作,系統就會發出包含 ACTION_MEDIA_BUTTON 的intent,如果需要對其進行操作,那么就需要:
<receiver android:name=".RemoteControlReceiver"><intent-filter><action android:name="android.intent.action.MEDIA_BUTTON" /></intent-filter> </receiver>The receiver implementation itself needs to extract which key was pressed to cause the broadcast. The Intent includes this under the EXTRA_KEY_EVENT key, while the KeyEvent class includes a list KEYCODE_MEDIA_* static constants that represents each of the possible media buttons, such as KEYCODE_MEDIA_PLAY_PAUSE and KEYCODE_MEDIA_NEXT.
在傳來的intent里,包含著EXTRA_KEY_EVENT,可以從這里獲取KeyEvent,也就是用戶點擊的時間,例如?KEYCODE_MEDIA_PLAY_PAUSE and KEYCODE_MEDIA_NEXT.
public class RemoteControlReceiver extends BroadcastReceiver {@Overridepublic 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. }}} }Because multiple applications might want to listen for media button presses, you must also programmatically control when your app should receive media button press events.
The following code can be used within your app to register and de-register your media button event receiver using the AudioManager. When registered, your broadcast receiver is the exclusive receiver of all media button broadcasts.
AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE); ...// Start listening for button presses am.registerMediaButtonEventReceiver(RemoteControlReceiver); ...// Stop listening for button presses am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);通過上面的方法,就能自己控制所有的按鈕響應了。
?
?在安卓系統中,為了避免多個APP同時播放音樂,因此有了“audio focus”的概念,只有獲得audio focus的APP才應該播放音樂
?You must specify which stream you're using and whether you expect to require transient or permanent audio focus. Request transient focus when you expect to play audio for only a short time (for example when playing navigation instructions). Request permanent audio focus when you plan to play audio for the foreseeable future (for example, when playing music).
有兩種focus,transient or permanent audio focus。顧名思義,一個針對事件短暫的,例如短信通知聲,另一種是長久性的,例如播放音樂。
AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE); ...// Request audio focus for playback int result = am.requestAudioFocus(afChangeListener,// Use the music stream. AudioManager.STREAM_MUSIC,// Request permanent focus. AudioManager.AUDIOFOCUS_GAIN);if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);// Start playback. }上面代碼展示了如何獲得音樂的focus,如果要進行音樂播放,播放之前必須獲得focus!
// Abandon audio focus when playback complete am.abandonAudioFocus(afChangeListener);Once you've finished playback be sure to call abandonAudioFocus(). This notifies the system that you no longer require focus and unregisters the associated AudioManager.OnAudioFocusChangeListener. In the case of abandoning transient focus, this allows any interupted app to continue playback.
播放結束記得通知系統你播放完了,并且記得unregisters the associated AudioManager.OnAudioFocusChangeListener 。
能通過:
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);獲得duck,duck似乎是一個,當其他APP獲得transient audio focus的時候,音樂繼續播放,不過很小聲。
對于focus的loss我們同樣需要進行處理,下面的代碼展示了如何根據其他APP的FOCUS請求來進行相應的操作,一般來說,如果是因為其他APP的transient audio focus而失去焦點,那么應該會重獲焦點,如果是permanent audio focus 那我們應該停止很多操作:
OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {public void onAudioFocusChange(int focusChange) {if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT// Pause playback} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {// Resume playback } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);am.abandonAudioFocus(afChangeListener);// Stop playback }} };還可以手動使用DUCK:
OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {public void onAudioFocusChange(int focusChange) {if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {// Lower the volume} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {// Raise it back to normal }} };可通過AudioManage來對當前的輸出設配進行檢測:
if (isBluetoothA2dpOn()) {// Adjust output for Bluetooth. } else if (isSpeakerphoneOn()) {// Adjust output for Speakerphone. } else if (isWiredHeadsetOn()) {// Adjust output for headsets } else { // If audio plays and noone can hear it, is it still playing? }官方很貼心,它想到了一種情景:當輸出設備切換時的情況,有一種是因為藍牙失去連接,而這個時候如果你播放音樂,有可能是一種噪聲,好在這種時候系統會發出廣播:
private class NoisyAudioStreamReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {// Pause the playback }} }private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);private void startPlayback() {registerReceiver(myNoisyAudioStreamReceiver(), intentFilter); }private void stopPlayback() {unregisterReceiver(myNoisyAudioStreamReceiver); }?
?
?
?
?
轉載于:https://www.cnblogs.com/yutoulck/p/3404470.html
總結
以上是生活随笔為你收集整理的Training—Managing Audio Playback的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vim7.4官方源码在vs2013的编译
- 下一篇: wpf控件提示Value ‘’ can