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.lxweimin.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);
    }

點個贊咯~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,406評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,034評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,413評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,449評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,165評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,559評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,606評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,781評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,327評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,084評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,278評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,849評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,495評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,927評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,172評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,010評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,241評論 2 375

推薦閱讀更多精彩內容