android 多媒体音频占用情况监听

什么场景适合? 

如果你的app有长时间(大于一两秒)使用到音频,比如音乐视频的播放,录音,或者网络软件通话。这些场景在音频被占用时,你是需要做适当处理 或暂停,或退出,或降低音量;在音频被其他软件释放时,再及时恢复app状态。

本文章的bug:部分手机可以监听音频被占用的情况,但是监听不到释放的情况,导致恢复app状态的动作不能执行(在这样的手机上发现其他app也无法恢复状态—>疑是系统释放了)。

 

下面的案例没有正儿八经使用音频,具体使用只需要实现最底下的四个方法即可。

其实对音频的控制只做app占用的情况还不够全面,应该加上对电话状态的监听才全面,请看最下面一段代码

 

注意点:

1.有版本的区别

2.type最好使用music,这是恢复播放比较好的一种类型了

public class SoftCallListenerActivity extends AppCompatActivity implements AudioManager.OnAudioFocusChangeListener {
    public static final String TAG = "SoftCallListenerActivity";

    AppCompatTextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_solf_call_listener);
        textView = findViewById(R.id.atv);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            audioListener();
        } else {
            audioListenerD26();
        }
    }

    AudioManager audioManager;

    AudioAttributes playbackAttributes;
    AudioFocusRequest focusRequest;

    final Object focusLock = new Object();

    private void audioListenerD26() {
        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        int result = audioManager.requestAudioFocus(this,
                AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_GAIN);

        if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
            playbackNow();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void audioListener() {
        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        playbackAttributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_GAME)
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .build();
        focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
                .setAudioAttributes(playbackAttributes)
                .setAcceptsDelayedFocusGain(true)
                .setOnAudioFocusChangeListener(this, handler)
                .build();
        request();
    }

    @Override
    protected void onResume() {
        super.onResume();
        Logs.w(TAG, "onResume:  request" );
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            request();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void request(){
        int res = audioManager.requestAudioFocus(focusRequest);
        synchronized (focusLock) {
            if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
                playbackNowAuthorized = false;
            } else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                playbackNowAuthorized = true;
                playbackNow();
            } else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
                playbackDelayed = true;
                playbackNowAuthorized = false;
            }
        }
    }
    Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            Logs.w(TAG, "handleMessage:" + msg.what);
        }
    };

    boolean playbackDelayed = false;
    boolean playbackNowAuthorized = false;
    boolean resumeOnFocusGain = false;

    @Override
    public void onAudioFocusChange(int focusChange) {
        Logs.w(TAG, "onAudioFocusChange:" + focusChange);
        switch (focusChange) {
            case AudioManager.AUDIOFOCUS_GAIN:
                if (playbackDelayed || resumeOnFocusGain) {
                    synchronized (focusLock) {
                        playbackDelayed = false;
                        resumeOnFocusGain = false;
                    }
                    playbackNow();
                }
                break;
            case AudioManager.AUDIOFOCUS_LOSS:
                synchronized (focusLock) {
                    resumeOnFocusGain = false;
                    playbackDelayed = false;
                }
                pausePlayback();
                break;
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                synchronized (focusLock) {
                    resumeOnFocusGain = true;
                    playbackDelayed = false;
                }
                pausePlayback();
                break;
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                playDependsYourDear();
                break;
        }
    }

    private void playDependsYourDear() {
        Logs.w(TAG, "playDependsYourDear");
    }

    private void playbackNow() {
        Logs.w(TAG, "playbackNow");
    }

    private void pausePlayback() {
        Logs.w(TAG, "pausePlayback");
    }
    /**
    *当app的音频使用完毕,应该主动释放,这样其他app才能及时响应
    */
    private void playComplete() {
        Logs.w(TAG, "playComplete");
        audioManager.abandonAudioFocus(this);
    }
}
private void telephony() {
        if (mTelephonyManager == null)
            mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        mPanelBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
                    try {
                        JSONObject jsonObject = new JSONObject();
                        int state = mTelephonyManager.getCallState();
                        switch (state) {
                            case TelephonyManager.CALL_STATE_IDLE:// 电话挂断 
                                Logs.w(TAG, "电话挂断..."); 
                                break;
                            case TelephonyManager.CALL_STATE_OFFHOOK: //电话通话的状态 
                                Logs.w(TAG, "正在通话...");
                                break;
                            case TelephonyManager.CALL_STATE_RINGING: //电话响铃的状态 
                                Logs.w(TAG, "电话响铃...");
                                break;
                        }
                        sendMessage(jsonObject.toString());
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        IntentFilter panelFilter = new IntentFilter();
        panelFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
        panelFilter.setPriority(Integer.MAX_VALUE);
        mContext.registerReceiver(mPanelBroadcastReceiver, panelFilter, null, null);
    }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值