天天看點

Android音量控制

0. Thanks To

Android音量控制調節

android 音量控制setVolumeControlStream

android 音量調節以及媒體音量界面

1. 音量調節

我們知道,在平常調節音量的時候,是有一定的調節數值,

也就是,每按一次音量+/-,音量的增加/減小幅度,這個我們稱為:系統的音量步進值。

而,音量還有一定的範圍,系統的是:0到Max,Max不确定,這個稱為:系統的音量範圍。

在Android中,是有幾種類型的音量可以調節:

  • STREAM_ALARM 警報
  • STREAM_MUSIC 音樂回放即媒體音量
  • STREAM_RING 鈴聲
  • STREAM_SYSTEM 系統
  • STREAM_VOICE_CALL 通話

Android中的所有音量都是通過:AudioManager 去管理的,也是通過它去調節:

//擷取系統的Audio管理者
    AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);  
    //最大音量
    int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    //目前音量
    int currentVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
           

而,日常的項目中,有兩種的調節方式:

  • 1.漸進式,即像手動按音量鍵一樣,一步一步增加或減少:

    通過AudioManager的adjustStreamVolume方法

public void adjustStreamVolume (int  streamType, int direction, int flags)
參數說明:

            int streamType  需要調整的音量類型
                (以下常量定義于AudioManager類中)
                STREAM_ALARM 警報
                STREAM_MUSIC 音樂回放即媒體音量
                STREAM_NOTIFICATION 視窗頂部狀态欄Notification,
                STREAM_RING 鈴聲
                STREAM_SYSTEM 系統
                STREAM_VOICE_CALL 通話
                STREAM_DTMF 雙音多頻,不是很明白什麼東西

            int direction   調整的方向,加或者減。
                (以下常量定義于AudioManager類中)
                ADJUST_LOWER 降低音量
                ADJUST_RAISE 升高音量
                ADJUST_SAME 保持不變,這個主要用于向使用者展示目前的音量

            int flags   附加的一些參數
                參數的說明參考API文檔:http://www.android-doc.com/reference/android/media/AudioManager.html

                FLAG_PLAY_SOUND 調整音量時播放聲音
                FLAG_SHOW_UI 調整時顯示音量條,就是按音量鍵出現的那個
                0表示什麼也沒有
           
  • 2.直接自定義調節的幅度(步進值),直接調節音量大小。
public void setStreamVolume (int streamType, int index, int flags)
            參數說明:
                第一個,第三個和上面的一樣

                第二個參數:
                    int index: 把音量調整到index值。

                這裡,可以根據擷取的最大音量去自己設定調整的幅度。
           

2. 音量按鍵的監聽

直接上代碼,需要在Activity中,重寫其按鍵的回調:

@Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        int action = event.getAction();
        if (action ==KeyEvent.ACTION_DOWN) {
            tv.setText("+++++++++ACTION_DOWN++++++"+ count++);
            return true;
        }
        if (action== KeyEvent.ACTION_UP) {
            tv.setText("+++++ACTION_UP++++++++++");
            return true;
        }
        return super.dispatchKeyEvent(event);
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_VOLUME_DOWN:
            tv.setText("-----------------"+count);
            count--;
            return true;
        case KeyEvent.KEYCODE_VOLUME_UP:
            tv.setText("++++++++++++++++"+ count);
            count++;
            return true;
        case KeyEvent.KEYCODE_VOLUME_MUTE:
            tv.setText("MUTE");
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
           

兩個方法選其一就好。

3. UI修改:

我們可以直接在監聽裡面做,讓系統音量UI不彈出,設定好調整音量的兩個方法的FLAG就好,然後自己去控制音量。

這裡我們可以用自定義的Toast布局去弄,或者是基于Dialog的組合控件去曾現這個音量條。

4. 封裝音量控制:

代碼裡面定義了常用的DIY音量調節範圍:0-100,預設音量步進值為2。

package com.chestnut.Common.Helper;

import android.content.Context;
import android.media.AudioManager;
import android.support.annotation.IntDef;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * <pre>
 *     author: Chestnut
 *     blog  : http://www.jianshu.com/u/a0206b5f4526
 *     time  : 2017/6/17 16:11
 *     desc  :  內建音量控制
 *     thanks To:   http://blog.csdn.net/hufeng882412/article/details/7310131
 *     dependent on:
 *     update log:
 * </pre>
 */

public class AudioMngHelper {

    private final String TAG = "AudioMngHelper";
    private final boolean OpenLog = true;

    private AudioManager audioManager;
    private int NOW_AUDIO_TYPE = TYPE_MUSIC;
    private int NOW_FLAG = FLAG_NOTHING;
    private int VOICE_STEP_100 = 2; //0-100的步進。

    /**
     * 封裝:STREAM_類型
     */
    public final static int TYPE_MUSIC = AudioManager.STREAM_MUSIC;
    public final static int TYPE_ALARM = AudioManager.STREAM_ALARM;
    public final static int TYPE_RING = AudioManager.STREAM_RING;
    @IntDef({TYPE_MUSIC, TYPE_ALARM, TYPE_RING})
    @Retention(RetentionPolicy.SOURCE)
    public @interface TYPE {}

    /**
     * 封裝:FLAG
     */
    public final static int FLAG_SHOW_UI = AudioManager.FLAG_SHOW_UI;
    public final static int FLAG_PLAY_SOUND = AudioManager.FLAG_PLAY_SOUND;
    public final static int FLAG_NOTHING = 0;
    @IntDef({FLAG_SHOW_UI, FLAG_PLAY_SOUND, FLAG_NOTHING})
    @Retention(RetentionPolicy.SOURCE)
    public @interface FLAG {}

    /**
     * 初始化,擷取音量管理者
     * @param context   上下文
     */
    public AudioMngHelper(Context context) {
        audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    }

    public int getSystemMaxVolume() {
        return audioManager.getStreamMaxVolume(NOW_AUDIO_TYPE);
    }

    public int getSystemCurrentVolume() {
        return audioManager.getStreamVolume(NOW_AUDIO_TYPE);
    }

    /**
     * 以0-100為範圍,擷取目前的音量值
     * @return  擷取目前的音量值
     */
    public int get100CurrentVolume() {
        return 100*getSystemCurrentVolume()/getSystemMaxVolume();
    }

    /**
     * 修改步進值
     * @param step  step
     * @return  this
     */
    public AudioMngHelper setVoiceStep100(int step) {
        VOICE_STEP_100 = step;
        return this;
    }

    /**
     * 改變目前的模式,對全局API生效
     * @param type
     * @return
     */
    public AudioMngHelper setAudioType(@TYPE int type) {
        NOW_AUDIO_TYPE = type;
        return this;
    }

    /**
     * 改變目前FLAG,對全局API生效
     * @param flag
     * @return
     */
    public AudioMngHelper setFlag(@FLAG int flag) {
        NOW_FLAG = flag;
        return this;
    }

    public AudioMngHelper addVoiceSystem() {
        audioManager.adjustStreamVolume(NOW_AUDIO_TYPE,AudioManager.ADJUST_RAISE,NOW_FLAG);
        return this;
    }

    public AudioMngHelper subVoiceSystem() {
        audioManager.adjustStreamVolume(NOW_AUDIO_TYPE,AudioManager.ADJUST_LOWER,NOW_FLAG);
        return this;
    }

    /**
     * 調整音量,自定義
     * @param num   0-100
     * @return  改完後的音量值
     */
    public int setVoice100(int num) {
        int a = (int) Math.ceil((num)*getSystemMaxVolume()*0.01);
        a = a<=0 ? 0 : a;
        a = a>=100 ? 100 : a;
        audioManager.setStreamVolume(NOW_AUDIO_TYPE,a,0);
        return get100CurrentVolume();
    }

    /**
     * 步進加,步進值可修改
     *  0——100
     * @return  改完後的音量值
     */
    public int addVoice100() {
        int a = (int) Math.ceil((VOICE_STEP_100 + get100CurrentVolume())*getSystemMaxVolume()*0.01);
        a = a<=0 ? 0 : a;
        a = a>=100 ? 100 : a;
        audioManager.setStreamVolume(NOW_AUDIO_TYPE,a,NOW_FLAG);
        return get100CurrentVolume();
    }

    /**
     * 步進減,步進值可修改
     *  0——100
     * @return  改完後的音量值
     */
    public int subVoice100() {
        int a = (int) Math.floor((get100CurrentVolume() - VOICE_STEP_100)*getSystemMaxVolume()*0.01);
        a = a<=0 ? 0 : a;
        a = a>=100 ? 100 : a;
        audioManager.setStreamVolume(NOW_AUDIO_TYPE,a,NOW_FLAG);
        return get100CurrentVolume();
    }
}
           

部分API的說明:

  • 可以設定對哪種類型的音量去調控,通過:AudioMngHelper.setAudioType,通過注解的方式限制了使用者的設定類型,在類的開頭可以看到,預設值是媒體類型。
  • 可以對Flag進行全局的設定,通過:AudioMngHelper.setFlag,設定顯示UI或者聽到調節音效或者啥都沒。
  • get100CurrentVolume():以0-100為範圍,擷取目前的音量值
  • getSystemMaxVolume():擷取系統音量範圍的最大值
  • getSystemCurrentVolume():擷取系統音量範圍的目前值
  • addVoiceSystem():以系統步進值和範圍為基礎,音量+
  • subVoiceSystem():同上,音量-
  • addVoice100():以0-100範圍和自定義的步進值為基礎,音量+
  • subVoice100():同上,音量-
  • setVoiceStep100():設定DIY步進值,預設是2。

5. Demo

這個Demo示例了怎麼使用這個封裝,和示例了怎麼修改音量調UI。

ChestnutPlus/ModuleMedia

代碼在:Moudle-Media-src-java下

通過MainActivity調用VideoActivity,記得修改視訊的URL。

/**
     * 監聽音量實體按鍵
     * @param keyCode
     * @param event
     * @return
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        int a;
        switch (keyCode) {
            case KeyEvent.KEYCODE_VOLUME_DOWN:
                xToastMusic.setVoice(audioMngHelper.subVoice100()).show();
                return true;
            case KeyEvent.KEYCODE_VOLUME_UP:
                xToastMusic.setVoice(audioMngHelper.addVoice100()).show();
                return true;
            case KeyEvent.KEYCODE_VOLUME_MUTE:
                break;
        }
        return super.onKeyDown(keyCode, event);
    }