Android 多个应用之间声音竞争之Android 系统处理音频焦点(AudioFocus)

问题发现

最近在项目中发现我们的自己的apk和第三方的媒体apk会出现串音问题。即两者之间的声音会重叠在一起。

解决问题

1. 使用多媒体按键去控制第三方应用的声音播放(无效果)

通过触发媒体的按钮来操作播放器状态:KeyEvent.KEYCODE_MEDIA_PAUSE

public static void sendMediaButton(Context context, int keyCode) {
    AudioManager audioManager= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    //先判断后台是否再播放音乐
    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);
    }
}

不知为什么,使用后没有效果。于是就有了以下的方法

2. 使用AudioFocus 音频焦点(问题得到解决)
AudioFoucs 简介

Android 开发中免不了需要播放视频,音频文件,但是手机上可能有其他的一些软件,在后台播放音频的时候,这个时候另外的软件也需要播放音频,这个时候就会出现俩个音频同时播放的问题,在 Android2.2 之后提供了 audioFocus获取音频的焦点,但是这个并不是强制需要实现的,所以当你在测试的时候,有的应用没有处理音频焦点,所以会有和其他应用串音的现象。

个人认为这个 audiofocus 就类似于一个 flag 全局变量一样。然后各个应用根据这个值是设置自己的音频要播放还是暂停。如果获得了焦点,则可以播放,如果失去了焦点,则应该暂停正在播放的音频。

AudioFocus 用法
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN)

此处 requestAudioFocus后面第一参数传null,是直接去请求音频焦点的动作。当然这里不建议这样。这种太暴力。建议null这里替换成一个listener监听。然后通过去实现这个listener去监听焦点的变化,从而去做一些暂停播放音乐的动作。

  audioManager.requestAudioFocus(mAudioFocusChange , AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN)
 private AudioManager.OnAudioFocusChangeListener mAudioFocusChange = new
    AudioManager.OnAudioFocusChangeListener() {
    @Override
    public void onAudioFocusChange(int focusChange) {
    switch (focusChange){
        case AudioManager.AUDIOFOCUS_GAIN:
              //当其他应用申请焦点之后又释放焦点会触发此回调
              //可重新播放音乐
             Log.d(TAG, "AUDIOFOCUS_GAIN");
             start();
             break;
        case AudioManager.AUDIOFOCUS_LOSS:
              //长时间丢失焦点,当其他应用申请的焦点为 AUDIOFOCUS_GAIN 时,
             //会触发此回调事件,例如播放 QQ 音乐,网易云音乐等
             //通常需要暂停音乐播放,若没有暂停播放就会出现和其他音乐同时输出声音
            Log.d(TAG, "AUDIOFOCUS_LOSS");
            stop();
           //释放焦点,该方法可根据需要来决定是否调用
           //若焦点释放掉之后,将不会再自动获得
           mAudioManager.abandonAudioFocus(mAudioFocusChange);
           break;
        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
             //短暂性丢失焦点,当其他应用申请 AUDIOFOCUS_GAIN_TRANSIENT 或
             AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE 时,
            //会触发此回调事件,例如播放短视频,拨打电话等。
             //通常需要暂停音乐播放
             stop();
            Log.d(TAG, "AUDIOFOCUS_LOSS_TRANSIENT");
            break;
        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
             //短暂性丢失焦点并作降音处理
           Log.d(TAG, "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
           break;
                                           }
                      }
    };

使用完后丢点焦点:

audioManager .abandonAudioFocus(mAudioFocusChange )
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

假装多好123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值