由于在API O中requestAudioFocus(AudioManager.OnAudioFocusChangeListener l, int streamType, int durationHint)
已被弃用,那么如何使用AudioFocusRequest设置音频焦点变更监听器呢?
由于在API O中requestAudioFocus(AudioManager.OnAudioFocusChangeListener l, int streamType, int durationHint)
已被弃用,那么如何使用AudioFocusRequest设置音频焦点变更监听器呢?
https://developer.android.com/guide/topics/media-apps/audio-focus此为资源的官方链接
AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mAudioManager.requestAudioFocus(new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build()
)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(new AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
//Handle Focus Change
}
}).build()
);
} else {
mAudioManager.requestAudioFocus(focusChange -> {
//Handle Focus Change for earliest version of oreo
},
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
}
class MyClass : AudioManager.OnAudioFocusChangeListener {
internal var audioManager: AudioManager? = null
private var focusRequest: AudioFocusRequestCompat? = null
private var playbackAttributes : AudioAttributesCompat? = null
// Create AudioManager and other audio related objects
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager?
playbackAttributes = AudioAttributesCompat.Builder()
.setUsage(AudioAttributesCompat.USAGE_MEDIA)
.setContentType(AudioAttributesCompat.CONTENT_TYPE_SPEECH)
.build()
focusRequest = AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN)
.setAudioAttributes(playbackAttributes ?: return)
.setWillPauseWhenDucked(false)
.setOnAudioFocusChangeListener(this)
.build()
// Request audio focus and check if it was granted to us
if (requestAudioFocus(audioManager!!, focusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// We obtained audio focus
}
else {
// We could not obtain audio focus
}
// And to remove audio focus
if (audioManager != null && focusRequest != null)
abandonAudioFocusRequest(audioManager!!, focusRequest!!)
// Implementation of OnAudioFocusChangeListener
override fun onAudioFocusChange(focusState: Int) {
// Invoked when the audio focus of the system is updated.
when (focusState) {
AudioManager.AUDIOFOCUS_GAIN -> {
// We recovered audio focus.
Timber.d("Audio Focus obtained")
}
AudioManager.AUDIOFOCUS_LOSS -> {
// Lost focus for an unbounded amount of time
Timber.d("Audio Focus lost")
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
// Lost focus for a short time, but it's ok to keep playing at an attenuated level
Timber.d("Audio Focus transient loss - can duck")
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
// Lost focus for a short time
Timber.d("Audio Focus transient loss - cannot duck")
}
}
}
}
我在官方文档中发现了以下内容:
请求音频焦点:您的服务可以使用requestAudioFocus()方法提交更精细的请求,以接收设备范围内的音频焦点。传递一个AudioFocusRequest对象,您可以使用AudioFocusRequest.Builder创建该对象。在这个构建器类中,您可以指定以下选项:
您希望获得的焦点类型,例如AUDIOFOCUS_GAIN_TRANSIENT或AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK。当另一个音频服务接管设备焦点时,您的服务是否应该继续更安静地播放或完全暂停。您的服务是否可以等待直到设备准备好才能获得焦点。
注意:当构建您的AudioFocusRequest实例时,如果您通过调用setAcceptsDelayedFocusGain()表示您的服务可以等待产生声音,则还必须调用setOnAudioFocusChangeListener(),以便您的服务知道何时可以开始产生声音。
正如@kelebro63所提到的,以下示例显示如何使用AudioFocusRequest.Builder
构建AudioFocusRequest
并请求和放弃音频焦点:
mAudioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
mPlaybackAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(mPlaybackAttributes)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(mMyFocusListener, mMyHandler)
.build();
mMediaPlayer = new MediaPlayer();
final Object mFocusLock = new Object();
boolean mPlaybackDelayed = false;
boolean mPlaybackNowAuthorized = false;
// ...
int res = mAudioManager.requestAudioFocus(mFocusRequest);
synchronized(mFocusLock) {
if (res == AUDIOFOCUS_REQUEST_FAILED) {
mPlaybackNowAuthorized = false;
} else if (res == AUDIOFOCUS_REQUEST_GRANTED) {
mPlaybackNowAuthorized = true;
playbackNow();
} else if (res == AUDIOFOCUS_REQUEST_DELAYED) {
mPlaybackDelayed = true;
mPlaybackNowAuthorized = false;
}
}
// ...
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
if (mPlaybackDelayed || mResumeOnFocusGain) {
synchronized(mFocusLock) {
mPlaybackDelayed = false;
mResumeOnFocusGain = false;
}
playbackNow();
}
break;
case AudioManager.AUDIOFOCUS_LOSS:
synchronized(mFocusLock) {
mResumeOnFocusGain = false;
mPlaybackDelayed = false;
}
pausePlayback();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
synchronized(mFocusLock) {
mResumeOnFocusGain = true;
mPlaybackDelayed = false;
}
pausePlayback();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// ... pausing or ducking depends on your application
break;
}
}
}
参考资料:
要获得焦点,请使用以下代码(它会暂停其他播放器):
mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
mAudioManager.requestAudioFocus(null,AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
要取消焦点,请使用以下内容(这将恢复该播放器):
mAudioManager.abandonAudioFocus(null);