實測Android音頻的焦點獲取和歸還
前言
最近老板想在產(chǎn)品中的短視頻后者直播播放的時候?qū)τ谑謾C中的音樂播放器進行暫停播放舆蝴,并且退出視頻播放后手機的音樂播放器還能繼續(xù)播放之前的音樂。
先試試微信,emmm洁仗,確實可以贡珊。
官網(wǎng)管理音頻焦點準(zhǔn)則:
- 在即將開始播放之前調(diào)用
requestAudioFocus()
冗尤,并驗證調(diào)用是否返回AUDIOFOCUS_REQUEST_GRANTED
。如果按照本指南中的說明設(shè)計應(yīng)用播瞳,則應(yīng)在媒體會話的onPlay()
回調(diào)中調(diào)用requestAudioFocus()
互艾。 - 在其他應(yīng)用獲得音頻焦點時瞎领,停止或暫停播放泥张,或降低音量忽匈。
- 播放停止后,放棄音頻焦點方淤。
不同版本音頻焦點的處理方式不太相同:
從 Android 2.2(API 級別 8)開始,應(yīng)用通過調(diào)用
requestAudioFocus()
和abandonAudioFocus()
來管理音頻焦點蹄殃。應(yīng)用還必須為這兩個調(diào)用注冊AudioManager.OnAudioFocusChangeListener
携茂,以便接收回調(diào)并管理自己的音量。對于以 Android 5.0(API 級別 21)及更高版本為目標(biāo)平臺的應(yīng)用诅岩,音頻應(yīng)用應(yīng)使用
AudioAttributes
來描述應(yīng)用正在播放的音頻類型讳苦。例如,播放語音的應(yīng)用應(yīng)指定CONTENT_TYPE_SPEECH
吩谦。面向 Android 8.0(API 級別 26)或更高版本的應(yīng)用應(yīng)使用
requestAudioFocus()
方法鸳谜,該方法會接受AudioFocusRequest
參數(shù)。AudioFocusRequest
包含有關(guān)應(yīng)用的音頻上下文和功能的信息式廷。系統(tǒng)使用這些信息來自動管理音頻焦點的得到和失去咐扭。
API介紹
處理音頻焦點都是通過AudioManager這個類,如下是獲得該類實例的方法:
AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
requestAudioFocus()
//用于申請音頻焦點
abandonAudioFocus()
//用于釋放音頻焦點
AudioManager.OnAudioFocusChangeListener
接口滑废,提供了onAudioFocusChange()
方法來監(jiān)聽音頻焦點變化
-
requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)
參數(shù):AudioManager.OnAudioFocusChangeListener l
:
用于監(jiān)聽音頻焦點變化蝗肪,從而可以進行適當(dāng)?shù)牟僮鳎鐣和2シ诺取?/p>-
streamType
:
申請音頻焦點處理的音頻類型蠕趁,例如薛闪,當(dāng)播放音樂時,可以傳入STREAM_MUSIC
俺陋;當(dāng)播放鈴聲時豁延,可以傳入STREAM_RING
。表中列出了一些的可選值:類型 含義 值 STREAM_VOICE_CALL 通話 0 STREAM_SYSTEM 系統(tǒng) 1 STREAM_RING 鈴聲 2 STREAM_MUSIC 音樂 3 STREAM_ALARM 鬧鈴 4 STREAM_NOTIFICATION 系統(tǒng)通知 5 ... ... ... durationHint
(PS:重要參數(shù)):
可選值有以下五個:
(1)AUDIOFOCUS_GAIN
: 此參數(shù)表示希望申請一個永久的音頻焦點腊状,并且希望上一個持有音頻焦點的App停止播放诱咏;例如在需要播放音樂時。
(2)AUDIOFOCUS_GAIN_TRANSIENT
:表示申請一個短暫的音頻焦點寿酌,并且馬上就會被釋放胰苏,此時希望上一個持有音頻焦點的App暫停播放。例如播放一個提醒聲音。
(3)AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
:效果同AUDIOFOCUS_GAIN_TRANSIENT
硕并,只是希望上一個持有焦點的App減小其播放聲音(但仍可以播放)法焰,此時會混音播放。例如導(dǎo)航播報倔毙。
(4)AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
: 表示申請一個短暫的音頻焦點埃仪,并且會希望系統(tǒng)不要播放任何突然的聲音(例如通知,提醒等)陕赃,例如用戶在錄音卵蛉。返回值:
AUDIOFOCUS_REQUEST_GRANTED
或者AUDIOFOCUS_REQUEST_FAILED
。
abandonAudioFocus(OnAudioFocusChangeListener l)
參數(shù)通上AudioManager.OnAudioFocusChangeListener
.AudioManager.OnAudioFocusChangeListener
:當(dāng)音頻焦點發(fā)生變化時進行onAudioFocusChange(int focusChange)
方法的回調(diào)么库;
new AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// TBD 繼續(xù)播放
break;
case AudioManager.AUDIOFOCUS_LOSS:
// TBD 停止播放
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// TBD 暫停播放
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// TBD 混音播放
break;
default:
break;
}
}
};
實測代碼:
核心是需要把 AudioManager.AUDIOFOCUS_GAIN
改為 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
public class MainActivity extends Activity {
private AudioManager mAudioManager;
private AudioFocusRequest mFocusRequest;
private AudioManager.OnAudioFocusChangeListener mListener;
private AudioAttributes mAttribute;
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mListener = new AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// TBD 繼續(xù)播放
break;
case AudioManager.AUDIOFOCUS_LOSS:
// TBD 停止播放
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// TBD 暫停播放
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// TBD 混音播放
break;
default:
break;
}
}
};
//android 版本 5.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mAttribute = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
}
//android 版本 8.0
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
.setWillPauseWhenDucked(true)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(mListener, mHandler)
.setAudioAttributes(mAttribute)
.build();
}
}
private void requestAudioFocus() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mAudioManager.requestAudioFocus(mFocusRequest);
} else {
mAudioManager.requestAudioFocus(mListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
}
}
private void abandonAudioFocus() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mAudioManager.abandonAudioFocusRequest(mFocusRequest);
} else {
mAudioManager.abandonAudioFocus(mListener);
}
}
}
參考:
https://segmentfault.com/a/1190000022234509
http://www.reibang.com/p/26ea60c499a7
文章到這里就全部講述完啦傻丝,若有其他需要交流的可以留言哦~!~诉儒!