• 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表示什么也没有

    直接自定义调节的幅度(步进值),直接调节音量大小。

    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。

    原文地址:https://www.jianshu.com/p/3005c7b8e7d4

  • 相关阅读:
    Java 引用类型
    Mysql-5.7.14使用常见问题汇总
    CountBoard 是一个基于Tkinter简单的,开源的桌面日程倒计时应用
    HashMap的源码分析
    redis-cluster源码分析
    redis集群方案
    redis集群命令
    redis集群删除master节点
    redis集群添加master节点
    redis集群部署
  • 原文地址:https://www.cnblogs.com/cxeye/p/15243518.html
Copyright © 2020-2023  润新知