音频焦点的监听

AUDIOFOCUS_GAIN_TRANSIENT:获取的短暂的焦点,就是告知被剥夺者,你很快会重获焦点。对应AUDIOFOCUS_LOSS_TRANSIENT

AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:获取焦点,告知被剥夺者,你可以继续播放并将音量降为0或者低音量播放。对应AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK

AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:获取短暂焦点,但非常期望没有其他声音在播放。这个没有对应的loss标志。

AUDIOFOCUS_GAIN:获取较长期的焦点,对应AUDIOFOCUS_LOSS;
原文参考:https://blog.csdn.net/b1480521874/article/details/54669032 
public class MainActivity extends AppCompatActivity {
    public static String TAG=MainActivity.class.getName();
    private AudioManager audioManager;
    private AudioManager.OnAudioFocusChangeListener changeListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        sendMediaButton(this, KeyEvent.KEYCODE_MEDIA_PAUSE);
    }

    public void sendMediaButton(Context context, int keyCode) {
        //先判断后台是否再播放音乐
        /*if (audioManager.isMusicActive()) {
            KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
            Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
            intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
            context.sendOrderedBroadcast(intent, null);

            keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
            intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
            intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
            context.sendOrderedBroadcast(intent, null);
        }*/
        changeListener = new AudioManager.OnAudioFocusChangeListener() {
            @Override
            public void onAudioFocusChange(int i) {
                switch (i) {
                    //会长时间失去,所以告知下面的判断,获得焦点后不要自动播放
                    case AudioManager.AUDIOFOCUS_LOSS:
                        Log.i(TAG,"AudioManager.AUDIOFOCUS_LOSS");
                        break;
                    //别的播放
                    //短暂失去焦点,先暂停。同时将标志位置成重新获得焦点后就开始播放
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        Log.i(TAG,"AudioManager.AUDIOFOCUS_LOSS_TRANSIENT");
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                        Log.i(TAG,"AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
                        break;
                    //重新获得焦点,且符合播放条件,开始播放
                    case AudioManager.AUDIOFOCUS_GAIN:
                        Log.i(TAG,"AudioManager.AUDIOFOCUS_GAIN");
                        break;
                }
            }
        };
//      AudioManager.AUDIOFOCUS_LOSS_TRANSIENT-->AudioManager.AUDIOFOCUS_GAIN
        audioManager.requestAudioFocus(changeListener, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
        audioManager.requestAudioFocus(changeListener, AudioManager.STREAM_ALARM, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
        audioManager.requestAudioFocus(changeListener, AudioManager.STREAM_RING, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

        audioManager.requestAudioFocus(changeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        audioManager.abandonAudioFocus(changeListener);
    }
}

高版本的监听(26以上)

 AudioFocusRequest.Builder builder = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
        builder.setOnAudioFocusChangeListener(new AudioManager.OnAudioFocusChangeListener() {
            @Override
            public void onAudioFocusChange(int focusChange) {

            }
        });
        mAudioManager.requestAudioFocus(builder.build());

对应的
发起方强制获取AUDIOFOCUS_GAIN 接收方只会接收到AudioManager.AUDIOFOCUS_LOSS
发起方短暂获取AUDIOFOCUS_GAIN_TRANSIENT接收方在发起方发起时会触发AUDIOFOCUS_LOSS_TRANSIENT,以及恢复的时候会触发AudioManager.AUDIOFOCUS_GAIN

### 手机音频焦点管理机制 在移动设备上,多个应用程序可能同时请求播放音频资源。为了协调这些应用之间的音频输出并提供良好的用户体验,操作系统引入了音频焦点管理系统[^1]。 当某个应用希望开始播放声音时,该应用会向系统申请获得音频焦点。如果当前没有其他应用持有焦点,则新申请的应用将被授予焦点;如果有更高优先级的应用正在使用音频焦点,那么新的请求可能会失败或等待现有焦点释放后再尝试获取[^2]。 #### 音频焦点状态变化通知 每当音频焦点的状态发生改变——无论是因为有新的应用获得了焦点还是之前拥有者放弃了它——都会触发相应的广播事件给所有监听此变更的应用程序。这使得各个应用能够及时调整自己的行为来响应最新的情况: - 当失去焦点时,通常的做法是暂停播放或将音量调低; - 而重新得到焦点之后则可以恢复正常的音频输出水平[^3]。 ```java AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() { public void onAudioFocusChange(int focusChange) { switch(focusChange){ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // Lower the volume while another app is playing sound temporarily. break; case AudioManager.AUDIOFOCUS_GAIN: // Resume normal playback after transient loss of focus ends. break; default: // Handle other cases as needed... } } }; ``` ### 实现方式概述 对于开发者来说,在构建涉及媒体播放功能的应用时应当遵循上述提到的原则,并通过API接口与系统的音频服务进行交互以正确处理音频焦点的变化。具体而言,可以通过`requestAudioFocus()`方法请求获得音频焦点,并注册一个实现了`OnAudioFocusChangeListener`接口的对象用于接收来自系统的反馈信息关于何时应该做出相应的行为调整[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值