音频焦点的基本用法

来源:互联网 发布:淘宝店铺刷信誉 编辑:程序博客网 时间:2024/06/08 20:40

请求焦点:

/**     *  Request audio focus.     *  Send a request to obtain the audio focus     *  @param l the listener to be notified of audio focus changes     *  @param streamType the main audio stream type affected by the focus request     *  @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request     *      is temporary, and focus will be abandonned shortly. Examples of transient requests are     *      for the playback of driving directions, or notifications sounds.     *      Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for     *      the previous focus owner to keep playing if it ducks its audio output.     *      Alternatively use {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} for a temporary request     *      that benefits from the system not playing disruptive sounds like notifications, for     *      usecases such as voice memo recording, or speech recognition.     *      Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such     *      as the playback of a song or a video.     *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}     */    public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)
下面几个参数都是和onAudioFocusChange(int focusChange)中的focusChange参数对应的

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;



下面是其他博客的解释,但是我觉得是错误的,AUDIOFOCUS_LOSS不是失去很长时间,而是在request的时候参数是AUDIOFOCUS_GAIN,而AUDIOFOCUS_LOSS的解释是

失去焦点的时间未知,可能会长时间失去焦点。

focusChange参数告你音频焦点时如何改变的,并且能够是下面的值之一(它们是所有的在AudioManager类中定义的常量):

    AUDIOFOCUS_GAIN:你已经获得音频焦点;
    AUDIOFOCUS_LOSS:你已经失去音频焦点很长时间了,必须终止所有的音频播放。因为长时间的失去焦点后,不应该在期望有焦点返回,这是一个尽可能清除不用资源的好位置。例如,应该在此时释放MediaPlayer对象;
    AUDIOFOCUS_LOSS_TRANSIENT:这说明你临时失去了音频焦点,但是在不久就会再返回来。此时,你必须终止所有的音频播放,但是保留你的播放资源,因为可能不久就会返回来。
    AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:这说明你已经临时失去了音频焦点,但允许你安静的播放音频(低音量),而不是完全的终止音频播放。目前所有的情况下,oFocusChange的时候停止mediaPlayer */

源码:

/**     * @hide     * Used to indicate no audio focus has been gained or lost.     */    public static final int AUDIOFOCUS_NONE = 0;    /**     * Used to indicate a gain of audio focus, or a request of audio focus, of unknown duration.     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)     */    public static final int AUDIOFOCUS_GAIN = 1;    /**     * Used to indicate a temporary gain or request of audio focus, anticipated to last a short     * amount of time. Examples of temporary changes are the playback of driving directions, or an     * event notification.     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)     */    public static final int AUDIOFOCUS_GAIN_TRANSIENT = 2;    /**     * Used to indicate a temporary request of audio focus, anticipated to last a short     * amount of time, and where it is acceptable for other audio applications to keep playing     * after having lowered their output level (also referred to as "ducking").     * Examples of temporary changes are the playback of driving directions where playback of music     * in the background is acceptable.     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)     */    public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK = 3;    /**     * Used to indicate a temporary request of audio focus, anticipated to last a short     * amount of time, during which no other applications, or system components, should play     * anything. Examples of exclusive and transient audio focus requests are voice     * memo recording and speech recognition, during which the system shouldn't play any     * notifications, and media playback should have paused.     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)     */    public static final int AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE = 4;    /**     * Used to indicate a loss of audio focus of unknown duration.     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)     */    public static final int AUDIOFOCUS_LOSS = -1 * AUDIOFOCUS_GAIN;    /**     * Used to indicate a transient loss of audio focus.     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)     */    public static final int AUDIOFOCUS_LOSS_TRANSIENT = -1 * AUDIOFOCUS_GAIN_TRANSIENT;    /**     * Used to indicate a transient loss of audio focus where the loser of the audio focus can     * lower its output volume if it wants to continue playing (also referred to as "ducking"), as     * the new focus owner doesn't require others to be silent.     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)     */    public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK =            -1 * AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;

streamType:

 /** The audio stream for phone calls */    public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL;    /** The audio stream for system sounds */    public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM;    /** The audio stream for the phone ring */    public static final int STREAM_RING = AudioSystem.STREAM_RING;    /** The audio stream for music playback */    public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC;    /** The audio stream for alarms */    public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM;    /** The audio stream for notifications */    public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION;    /** @hide The audio stream for phone calls when connected to bluetooth */    public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO;    /** @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */    public static final int STREAM_SYSTEM_ENFORCED = AudioSystem.STREAM_SYSTEM_ENFORCED;    /** The audio stream for DTMF Tones */    public static final int STREAM_DTMF = AudioSystem.STREAM_DTMF;    /** @hide The audio stream for text to speech (TTS) */    public static final int STREAM_TTS = AudioSystem.STREAM_TTS;
应该是不同的流优先等都不一样,从上到下应该由高到低。

通话时,用音乐流requestAudioFocus会失败,返回AUDIOFOCUS_REQUEST_FAILED。



释放焦点:

/**     *  Abandon audio focus. Causes the previous focus owner, if any, to receive focus.     *  @param l the listener with which focus was requested.     *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}     */    public int abandonAudioFocus(OnAudioFocusChangeListener l) {        return abandonAudioFocus(l, null /*AudioAttributes, legacy behavior*/);    }
如果调用该方法时有焦点的话,就会让前一个拥有焦点的人得到焦点,至于它的返回值就不知道是什么意思了。



焦点使用总结:

1.请求焦点,关键是知道request方法中的各个参数含义,处理请求成功和失败。

2.在请求时传入监听器,在监听器中处理loss和gain的逻辑。

3.在不需要焦点的时候释放焦点。





通话、来电、去电时的音乐焦点处理:

因为有些手机在通话过程中,按加减键静音时,会释放焦点,但此时还是通话过程,音乐会获得焦点,但是不能播放。就需要同时监听通话状态。

直接贴代码:

焦点获得和通话空闲状态同步

public boolean mHasAudioFocusWhenCall = false;    private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() {            public void onAudioFocusChange(int focusChange) {            // AudioFocus is a new feature: focus updates are made verbose on            // purpose            // delay 1.8 second to avoid noises after call.            int delay = 0;            if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {             //Gionee <zhangjinbiao> <2017-1-22> modify for <60901> begin                TelephonyManager tm =   (TelephonyManager)MediaPlaybackService.this.getSystemService(Service.TELEPHONY_SERVICE);                if(tm != null && tm.getCallState() != TelephonyManager.CALL_STATE_IDLE){                mHasAudioFocusWhenCall = true;                return;                }              //Gionee <zhangjinbiao> <2017-1-22> modify for <60901> begin                // delay = 1800;                mLossOfFocusDuringGainDelay = false;            }            mMediaplayerHandler.sendMessageDelayed(                    mMediaplayerHandler.obtainMessage(FOCUSCHANGE, focusChange, 0), delay);        }    };
通话空闲和焦点获得同步

    private BroadcastReceiver mPhoneStateReceiver = new BroadcastReceiver() {          @Override      public void onReceive(Context context, Intent intent) {                      TelephonyManager tm =                           (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);                                                LogUtil.d(TAG, "phone state: " + tm.getCallState());                       if(mLossOfFocusDuringGainDelay == true && mHasAudioFocusWhenCall){                               int delay = 0;                               mLossOfFocusDuringGainDelay = false;                               mMediaplayerHandler.sendMessageDelayed(                                       mMediaplayerHandler.obtainMessage(FOCUSCHANGE, AudioManager.AUDIOFOCUS_GAIN, 0), delay);                       }                       mHasAudioFocusWhenCall = false;                       break;                    }       }  } ;



其他关于音频焦点使用的博客:

http://www.jianshu.com/p/ab807638225c

https://yrom.net/blog/2013/11/08/audio-focus/





0 0
原创粉丝点击