Android 7.1 修改系统默认音量
一.系统修改默认音量
frameworks\base\media\java\android\media\AudioSystem.java
1.1.音量类型
STREAM_VOICE_CALL 通话
STREAM_SYSTEM 系统
STREAM_RING 铃声
STREAM_MUSIC 媒体音量
STREAM_ALARM 闹钟
STREAM_NOTIFICATION 通知
public static final int STREAM_DEFAULT = -1;
/* The audio stream for phone calls */
public static final int STREAM_VOICE_CALL = 0;
/* The audio stream for system sounds */
public static final int STREAM_SYSTEM = 1;
/* The audio stream for the phone ring and message alerts */
public static final int STREAM_RING = 2;
/* The audio stream for music playback */
public static final int STREAM_MUSIC = 3;
/* The audio stream for alarms */
public static final int STREAM_ALARM = 4;
/* The audio stream for notifications */
public static final int STREAM_NOTIFICATION = 5;
/* @hide The audio stream for phone calls when connected on bluetooth */
public static final int STREAM_BLUETOOTH_SCO = 6;
/* @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */
public static final int STREAM_SYSTEM_ENFORCED = 7;
1.2.默认音量大小
public static int getDefaultStreamVolume(int streamType) {
return DEFAULT_STREAM_VOLUME[streamType];
}
public static int[] DEFAULT_STREAM_VOLUME = new int[] {
11, // STREAM_VOICE_CALL
11, // STREAM_SYSTEM
11, // STREAM_RING
11, // STREAM_MUSIC
11, // STREAM_ALARM
11, // STREAM_NOTIFICATION
11, // STREAM_BLUETOOTH_SCO
11, // STREAM_SYSTEM_ENFORCED
11, // STREAM_DTMF
11 // STREAM_TTS
};
二.音频管理器 修改 系统音量
1.1.权限问题
02-17 10:29:18.007 D/AndroidRuntime( 3353): Shutting down VM 02-17 10:29:18.009 E/AndroidRuntime( 3353): FATAL EXCEPTION: main 02-17 10:29:18.009 E/AndroidRuntime( 3353): Process: com.gatsby.sound, PID: 3353 02-17 10:29:18.009 E/AndroidRuntime( 3353): java.lang.SecurityException: Not allowed to change Do Not Disturb state 02-17 10:29:18.009 E/AndroidRuntime( 3353): at android.os.Parcel.readException(Parcel.java:1692) 02-17 10:29:18.009 E/AndroidRuntime( 3353): at android.os.Parcel.readException(Parcel.java:1645) 02-17 10:29:18.009 E/AndroidRuntime( 3353): at android.media.IAudioService$Stub$Proxy.setStreamVolume(IAudioService.java:788) 02-17 10:29:18.009 E/AndroidRuntime( 3353): at android.media.AudioManager.setStreamVolume(AudioManager.java:1046) 02-17 10:29:18.009 E/AndroidRuntime( 3353): at com.gatsby.sound.MainActivity$1.onProgressChanged(MainActivity.java:48) 02-17 10:29:18.009 E/AndroidRuntime( 3353): at android.widget.SeekBar.onProgressRefresh(SeekBar.java:93)
解决方法
Android 7.0及之后,设置系统音量需要开启勿扰模式权限,需要在AndroidManifest.xml里面申请如下权限
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
然后设置音量的时候,如果没有权限,需要引导用户去设置页打开勿扰模式下设置音量的权限:
NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& !mNotificationManager.isNotificationPolicyAccessGranted()) {
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
mContext.startActivity(intent);
}

2.Demo
2.1.AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gatsby.sound">
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Sound">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
2.2.dimens.xml
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

2.3.activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/lableSys"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/媒体音量"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:text="系统音量:" />
<TextView
android:id="@+id/媒体音量"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/seekBarSys"
android:layout_alignEnd="@+id/lableNotfic"
android:layout_alignParentStart="true"
android:layout_marginTop="19dp"
android:text="媒体音量" />
<TextView
android:id="@+id/lableNotfic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/媒体音量"
android:layout_alignParentStart="true"
android:layout_marginTop="23dp"
android:text="系统提示音" />
<Button
android:id="@+id/btnSysOut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="15dp"
android:text="退出" />
<TextView
android:id="@+id/sysVol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/lableSys"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:text="15/15" />
<TextView
android:id="@+id/mediaVol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/seekBarMedia"
android:layout_alignBottom="@+id/seekBarMedia"
android:layout_alignParentEnd="true"
android:text="0/10" />
<TextView
android:id="@+id/notficVol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/seekBarNotfic"
android:layout_alignParentEnd="true"
android:text="0/10" />
<SeekBar
android:id="@+id/seekBarMedia"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/媒体音量"
android:layout_toEndOf="@+id/媒体音量" />
<SeekBar
android:id="@+id/seekBarSys"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_toEndOf="@+id/lableSys" />
<SeekBar
android:id="@+id/seekBarNotfic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/lableNotfic"
android:layout_alignParentEnd="true"
android:layout_toEndOf="@+id/lableNotfic" />
</RelativeLayout>
2.3.MainActivity.java
package com.gatsby.sound;
import android.annotation.SuppressLint;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
Context mContext;
SeekBar sbSys;
SeekBar sbMedia;
SeekBar sbNotfic;
AudioManager am;
TextView sysVol;
TextView mediaVol;
TextView notficVol;
@SuppressLint("SetTextI18n")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
Button btn = (Button) findViewById(R.id.btnSysOut);
sysVol = (TextView) findViewById(R.id.sysVol);
mediaVol = (TextView) findViewById(R.id.mediaVol);
notficVol = (TextView) findViewById(R.id.notficVol);
sysVol.setText(am.getStreamVolume(AudioManager.STREAM_SYSTEM) + "/" + am.getStreamMaxVolume(AudioManager.STREAM_SYSTEM));
mediaVol.setText(am.getStreamVolume(AudioManager.STREAM_MUSIC) + "/" + am.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
notficVol.setText(am.getStreamVolume(AudioManager.STREAM_NOTIFICATION) + "/" + am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION));
sbSys = (SeekBar) findViewById(R.id.seekBarSys);
sbSys.setMax(am.getStreamMaxVolume(AudioManager.STREAM_SYSTEM));
sbSys.setProgress(am.getStreamVolume(AudioManager.STREAM_SYSTEM));
sbMedia = (SeekBar) findViewById(R.id.seekBarMedia);
sbMedia.setMax(am.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
sbMedia.setProgress(am.getStreamVolume(AudioManager.STREAM_MUSIC));
sbNotfic = (SeekBar) findViewById(R.id.seekBarNotfic);
sbNotfic.setMax(am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION));
sbNotfic.setProgress(am.getStreamVolume(AudioManager.STREAM_NOTIFICATION));
//设置音量权限
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& !mNotificationManager.isNotificationPolicyAccessGranted()) {
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
mContext.startActivity(intent);
}
//系统声音
sbSys.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
am.setStreamVolume(AudioManager.STREAM_SYSTEM, i, AudioManager.FLAG_PLAY_SOUND);
sysVol.setText(am.getStreamVolume(AudioManager.STREAM_SYSTEM) + "/" + am.getStreamMaxVolume(AudioManager.STREAM_SYSTEM));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//媒体声音
sbMedia.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
am.setStreamVolume(AudioManager.STREAM_MUSIC, i, AudioManager.FLAG_PLAY_SOUND);
mediaVol.setText(am.getStreamVolume(AudioManager.STREAM_MUSIC) + "/" + am.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//系统提示音
sbNotfic.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
am.setStreamVolume(AudioManager.STREAM_NOTIFICATION, i, AudioManager.FLAG_PLAY_SOUND);
notficVol.setText(am.getStreamVolume(AudioManager.STREAM_NOTIFICATION) + "/" + am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//退出APP
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
System.exit(0);
}
});
}
}
2.4.VolumeControl.java
package com.gatsby.sound;
import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
public class VolumeControl extends Activity {
AudioManager am=(AudioManager) getSystemService(Context.AUDIO_SERVICE);
/*手机闹铃的声音*/
public static final int DEVICE_ALARM= AudioManager.STREAM_ALARM;
/*手机音乐的声音*/
public static final int DEVICE_MUSIC= AudioManager.STREAM_MUSIC;
/*DTMF音调的声音*/
public static final int DEVICE_DTMF= AudioManager.STREAM_DTMF;
/*电话铃声的声音*/
public static final int DEVICE_RING= AudioManager.STREAM_RING;
/*系统提示的声音*/
public static final int DEVICE_NOTFICATION= AudioManager.STREAM_NOTIFICATION;
/*系统的声音*/
public static final int DEVICE_SYSTEM= AudioManager.STREAM_SYSTEM;
/*语音电话声音*/
public static final int DEVICE_VOICE_CALL= AudioManager.STREAM_VOICE_CALL;
/*降低音量*/
public static final int VOLUME_LOWER= AudioManager.ADJUST_LOWER;
/*升高音量*/
public static final int VOLUME_RAISE= AudioManager.ADJUST_RAISE;
/*保持不变*/
public static final int VOLUME_SAME= AudioManager.ADJUST_SAME;
/*调整音量时播放声音*/
public static final int FLAG_PLAY_SOUND= AudioManager.FLAG_PLAY_SOUND;
/*调整时显示音量条*/
public static final int FLAG_SHOW_UI = AudioManager.FLAG_SHOW_UI;
/*调整音量时什么都不做*/
public static final int FLAG_NONE = 0;
/**
* 控制声音大小
* @param streamType int AudioManager.STREAM_* 指定音量类型
* @param direction int AudioManager.ADJUST_* 调整音量大小
* @param flags int AudioManager.FLAG_* 调整音量时标志
* @return int 得到音量的当前值
*/
public int volumeControl(int streamType,int direction,int flags){
am.adjustStreamVolume(streamType,direction,flags);
return am.getStreamVolume(streamType);
}
/**
* 设置音量指定值
* @param streamType int AudioManager.STREAM_* 指定音量类型
* @param index int [0,MAX_VOLUME] 调整音量大小值
* @param flag int AudioManager.FLAG_* 调整音量时标志
*/
public void setVolume(int streamType,int index,int flag){
int maxVol=am.getStreamMaxVolume(streamType);
index=index>maxVol?maxVol:index;
am.setStreamVolume(streamType,index<=0?0:index,flag);
}
}

浙公网安备 33010602011771号