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;/** * 
 *     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: * 
*/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);    }

点个赞咯~

更多相关文章

  1. App Widget ————android 新一代移动操作系统的特征
  2. Android(安卓)文件系统获取root权限
  3. Android(安卓)Power Management
  4. 隐藏Android(安卓)系统自带的v7.widget.Toolbar的标题
  5. android系统工具之 draw9patch超详细教程
  6. Google 手机操作系统 Android(安卓)开发教程 转载
  7. Android应用程序如何进行系统签名
  8. Android(安卓)Activity 详解
  9. Android(安卓)初始化Setup Wizard——Provision

随机推荐

  1. 图解源码 | SpringBoot中自动配置原理
  2. 单例模式你会几种写法?
  3. 一步为你的Springboot应用自定义banner
  4. 工厂模式理解了没有?
  5. 你的Springboot应用到底启动了哪些bean?这
  6. 单例模式的十种写法,你会几个?
  7. 我在一个构造方法中写了30个参数,老板看了
  8. android:windowSoftInputMode属性详解以
  9. 一个GCRoot不可达的对象,会立刻被垃圾回收
  10. 压缩两个集合,方法原来这么多(实用技巧)