音频管理器

AudioManager这个音频管理器,它可以通过getSystemService得到。

(AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

方法介绍

  • setStreamVolume(int StreamType,int index,int flags):直接设置手机的指定类型的音量值

    streamType 这个参数指定了声音的类型,如下

    • STREAM_ALARM:手机闹铃声音

    • STREAM_DTMF:DTMF音调的声音

    • STREAM_MUSIC:手机音乐的声音

    • STREAM_NOTFICATION:系统提示的声音

    • STREAM_RING:电话铃声的声音

    • STREAM_SYSTEM:手机系统的声音(不知道什么是系统声音,按键的声音?)

    • STREAM_VOICE_CALL:语音电话的声音

    direction: 这个参数代表声音增大还是减少

    flags:调整声音时的标志,例如指定FLAG_SHOW_UI,指定调整声音时显示音量进度条

  • setMicrophoneMute(boolean on):设置是否让麦克风静音
  • setMode(int mode):设置声音模式,可设置的值有NORMAL,RINGTONE和IN_CALL
  • setRingMode(int ringerMode):设置手机的电话铃声的模式

    有如下集中几种

    • RINGER_MODE_NORMAL:正常手机铃声

    • RINGER_MODE_SILENT:手机铃声静音

    • RINGER_MODE_VIBRATE: 手机振动

  • setSpeakerphoneOn(boolean on):设置是否打开扩音器


知道了上述方法,还需要知道的一个点是播放媒体的时候请求音频焦点,退出播放后释放音频焦点。

    /**
     * 播放音乐前先请求音频焦点
     *
     * @return
     */
    public boolean requestAudioFocus() {
        return audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_REQUEST_GRANTED) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
    }
    /**
     * 退出播放器后 不再占用音频焦点
     */
    public void abandonAudioFocus() {
        audioManager.abandonAudioFocus(this);
    }

手机上避免不了会有其他媒体播放软件,所以会存在音频抢占的问题。因此在实现AudioManager.OnAudioFocusChangeListener这个接口的时候 需要实现一个必须的方法onAudioFocusChange

在当前拥有音频焦点的情况下,有这么几个场景:

  • 来电话,短暂丢失音频焦点

    需要强制停止当前播放,

  • 来短信,丢失瞬间的音频的焦点

    将当前播放音乐音量减小为一半,等待重新获得音频焦点

  • 通话结束,重新获得音频焦点

    恢复播放

  • 被其他播放器抢占,永久的丢失焦点

    停止播放

实现如下:

public class AudioFocusManager implements AudioManager.OnAudioFocusChangeListener {

    private final Context context;
    private final IPlayControl control;
    private final AudioManager audioManager;

    //    短暂 音频焦点丢失 打电话
    private boolean isPauseByFocusLossTransient;
    //    瞬间 音频焦点丢失 很快就回来 来通知或者短信
    private int mVolumeWhenFocusLossTransientCanDuck;

    public AudioFocusManager(Context context, IPlayControl control) {
        this.context = context;
        this.control = control;
        this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    }

    /**
     * 播放音乐前先请求音频焦点
     *
     * @return
     */
    public boolean requestAudioFocus() {
        return audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_REQUEST_GRANTED) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
    }

    /**
     * 退出播放器后 不再占用音频焦点
     */
    public void abandonAudioFocus() {
        audioManager.abandonAudioFocus(this);
    }

    /**
     * 音频焦点回调监听
     *
     * @param i
     */
    @Override
    public void onAudioFocusChange(int i) {

        int volume;

        switch (i) {
//            重新获得焦点
            case AudioManager.AUDIOFOCUS_GAIN:
                if (!willPlay() && isPauseByFocusLossTransient) {
//                    通话结束,恢复播放
                    play();
                }
                volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
                if (mVolumeWhenFocusLossTransientCanDuck > 0 && volume == mVolumeWhenFocusLossTransientCanDuck / 2) {
//                    恢复音量
                    audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolumeWhenFocusLossTransientCanDuck,
                            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                }
                isPauseByFocusLossTransient = false;
                mVolumeWhenFocusLossTransientCanDuck = 0;
                break;
//                永久丢失焦点,如被其他播放器抢占
            case AudioManager.AUDIOFOCUS_LOSS:
                if (willPlay()) {
                    forceStop();
                }
                break;
//                短暂丢失焦点,如来电话
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                if (willPlay()) {
                    forceStop();
                    isPauseByFocusLossTransient = true;
                }
                break;
//                瞬间丢失焦点,如通知
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
//                音量减小为一半
                volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
                if (willPlay() && volume > 0) {
                    mVolumeWhenFocusLossTransientCanDuck = volume;
                    audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolumeWhenFocusLossTransientCanDuck,
                            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                }
                break;
        }

    }

    private void play() {
        try {
            control.resume();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private void forceStop() {
        try {
            control.pause();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private boolean willPlay() {
        try {
            return control.status() == PlayController.STATUS_PLAYING;
        } catch (RemoteException e) {
            e.printStackTrace();
            return false;
        }
    }
}

参考文章

初学Android,音频管理器之控制音频(六十六)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值