Android音量控制

0. Thanks To

Android音量控制調(diào)節(jié)
android 音量控制setVolumeControlStream
android 音量調(diào)節(jié)以及媒體音量界面

1. 音量調(diào)節(jié)

我們知道遥诉,在平常調(diào)節(jié)音量的時(shí)候橡淑,是有一定的調(diào)節(jié)數(shù)值亏吝,
也就是炉抒,每按一次音量+/-,音量的增加/減小幅度世舰,這個(gè)我們稱為:系統(tǒng)的音量步進(jìn)值动雹。
而,音量還有一定的范圍跟压,系統(tǒng)的是:0到Max胰蝠,Max不確定,這個(gè)稱為:系統(tǒng)的音量范圍震蒋。

在Android中茸塞,是有幾種類(lèi)型的音量可以調(diào)節(jié):

  • STREAM_ALARM 警報(bào)
  • STREAM_MUSIC 音樂(lè)回放即媒體音量
  • STREAM_RING 鈴聲
  • STREAM_SYSTEM 系統(tǒng)
  • STREAM_VOICE_CALL 通話

Android中的所有音量都是通過(guò):AudioManager 去管理的,也是通過(guò)它去調(diào)節(jié):

    //獲取系統(tǒng)的Audio管理者
    AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);  
    //最大音量
    int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    //當(dāng)前音量
    int currentVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

而查剖,日常的項(xiàng)目中钾虐,有兩種的調(diào)節(jié)方式:

  • 1.漸進(jìn)式,即像手動(dòng)按音量鍵一樣,一步一步增加或減少:
    通過(guò)AudioManager的adjustStreamVolume方法
public void adjustStreamVolume (int  streamType, int direction, int flags)
參數(shù)說(shuō)明:

            int streamType  需要調(diào)整的音量類(lèi)型
                (以下常量定義于AudioManager類(lèi)中)
                STREAM_ALARM 警報(bào)
                STREAM_MUSIC 音樂(lè)回放即媒體音量
                STREAM_NOTIFICATION 窗口頂部狀態(tài)欄Notification,
                STREAM_RING 鈴聲
                STREAM_SYSTEM 系統(tǒng)
                STREAM_VOICE_CALL 通話
                STREAM_DTMF 雙音多頻,不是很明白什么東西

            int direction   調(diào)整的方向,加或者減梗搅。
                (以下常量定義于AudioManager類(lèi)中)
                ADJUST_LOWER 降低音量
                ADJUST_RAISE 升高音量
                ADJUST_SAME 保持不變,這個(gè)主要用于向用戶展示當(dāng)前的音量

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

                FLAG_PLAY_SOUND 調(diào)整音量時(shí)播放聲音
                FLAG_SHOW_UI 調(diào)整時(shí)顯示音量條,就是按音量鍵出現(xiàn)的那個(gè)
                0表示什么也沒(méi)有
  • 2.直接自定義調(diào)節(jié)的幅度(步進(jìn)值)禾唁,直接調(diào)節(jié)音量大小。
public void setStreamVolume (int streamType, int index, int flags)
            參數(shù)說(shuō)明:
                第一個(gè)无切,第三個(gè)和上面的一樣

                第二個(gè)參數(shù):
                    int index: 把音量調(diào)整到index值。

                這里丐枉,可以根據(jù)獲取的最大音量去自己設(shè)置調(diào)整的幅度哆键。

2. 音量按鍵的監(jiān)聽(tīng)

直接上代碼,需要在Activity中瘦锹,重寫(xiě)其按鍵的回調(diào):

    @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);
    }

兩個(gè)方法選其一就好籍嘹。

3. UI修改:

我們可以直接在監(jiān)聽(tīng)里面做闪盔,讓系統(tǒng)音量UI不彈出,設(shè)置好調(diào)整音量的兩個(gè)方法的FLAG就好辱士,然后自己去控制音量泪掀。
這里我們可以用自定義的Toast布局去弄,或者是基于Dialog的組合控件去曾現(xiàn)這個(gè)音量條颂碘。

4. 封裝音量控制:

代碼里面定義了常用的DIY音量調(diào)節(jié)范圍:0-100异赫,默認(rèn)音量步進(jìn)值為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.reibang.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的步進(jìn)头岔。

    /**
     * 封裝:STREAM_類(lèi)型
     */
    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為范圍,獲取當(dāng)前的音量值
     * @return  獲取當(dāng)前的音量值
     */
    public int get100CurrentVolume() {
        return 100*getSystemCurrentVolume()/getSystemMaxVolume();
    }

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

    /**
     * 改變當(dāng)前的模式峡竣,對(duì)全局API生效
     * @param type
     * @return
     */
    public AudioMngHelper setAudioType(@TYPE int type) {
        NOW_AUDIO_TYPE = type;
        return this;
    }

    /**
     * 改變當(dāng)前FLAG靠抑,對(duì)全局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;
    }

    /**
     * 調(diào)整音量,自定義
     * @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();
    }

    /**
     * 步進(jìn)加适掰,步進(jìn)值可修改
     *  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();
    }

    /**
     * 步進(jìn)減颂碧,步進(jìn)值可修改
     *  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的說(shuō)明:

  • 可以設(shè)置對(duì)哪種類(lèi)型的音量去調(diào)控,通過(guò):AudioMngHelper.setAudioType类浪,通過(guò)注解的方式限制了用戶的設(shè)置類(lèi)型载城,在類(lèi)的開(kāi)頭可以看到,默認(rèn)值是媒體類(lèi)型戚宦。

  • 可以對(duì)Flag進(jìn)行全局的設(shè)置个曙,通過(guò):AudioMngHelper.setFlag,設(shè)置顯示UI或者聽(tīng)到調(diào)節(jié)音效或者啥都沒(méi)受楼。

  • get100CurrentVolume():以0-100為范圍垦搬,獲取當(dāng)前的音量值

  • getSystemMaxVolume():獲取系統(tǒng)音量范圍的最大值

  • getSystemCurrentVolume():獲取系統(tǒng)音量范圍的當(dāng)前值

  • addVoiceSystem():以系統(tǒng)步進(jìn)值和范圍為基礎(chǔ),音量+

  • subVoiceSystem():同上艳汽,音量-

  • addVoice100():以0-100范圍和自定義的步進(jìn)值為基礎(chǔ)猴贰,音量+

  • subVoice100():同上,音量-

  • setVoiceStep100():設(shè)置DIY步進(jìn)值河狐,默認(rèn)是2米绕。

5. Demo

這個(gè)Demo示例了怎么使用這個(gè)封裝,和示例了怎么修改音量調(diào)UI馋艺。
ChestnutPlus/ModuleMedia
代碼在:Moudle-Media-src-java下
通過(guò)MainActivity調(diào)用VideoActivity,記得修改視頻的URL栅干。

 /**
     * 監(jiān)聽(tīng)音量實(shí)體按鍵
     * @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);
    }

點(diǎn)個(gè)贊咯~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市捐祠,隨后出現(xiàn)的幾起案子碱鳞,更是在濱河造成了極大的恐慌,老刑警劉巖踱蛀,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窿给,死亡現(xiàn)場(chǎng)離奇詭異贵白,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)坷备,“玉大人缰儿,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)磷蜀。 經(jīng)常有香客問(wèn)我,道長(zhǎng)百炬,這世上最難降的妖魔是什么褐隆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮剖踊,結(jié)果婚禮上庶弃,老公的妹妹穿的比我還像新娘。我一直安慰自己德澈,他們只是感情好歇攻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著梆造,像睡著了一般缴守。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上镇辉,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天屡穗,我揣著相機(jī)與錄音,去河邊找鬼忽肛。 笑死村砂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的屹逛。 我是一名探鬼主播础废,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼罕模!你這毒婦竟也來(lái)了评腺?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤淑掌,失蹤者是張志新(化名)和其女友劉穎歇僧,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體锋拖,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诈悍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兽埃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侥钳。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖柄错,靈堂內(nèi)的尸體忽然破棺而出舷夺,到底是詐尸還是另有隱情,我是刑警寧澤售貌,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布给猾,位于F島的核電站,受9級(jí)特大地震影響颂跨,放射性物質(zhì)發(fā)生泄漏敢伸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一恒削、第九天 我趴在偏房一處隱蔽的房頂上張望池颈。 院中可真熱鬧,春花似錦钓丰、人聲如沸躯砰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)琢歇。三九已至,卻和暖如春梦鉴,著一層夾襖步出監(jiān)牢的瞬間李茫,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工尚揣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涌矢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓快骗,卻偏偏與公主長(zhǎng)得像娜庇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子方篮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容