当前位置:   article > 正文

Android App开发音量调节中实现拖动条和滑动条和音频管理器AudioManager讲解及实战(超详细 附源码和演示视频)_taudiomanager

taudiomanager

需要源码请点赞关注收藏后评论区留下QQ~~~

一、拖动条和滑动条

拖动条SeekBar继承自进度条ProgressBar,它与进度条的不同之处在于,进度条只能在代码中修改进度值,不能由用户改变进度值,拖动条不仅可以在代码中修改进度值,还可以由用户拖动操作改变进度值,在播放音频和视频时,用户通过拖动条控制播放器快进或快退到指定位置,然后从新位置开始播放,除此之外,拖动条还可以调节音量大小,屏幕亮度,字体大小等

尽管拖动条在多数情况下够用了,但它有一个毛病,拖动之后用户不能直观的看到当前进度值是多少,为此Android设计了全新的滑动条空间Slider,首先要增加以下配置

implementaion 'com.google.android.materia:material:1.4.0'

运行效果如下 可以手动点击控制音量

 代码如下

Java类

  1. package com.example.audio;
  2. import android.os.Bundle;
  3. import android.widget.SeekBar;
  4. import android.widget.Toast;
  5. import androidx.appcompat.app.AppCompatActivity;
  6. import com.google.android.material.slider.Slider;
  7. public class SliderActivity extends AppCompatActivity {
  8. @Override
  9. protected void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.activity_slider);
  12. SeekBar sb_progress = findViewById(R.id.sb_progress);
  13. sb_progress.setOnSeekBarChangeListener(mSeekListener); // 设置拖动条的拖动监听器
  14. Slider sl_progress = findViewById(R.id.sl_progress);
  15. sl_progress.addOnSliderTouchListener(mSliderListener); // 设置滑动条的触摸监听器
  16. }
  17. private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() {
  18. // 在进度变更时触发。第三个参数为true表示用户拖动,为false表示代码设置进度
  19. @Override
  20. public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}
  21. // 在开始拖动进度时触发
  22. @Override
  23. public void onStartTrackingTouch(SeekBar seekBar) {}
  24. // 在停止拖动进度时触发
  25. @Override
  26. public void onStopTrackingTouch(SeekBar seekBar) {
  27. Toast.makeText(SliderActivity.this, "您选择的进度是"+seekBar.getProgress(),
  28. Toast.LENGTH_SHORT).show();
  29. }
  30. };
  31. private Slider.OnSliderTouchListener mSliderListener = new Slider.OnSliderTouchListener() {
  32. // 在开始滑动进度时触发
  33. @Override
  34. public void onStartTrackingTouch(Slider slider) {}
  35. // 在停止滑动进度时触发
  36. @Override
  37. public void onStopTrackingTouch(Slider slider) {
  38. Toast.makeText(SliderActivity.this, "您选择的进度是"+slider.getValue(),
  39. Toast.LENGTH_SHORT).show();
  40. }
  41. };
  42. }

 XML文件

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:orientation="vertical" >
  5. <TextView
  6. android:layout_width="match_parent"
  7. android:layout_height="wrap_content"
  8. android:layout_marginTop="5dp"
  9. android:gravity="center"
  10. android:text="下面是拖动条"
  11. android:textColor="@color/black"
  12. android:textSize="17sp" />
  13. <SeekBar
  14. android:id="@+id/sb_progress"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:layout_marginTop="5dp"
  18. android:max="100"
  19. android:progress="50"
  20. android:thumb="@drawable/seekbar_point" />
  21. <TextView
  22. android:layout_width="match_parent"
  23. android:layout_height="wrap_content"
  24. android:layout_margin="5dp"
  25. android:gravity="center"
  26. android:text="下面是来自MaterialDesign库的滑动条"
  27. android:textColor="@color/black"
  28. android:textSize="17sp" />
  29. <com.google.android.material.slider.Slider
  30. android:id="@+id/sl_progress"
  31. android:layout_width="match_parent"
  32. android:layout_height="wrap_content"
  33. android:stepSize="1"
  34. android:valueFrom="0"
  35. android:valueTo="100"
  36. android:value="0" />
  37. </LinearLayout>

二、音频管理器

Android只有一个麦克风,却管理着6种铃声,分别是通话音,系统音,铃音,闹钟音,通知音等

管理这些铃声音量的工具是音频管理器AudioManager 下面是它的常用方法

getStreamMaxVolume 获取指定类型铃声的最大音量

getStreamVolume 获取指定类型铃声的当前音量

getRingerMode 获取指定类型铃声的响铃模式

音量调整效果如下 这个设置页面不但允许通过拖动条将音量直接调整到目标值,还允许通过加减按钮逐级调大或者调小音量

可以拖动条也可以点击按钮来调节

 

 代码如下

Java类

  1. package com.example.audio;
  2. import android.content.Context;
  3. import android.media.AudioManager;
  4. import android.os.Bundle;
  5. import android.util.Log;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.widget.ImageView;
  9. import android.widget.SeekBar;
  10. import android.widget.SeekBar.OnSeekBarChangeListener;
  11. import androidx.appcompat.app.AppCompatActivity;
  12. public class AudioManagerActivity extends AppCompatActivity implements OnSeekBarChangeListener, OnClickListener {
  13. private static final String TAG = "VolumeManagerActivity";
  14. private SeekBar sb_voice, sb_system, sb_ring, sb_music, sb_alarm, sb_notify;
  15. private ImageView iv_volumn_up, iv_system_up, iv_ring_up, iv_music_up, iv_alarm_up, iv_notify_up;
  16. private ImageView iv_volumn_down, iv_system_down, iv_ring_down, iv_music_down, iv_alarm_down, iv_notify_down;
  17. private int[] mStreamType = { // 音频流类型数组
  18. AudioManager.STREAM_VOICE_CALL, AudioManager.STREAM_SYSTEM,
  19. AudioManager.STREAM_RING, AudioManager.STREAM_MUSIC,
  20. AudioManager.STREAM_ALARM, AudioManager.STREAM_NOTIFICATION};
  21. private int[] mMaxVolume = {0, 0, 0, 0, 0, 0}; // 最大音量数组
  22. private int[] mNowVolume = {0, 0, 0, 0, 0, 0}; // 当前音量数组
  23. private SeekBar[] mSeekBar = { // 拖动条的控件数组
  24. sb_voice, sb_system, sb_ring,
  25. sb_music, sb_alarm, sb_notify};
  26. private int[] mStreamRes = { // 拖动条的资源编号数组
  27. R.id.sb_voice, R.id.sb_system, R.id.sb_ring,
  28. R.id.sb_music, R.id.sb_alarm, R.id.sb_notify};
  29. private ImageView[] mAddView = { // 增大音量按钮的控件数组
  30. iv_volumn_up, iv_system_up, iv_ring_up,
  31. iv_music_up, iv_alarm_up, iv_notify_up};
  32. private int[] mAddRes = { // 增大音量按钮的资源编号数组
  33. R.id.iv_volumn_up, R.id.iv_system_up, R.id.iv_ring_up,
  34. R.id.iv_music_up, R.id.iv_alarm_up, R.id.iv_notify_up};
  35. private ImageView[] mDelView = { // 减小音量按钮的控件数组
  36. iv_volumn_down, iv_system_down, iv_ring_down,
  37. iv_music_down, iv_alarm_down, iv_notify_down};
  38. private int[] mDelRes = { // 减小音量按钮的资源编号数组
  39. R.id.iv_volumn_down, R.id.iv_system_down, R.id.iv_ring_down,
  40. R.id.iv_music_down, R.id.iv_alarm_down, R.id.iv_notify_down};
  41. private int SEEK_BAR = 1, ADD_VIEW = 2, DEL_VIEW = 3;
  42. private AudioManager mAudioMgr; // 声明一个音频管理器对象
  43. @Override
  44. protected void onCreate(Bundle savedInstanceState) {
  45. super.onCreate(savedInstanceState);
  46. setContentView(R.layout.activity_audio_manager);
  47. // 从布局文件中依次获取各音量类型的拖动条、增大音量按钮、减小音量按钮
  48. for (int i = 0; i < mStreamType.length; i++) {
  49. mSeekBar[i] = findViewById(mStreamRes[i]);
  50. mAddView[i] = findViewById(mAddRes[i]);
  51. mDelView[i] = findViewById(mDelRes[i]);
  52. }
  53. setStreamVolume(); // 设置各音量类型的拖动条进度
  54. for (int i = 0; i < mStreamType.length; i++) {
  55. // 给各音量类型的拖动条设置拖动变更监听器
  56. mSeekBar[i].setOnSeekBarChangeListener(this);
  57. // 给各音量类型的增大音量按钮设置点击监听器
  58. mAddView[i].setOnClickListener(this);
  59. // 给各音量类型的减小音量按钮设置点击监听器
  60. mDelView[i].setOnClickListener(this);
  61. }
  62. }
  63. // 设置各音量类型的拖动条进度
  64. void setStreamVolume() {
  65. // 从系统服务中获取音频管理器
  66. mAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
  67. for (int i = 0; i < mStreamType.length; i++) {
  68. int type = mStreamType[i];
  69. // 获取指定音频类型的最大音量
  70. mMaxVolume[i] = mAudioMgr.getStreamMaxVolume(type);
  71. // 获取指定音频类型的当前音量
  72. mNowVolume[i] = mAudioMgr.getStreamVolume(type);
  73. // 设置拖动条的音量大小进度
  74. mSeekBar[i].setProgress(mSeekBar[i].getMax() * mNowVolume[i] / mMaxVolume[i]);
  75. }
  76. }
  77. // 在进度变更时触发。第三个参数为true表示用户拖动,为false表示代码设置进度
  78. @Override
  79. public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}
  80. // 在开始拖动进度时触发
  81. @Override
  82. public void onStartTrackingTouch(SeekBar seekBar) {}
  83. // 在停止拖动进度时触发
  84. @Override
  85. public void onStopTrackingTouch(SeekBar seekBar) {
  86. Log.d(TAG, "当前进度为:" + seekBar.getProgress() + ", 最大进度为" + seekBar.getMax());
  87. int index = getArrayIndex(seekBar.getId(), SEEK_BAR);
  88. int type = mStreamType[index];
  89. int volume = mMaxVolume[index] * seekBar.getProgress() / seekBar.getMax();
  90. Log.d(TAG, "volume=" + volume + ", last volume=" + mNowVolume[index] + ", max volume=" + mMaxVolume[index]);
  91. if (volume != mNowVolume[index]) {
  92. mNowVolume[index] = volume;
  93. // 根据拖动位置,计算并设置拖动条的当前进度
  94. seekBar.setProgress(seekBar.getMax() * mNowVolume[index] / mMaxVolume[index]);
  95. }
  96. // 设置该音频类型的当前音量
  97. mAudioMgr.setStreamVolume(type, volume, AudioManager.FLAG_PLAY_SOUND);
  98. }
  99. @Override
  100. public void onClick(View v) {
  101. int add_index = getArrayIndex(v.getId(), ADD_VIEW);
  102. int del_index = getArrayIndex(v.getId(), DEL_VIEW);
  103. if (add_index != -1) { // 点击了增大音量按钮
  104. SeekBar seekBar = mSeekBar[add_index];
  105. if (mNowVolume[add_index] < mMaxVolume[add_index]) {
  106. mNowVolume[add_index] = mNowVolume[add_index] + 1;
  107. // 设置拖动条的音量大小进度
  108. seekBar.setProgress(seekBar.getMax() * mNowVolume[add_index] / mMaxVolume[add_index]);
  109. // 把该音频类型的当前音量调大一级
  110. mAudioMgr.adjustStreamVolume(mStreamType[add_index], AudioManager.ADJUST_RAISE, AudioManager.FLAG_PLAY_SOUND);
  111. }
  112. } else if (del_index != -1) { // 点击了减小音量按钮
  113. SeekBar seekBar = mSeekBar[del_index];
  114. if (mNowVolume[del_index] > 0) {
  115. mNowVolume[del_index] = mNowVolume[del_index] - 1;
  116. // 设置拖动条的音量大小进度
  117. seekBar.setProgress(seekBar.getMax() * mNowVolume[del_index] / mMaxVolume[del_index]);
  118. // 把该音频类型的当前音量调小一级
  119. mAudioMgr.adjustStreamVolume(mStreamType[del_index], AudioManager.ADJUST_LOWER, AudioManager.FLAG_PLAY_SOUND);
  120. }
  121. }
  122. }
  123. // 根据资源编号与类型寻找它在对应数组中的位置
  124. private int getArrayIndex(int resid, int type) {
  125. int index = -1;
  126. if (type == SEEK_BAR) { // 这是拖动条
  127. for (int i = 0; i < mSeekBar.length; i++) {
  128. if (mSeekBar[i].getId() == resid) {
  129. index = i;
  130. break;
  131. }
  132. }
  133. } else if (type == ADD_VIEW) { // 这是增大音量按钮
  134. for (int i = 0; i < mAddView.length; i++) {
  135. if (mAddView[i].getId() == resid) {
  136. index = i;
  137. break;
  138. }
  139. }
  140. } else if (type == DEL_VIEW) { // 这是减小音量按钮
  141. for (int i = 0; i < mDelView.length; i++) {
  142. if (mDelView[i].getId() == resid) {
  143. index = i;
  144. break;
  145. }
  146. }
  147. }
  148. return index;
  149. }
  150. }

XML文件

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:orientation="vertical" >
  5. <ScrollView
  6. android:layout_width="match_parent"
  7. android:layout_height="wrap_content" >
  8. <LinearLayout
  9. android:layout_width="match_parent"
  10. android:layout_height="wrap_content"
  11. android:orientation="vertical" >
  12. <LinearLayout
  13. android:layout_width="match_parent"
  14. android:layout_height="wrap_content"
  15. android:layout_marginTop="10dp"
  16. android:orientation="horizontal" >
  17. <TextView
  18. android:layout_width="0dp"
  19. android:layout_height="match_parent"
  20. android:layout_weight="1"
  21. android:gravity="bottom|center_horizontal"
  22. android:text="调节通话音量"
  23. android:textColor="#000000"
  24. android:textSize="17sp" />
  25. <ImageView
  26. android:id="@+id/iv_volumn_down"
  27. android:layout_width="wrap_content"
  28. android:layout_height="wrap_content"
  29. android:layout_marginRight="30dp"
  30. android:src="@drawable/volumn_down" />
  31. <ImageView
  32. android:id="@+id/iv_volumn_up"
  33. android:layout_width="wrap_content"
  34. android:layout_height="wrap_content"
  35. android:layout_marginRight="50dp"
  36. android:src="@drawable/volumn_up" />
  37. </LinearLayout>
  38. <SeekBar
  39. android:id="@+id/sb_voice"
  40. android:layout_width="match_parent"
  41. android:layout_height="wrap_content"
  42. android:layout_marginTop="5dp"
  43. android:thumb="@drawable/seekbar_point" />
  44. <LinearLayout
  45. android:layout_width="match_parent"
  46. android:layout_height="wrap_content"
  47. android:layout_marginTop="10dp"
  48. android:orientation="horizontal" >
  49. <TextView
  50. android:layout_width="0dp"
  51. android:layout_height="match_parent"
  52. android:layout_weight="1"
  53. android:gravity="bottom|center_horizontal"
  54. android:text="调节系统音量"
  55. android:textColor="#000000"
  56. android:textSize="17sp" />
  57. <ImageView
  58. android:id="@+id/iv_system_down"
  59. android:layout_width="wrap_content"
  60. android:layout_height="wrap_content"
  61. android:layout_marginRight="30dp"
  62. android:src="@drawable/volumn_down" />
  63. <ImageView
  64. android:id="@+id/iv_system_up"
  65. android:layout_width="wrap_content"
  66. android:layout_height="wrap_content"
  67. android:layout_marginRight="50dp"
  68. android:src="@drawable/volumn_up" />
  69. </LinearLayout>
  70. <SeekBar
  71. android:id="@+id/sb_system"
  72. android:layout_width="match_parent"
  73. android:layout_height="wrap_content"
  74. android:layout_marginTop="5dp"
  75. android:thumb="@drawable/seekbar_point" />
  76. <LinearLayout
  77. android:layout_width="match_parent"
  78. android:layout_height="wrap_content"
  79. android:layout_marginTop="10dp"
  80. android:orientation="horizontal" >
  81. <TextView
  82. android:layout_width="0dp"
  83. android:layout_height="match_parent"
  84. android:layout_weight="1"
  85. android:gravity="bottom|center_horizontal"
  86. android:text="调节铃声音量"
  87. android:textColor="#000000"
  88. android:textSize="17sp" />
  89. <ImageView
  90. android:id="@+id/iv_ring_down"
  91. android:layout_width="wrap_content"
  92. android:layout_height="wrap_content"
  93. android:layout_marginRight="30dp"
  94. android:src="@drawable/volumn_down" />
  95. <ImageView
  96. android:id="@+id/iv_ring_up"
  97. android:layout_width="wrap_content"
  98. android:layout_height="wrap_content"
  99. android:layout_marginRight="50dp"
  100. android:src="@drawable/volumn_up" />
  101. </LinearLayout>
  102. <SeekBar
  103. android:id="@+id/sb_ring"
  104. android:layout_width="match_parent"
  105. android:layout_height="wrap_content"
  106. android:layout_marginTop="5dp"
  107. android:thumb="@drawable/seekbar_point" />
  108. <LinearLayout
  109. android:layout_width="match_parent"
  110. android:layout_height="wrap_content"
  111. android:layout_marginTop="10dp"
  112. android:orientation="horizontal" >
  113. <TextView
  114. android:layout_width="0dp"
  115. android:layout_height="match_parent"
  116. android:layout_weight="1"
  117. android:gravity="bottom|center_horizontal"
  118. android:text="调节音乐音量"
  119. android:textColor="#000000"
  120. android:textSize="17sp" />
  121. <ImageView
  122. android:id="@+id/iv_music_down"
  123. android:layout_width="wrap_content"
  124. android:layout_height="wrap_content"
  125. android:layout_marginRight="30dp"
  126. android:src="@drawable/volumn_down" />
  127. <ImageView
  128. android:id="@+id/iv_music_up"
  129. android:layout_width="wrap_content"
  130. android:layout_height="wrap_content"
  131. android:layout_marginRight="50dp"
  132. android:src="@drawable/volumn_up" />
  133. </LinearLayout>
  134. <SeekBar
  135. android:id="@+id/sb_music"
  136. android:layout_width="match_parent"
  137. android:layout_height="wrap_content"
  138. android:layout_marginTop="5dp"
  139. android:thumb="@drawable/seekbar_point" />
  140. <LinearLayout
  141. android:layout_width="match_parent"
  142. android:layout_height="wrap_content"
  143. android:layout_marginTop="10dp"
  144. android:orientation="horizontal" >
  145. <TextView
  146. android:layout_width="0dp"
  147. android:layout_height="match_parent"
  148. android:layout_weight="1"
  149. android:gravity="bottom|center_horizontal"
  150. android:text="调节闹钟音量"
  151. android:textColor="#000000"
  152. android:textSize="17sp" />
  153. <ImageView
  154. android:id="@+id/iv_alarm_down"
  155. android:layout_width="wrap_content"
  156. android:layout_height="wrap_content"
  157. android:layout_marginRight="30dp"
  158. android:src="@drawable/volumn_down" />
  159. <ImageView
  160. android:id="@+id/iv_alarm_up"
  161. android:layout_width="wrap_content"
  162. android:layout_height="wrap_content"
  163. android:layout_marginRight="50dp"
  164. android:src="@drawable/volumn_up" />
  165. </LinearLayout>
  166. <SeekBar
  167. android:id="@+id/sb_alarm"
  168. android:layout_width="match_parent"
  169. android:layout_height="wrap_content"
  170. android:layout_marginTop="5dp"
  171. android:thumb="@drawable/seekbar_point" />
  172. <LinearLayout
  173. android:layout_width="match_parent"
  174. android:layout_height="wrap_content"
  175. android:layout_marginTop="10dp"
  176. android:orientation="horizontal" >
  177. <TextView
  178. android:layout_width="0dp"
  179. android:layout_height="match_parent"
  180. android:layout_weight="1"
  181. android:gravity="bottom|center_horizontal"
  182. android:text="调节通知音量"
  183. android:textColor="#000000"
  184. android:textSize="17sp" />
  185. <ImageView
  186. android:id="@+id/iv_notify_down"
  187. android:layout_width="wrap_content"
  188. android:layout_height="wrap_content"
  189. android:layout_marginRight="30dp"
  190. android:src="@drawable/volumn_down" />
  191. <ImageView
  192. android:id="@+id/iv_notify_up"
  193. android:layout_width="wrap_content"
  194. android:layout_height="wrap_content"
  195. android:layout_marginRight="50dp"
  196. android:src="@drawable/volumn_up" />
  197. </LinearLayout>
  198. <SeekBar
  199. android:id="@+id/sb_notify"
  200. android:layout_width="match_parent"
  201. android:layout_height="wrap_content"
  202. android:layout_marginTop="5dp"
  203. android:thumb="@drawable/seekbar_point" />
  204. </LinearLayout>
  205. </ScrollView>
  206. </LinearLayout>

创作不易 觉得有帮助请点赞关注收藏~~~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/314832
推荐阅读
相关标签
  

闽ICP备14008679号