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