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);
    }

}

  

 

posted @ 2022-02-17 11:19  CrushGirl  阅读(1799)  评论(0编辑  收藏  举报