基于AudioManager实现的音频控制器
.
介绍
如果我们想对Android 系统中各种音频进行控制,那我们可以通过**AudioManager **(音频管理器)类提供的方法来实现,该类提供了各种音量控制与设置铃声模式相关操作,并且可以对麦克风以及音频焦点进行管理和监听等等。
.
.
AudioManager的常用方法
.
1. 音量控制相关的方法:
- getStreamMaxVolume(streamType):
作用: 获取streamType 对应类型的最大音量值
- getStreamVolume(streamType):
作用: 获取streamType 对应类型的当前音量,当设置为0的时候,会自动调整为震动模式
- adjustStreamVolume(streamType, direction,flags):
作用: 根据不同的streamType 类型,调整手机指定类型的声音
streamType类型如下:
STREAM_ALARM :表示手机闹铃的声音STREAM_DTMF :表示DTMF音调的声音STREAM_MUSIC :表示手机媒体声音STREAM_NOTIFICATION :表示系统提示的声音STREAM_RING :表示电话铃声的声音STREAM_SYSTEM :表示手机系统的声音STREAM_VOICE_CALL :表示语音电话的声音
- setStreamVolume (streamType,index,flags):
作用: 直接设置手机的指定类型的音量值。其中streamType 参数与adjustStreamVolume() 方法中第一个参数的意义相同
- setStreamMute(streamType,state):
作用: 将手机的指定类型的声音调整为静音。其中streamType 参数与adjustStreamVolume() 方法中第一个参数的意义相同
.
2. 铃声与通话相关的方法:
作用: 获取当前的音频模式
作用: 设置声音模式。可设置的值有 NORMAL ,RINGTONE , 和IN_CALL
作用: 获取当前的铃声模式
- setRingerMode(ringerMode):
作用: 设置手机电话铃声的模式
ringerMode类型如下:
RINGER_MODE_NORMAL :正常的手机铃声RINGER_MODE_SILENT :手机铃声静音RINGER_MODE_VIBRATE :手机震动
- setSpeakerphoneOn(boolean on):
作用: 设置扬声器打开或关闭。设置为true 开启免提通话;false 关闭免提
- setMicrophoneMute(boolean on):
作用: 设置是否让麦克风静音。设置为true 将麦克风静音;false 关闭静音
.
3. 音频设置相关的方法:
作用: 判断是否有音乐处于活跃状态
- requestAudioFocus(AudioManager.OnAudioFocusChangeListener,streamType,durationHint):
作用: 请求音频的焦点
- abandonAudioFocus(AudioManager.OnAudioFocusChangeListener):
作用: 放弃音频的焦点
作用: 加载声音效果
- playSoundEffect(effectType,volume):
作用: 播放声音效果
作用: 卸载音效
- setStreamSolo(streamType,state):
作用: 设置独奏或来取消特定流
作用: 判断是否插入了耳机
.
.
基于AudioManager音频控制器的实现
.
效果图:
.
1. 在AndroidManifest.xml 中注册权限
<!-- 授予程序访问振动器的权限 -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
.
2. 获得AudioManager对象实例
private Vibrator vibrator;
private AudioManager audioManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
audioManager = (AudioManager) getApplicationContext().getSystemService
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
}
.
3. 调用 AudioManager中的方法实现具体功能
.
4. 监听物理音量按键
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.i("萝莉","="+keyCode);
mediaCurVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (mediaCurVolume < mediaMaxVolume) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mediaCurVolume + 1, 0);
sb_media_audio.setProgress(mediaCurVolume + 1);
} else {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mediaMaxVolume, 0);
sb_media_audio.setProgress(mediaMaxVolume);
}
setVibrator();
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (mediaCurVolume > 0) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mediaCurVolume - 1, 0);
sb_media_audio.setProgress(mediaCurVolume - 1);
} else {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
sb_media_audio.setProgress(0);
}
setVibrator();
return true;
}
return super.onKeyDown(keyCode, event);
}
.
.
实现的完整代码如下:
.
1. 布局代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/container_ball_menu_detail_voice"
android:layout_width="240dp"
android:layout_height="240dp"
android:background="@drawable/shape_react_corners_top_menu_bg"
android:padding="3dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:id="@+id/container_ball_menu_detail_voice_content"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="10dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
android:id="@+id/iv_audio_mode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/switch_mode"
android:layout_alignBottom="@id/switch_mode"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:src="@drawable/ic_silent_mode_0" />
<TextView
android:id="@+id/tv_audio_mode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/iv_audio_mode"
android:layout_alignBottom="@id/iv_audio_mode"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/iv_audio_mode"
android:gravity="center_vertical"
android:src="@drawable/ic_notifications"
android:text="静音关"
android:textColor="#ffffff" />
<Switch
android:id="@+id/switch_mode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:paddingEnd="5dp"
tools:ignore="UseSwitchCompatOrMaterialXml" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<ImageView
android:id="@+id/iv_audio_media"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_media" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/iv_audio_media"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="媒体"
android:textColor="@color/colorWhite" />
<SeekBar
android:id="@+id/sb_media_audio"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<ImageView
android:id="@+id/iv_audio_ring"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_notifications" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/iv_audio_ring"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="铃声"
android:textColor="@color/colorWhite" />
<SeekBar
android:id="@+id/sb_ring_audio"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<ImageView
android:id="@+id/iv_audio_alarm"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_alarm" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/iv_audio_alarm"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="闹钟"
android:textColor="@color/colorWhite" />
<SeekBar
android:id="@+id/sb_alarm_audio"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<ImageView
android:id="@+id/iv_audio_call"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_audio_call" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/iv_audio_call"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="通话"
android:textColor="@color/colorWhite" />
<SeekBar
android:id="@+id/sb_call_audio"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
.
2. MainActivity 中的实现的Java代码
public class MainActivity extends AppCompatActivity {
private Vibrator vibrator;
private int vibrateLevel = 30;
private AudioManager audioManager;
private int mediaMaxVolume;
private int mediaCurVolume;
private int alarmMaxVolume;
private int alarmCurVolume;
private int callMaxVolume;
private int callCurVolume;
private int ringMaxVolume;
private int ringCurVolume;
private ImageView iv_audio_mode;
private TextView tv_audio_mode;
private Switch switch_mode;
private SeekBar sb_media_audio;
private SeekBar sb_alarm_audio;
private SeekBar sb_call_audio;
private SeekBar sb_ring_audio;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
initView();
initListener();
}
@Override
protected void onResume() {
super.onResume();
setData();
}
private void init() {
audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
}
private void initView() {
tv_audio_mode = findViewById(R.id.tv_audio_mode);
iv_audio_mode = findViewById(R.id.iv_audio_mode);
switch_mode = findViewById(R.id.switch_mode);
sb_media_audio = findViewById(R.id.sb_media_audio);
sb_alarm_audio = findViewById(R.id.sb_alarm_audio);
sb_call_audio = findViewById(R.id.sb_call_audio);
sb_ring_audio = findViewById(R.id.sb_ring_audio);
}
private void setData() {
mediaMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
mediaCurVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
alarmMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
alarmCurVolume = audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
callMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
callCurVolume = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
ringMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
ringCurVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
sb_media_audio.setMax(mediaMaxVolume);
sb_media_audio.setProgress(mediaCurVolume);
sb_alarm_audio.setMax(alarmMaxVolume);
sb_alarm_audio.setProgress(alarmCurVolume);
sb_call_audio.setMax(callMaxVolume);
sb_call_audio.setProgress(callCurVolume);
sb_ring_audio.setMax(ringMaxVolume);
sb_ring_audio.setProgress(ringCurVolume);
switch (audioManager.getRingerMode()) {
case AudioManager.RINGER_MODE_SILENT:
case AudioManager.RINGER_MODE_VIBRATE:
switch_mode.setChecked(true);
return;
case AudioManager.RINGER_MODE_NORMAL:
switch_mode.setChecked(false);
return;
}
}
private void initListener() {
switch_mode.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (isChecked) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && !notificationManager.isNotificationPolicyAccessGranted()) {
startActivity(new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS));
} else {
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
iv_audio_mode.setImageResource(R.drawable.ic_silent_mode_1);
tv_audio_mode.setText("静音开");
sb_ring_audio.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_RING));
}
} else {
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
iv_audio_mode.setImageResource(R.drawable.ic_silent_mode_0);
tv_audio_mode.setText("静音关");
sb_ring_audio.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_RING));
}
});
sb_media_audio.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser){
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
setVibrator();
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
sb_ring_audio.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser){
audioManager.setStreamVolume(AudioManager.STREAM_RING, progress, 0);
setVibrator();
}
if (audioManager.getStreamVolume(AudioManager.STREAM_RING)!=0){
switch_mode.setChecked(false);
iv_audio_mode.setImageResource(R.drawable.ic_silent_mode_0);
tv_audio_mode.setText("静音关");
}else {
switch_mode.setChecked(true);
iv_audio_mode.setImageResource(R.drawable.ic_silent_mode_1);
tv_audio_mode.setText("静音开");
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
sb_alarm_audio.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser){
audioManager.setStreamVolume(AudioManager.STREAM_ALARM, progress, 0);
setVibrator();
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
sb_call_audio.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser){
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, progress, 0);
setVibrator();
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
private void setVibrator() {
if (vibrator.hasVibrator()) {
vibrator.vibrate(vibrateLevel);
} else {
Toast.makeText(this, "该设备不支持振动功能!", Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.i("萝莉","="+keyCode);
mediaCurVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (mediaCurVolume < mediaMaxVolume) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mediaCurVolume + 1, 0);
sb_media_audio.setProgress(mediaCurVolume + 1);
} else {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mediaMaxVolume, 0);
sb_media_audio.setProgress(mediaMaxVolume);
}
setVibrator();
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (mediaCurVolume > 0) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mediaCurVolume - 1, 0);
sb_media_audio.setProgress(mediaCurVolume - 1);
} else {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
sb_media_audio.setProgress(0);
}
setVibrator();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
.
案例地址:
.
.
参考资料
|