Android实现简易音量调节(AudioManager)

一:Android中手机声音调节相关函数
1、获取声音管理器
AudioManager audioManager = (AudioManager)getSystemService(Service.AUDIO_SERVICE);

2、获取声音流的最大音量
audioManager.getStreamMaxVolume (int streamType)
Returns the maximum volume index for a particular stream.

3、获取声音流的当前音量
audioManager.getStreamVolume (int streamType)
Returns the current volume index for a particular stream.

4、调节指定声音流的音量:
audioManager.adjustStreamVolume(int streamType, int  direction, int flags);

5、其他声音调节相关
  • audioManager.setStreamMute(int streamType, boolean state);设置指定声音类型(streamType)是否为静音。如果state为true,则设置为静音;否则,不设置为静音。
  • audioManager.setRingerMode(int ringerMode);设置铃音模式,可取值为RINGER_MODE_NORMAL(铃音正常模式), RINGER_MODE_SILENT(铃音静音模式), or RINGER_MODE_VIBRATE(铃音震动模式,即铃音为静音,启动震动)。

6、参数说明:

  • streamType:声音类型,可取值STREAM_VOICE_CALL(通话声音), STREAM_SYSTEM(系统声音),STREAM_RING(响铃声音), STREAM_MUSIC(媒体声音), STREAM_ALARM(闹钟声音),STREAM_NOTIFICATION(通知声音)。
  • direction:调整音量的方向,可取值ADJUST_LOWER(调低音量), ADJUST_RAISE(调高音量), or ADJUST_SAME(保持先前音量)。
  • flags:可选标志位(如要显示出音量调节UI,使用如下flag:AudioManager.FLAG_SHOW_UI)。

7、声音的调节是没有权限要求的;其他详细内容参考AudioManager相关文档(中文版:Android中文API(129) —— AudioManager  )




二:声音调节主要代码如下,具体功能请看注释(其中写着“广播相关”的注释代码功能:监听系统音量改变事件并实时改变滑动条的位置;比如在此应用界面按手机侧键改变音量时,若不监听音量改变事件则程序不会自动改变滑块的位置)

import android.app.Activity;
import android.util.Log;
import android.view.Window;
import android.widget.SeekBar;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;

public class MainActivity extends Activity implements SeekBar.OnSeekBarChangeListener{//实现滑动条接口以监听滑块改变事件

	//声明相关变量
    	private SeekBar seekbar_ntf;
    	private SeekBar seekbar_ring;
    	private SeekBar seekbar_music;
    	private SeekBar seekbar_alarm;
    	private SeekBar seekbar_call;
    	private AudioManager audioManager;
    	//private VolumeReceiver mVolumeReceiver;//广播相关
    	//private boolean setVolume;//广播相关,区分是在当前应用还是其他地方设置的音量

	@Override
	protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	requestWindowFeature(Window.FEATURE_NO_TITLE);
	setContentView(R.layout.activity_main);
	//获取声音管理服务及初始化seekbar
	audioManager = (AudioManager)getSystemService(Service.AUDIO_SERVICE);
	seekbar_ntf = (SeekBar) findViewById(R.id.seekbar_ntf);
	seekbar_ntf.setOnSeekBarChangeListener(this);
	seekbar_ring = (SeekBar) findViewById(R.id.seekbar_ring);
	seekbar_ring.setOnSeekBarChangeListener(this);
	seekbar_music = (SeekBar) findViewById(R.id.seekbar_music);
	seekbar_music.setOnSeekBarChangeListener(this);
	seekbar_alarm = (SeekBar) findViewById(R.id.seekbar_alarm);
	seekbar_alarm.setOnSeekBarChangeListener(this);
	seekbar_call = (SeekBar) findViewById(R.id.seekbar_call);
	seekbar_call.setOnSeekBarChangeListener(this);
	//获取相关音量并设置seekbar
        getAndsetVolume();
	//setVolume = false;//广播相关
	//注册广播 接收器并监听音量变化
        //mVolumeReceiver = new VolumeReceiver() ;//广播相关
        //IntentFilter filter = new IntentFilter() ;//广播相关
        //filter.addAction("android.media.VOLUME_CHANGED_ACTION") ;//广播相关
        //registerReceiver(mVolumeReceiver, filter);//广播相关
	}

	////广播相关,监听音量变化的广播接收器
//    private class VolumeReceiver extends BroadcastReceiver{
//        @Override
//        public void onReceive(Context context, Intent intent) {
//            //若音量发生变化则更改seekbar
//            if(intent.getAction().equals("android.media.VOLUME_CHANGED_ACTION")){
//            	if(setVolume) {//当前应用设置了音量
//            		setVolume = false;
//            	} else {//其他地方设置了音量
//            		getAndsetVolume();
//            	}
//            }
//        }
//    }
    
    	//获取相关音量并设置seekbar
	public void getAndsetVolume() {
	//通知声音,通知、邮件
        int max_ntf = audioManager.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION);
        int cur_ntf = audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
        //Log.d("demo", "sys_max:"+max_sys +", cur"+cur_sys);
        seekbar_ntf.setMax(max_ntf);
        seekbar_ntf.setProgress(cur_ntf);
        //响铃声音,来电、信息
        int max_ring = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
        int cur_ring = audioManager.getStreamVolume(AudioManager.STREAM_RING);
        //Log.d("demo", "ring_max:"+max_ring +", cur"+cur_ring);
        seekbar_ring.setMax(max_ring);
        seekbar_ring.setProgress(cur_ring);
        //媒体声音
        int max_music = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        int cur_music = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        //Log.d("demo", "music_max:"+max_music +", cur"+cur_music);
        seekbar_music.setMax(max_music);
        seekbar_music.setProgress(cur_music);
        //闹钟声音
        int max_alarm = audioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
        int cur_alarm = audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
        //Log.d("demo", "alarm_max:"+max_alarm +", cur"+cur_alarm);
        seekbar_alarm.setMax(max_alarm);
        seekbar_alarm.setProgress(cur_alarm);
        //通话声音
        int max_call = audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
        int cur_call = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
        //Log.d("demo", "call_max:"+max_call +", cur"+cur_call);
        seekbar_call.setMax(max_call);
        seekbar_call.setProgress(cur_call);
	}
	
    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        
    }
    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }
    //监听seekbar滑块改变事件以调节音量
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
        //Log.d("demo", "seekid:"+seekBar.getId()+", progess"+progress);
    	if(fromUser) {//首先判断是否是用户点击滑块,因为程序初始化时会设置滑块位置
	        switch(seekBar.getId()) {
	            case R.id.seekbar_ntf:{
	            	int ntf = audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
	            	if(progress < ntf) {//调小音量
	            		for(int i=0; i<ntf-progress; i++){
	            			//setVolume = true;//广播相关
	            			audioManager.adjustStreamVolume(AudioManager.STREAM_NOTIFICATION, AudioManager.ADJUST_LOWER, AudioManager.FLAG_VIBRATE);
	            		}
	            	} else if(progress > ntf) {//调大音量
	            		for(int i=0; i<progress-ntf; i++){
	            			//setVolume = true;//广播相关
	            			audioManager.adjustStreamVolume(AudioManager.STREAM_NOTIFICATION, AudioManager.ADJUST_RAISE, AudioManager.FLAG_VIBRATE);
	            		}
	            	}
	            	break;
	            }
	            case R.id.seekbar_ring:{
	            	int ring = audioManager.getStreamVolume(AudioManager.STREAM_RING);
	            	if(progress < ring) {//调小音量
	            		for(int i=0; i<ring-progress; i++){
	            			//setVolume = true;//广播相关
	            			audioManager.adjustStreamVolume(AudioManager.STREAM_RING, AudioManager.ADJUST_LOWER, AudioManager.FLAG_VIBRATE);
	            		}
	            	}else if(progress > ring) {//调大音量
	            		for(int i=0; i<progress-ring; i++){
	            			//setVolume = true;//广播相关
	            			audioManager.adjustStreamVolume(AudioManager.STREAM_RING, AudioManager.ADJUST_RAISE, AudioManager.FLAG_VIBRATE);
	            		}
	            	}
	            	break;
	            }
	            case R.id.seekbar_music:{
	            	int music = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
	            	if(progress < music) {//调小音量
	            		for(int i=0; i<music-progress; i++){
	            			//setVolume = true;//广播相关
	            			audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, AudioManager.FLAG_VIBRATE);
	            		}
	            	}else if(progress > music) {//调大音量
	            		for(int i=0; i<progress-music; i++){
	            			//setVolume = true;//广播相关
	            			audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FLAG_VIBRATE);
	            		}
	            	}
	            	break;
	            }
	            case R.id.seekbar_alarm:{
	            	int alarm = audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
	            	if(progress < alarm) {//调小音量
	            		for(int i=0; i<alarm-progress; i++){
	            			//setVolume = true;//广播相关
	            			audioManager.adjustStreamVolume(AudioManager.STREAM_ALARM, AudioManager.ADJUST_LOWER, AudioManager.FLAG_VIBRATE);
	            		}
	            	}else if(progress > alarm) {//调大音量
	            		for(int i=0; i<progress-alarm; i++){
	            			//setVolume = true;//广播相关
	            			audioManager.adjustStreamVolume(AudioManager.STREAM_ALARM, AudioManager.ADJUST_RAISE, AudioManager.FLAG_VIBRATE);
	            		}
	            	}
	            	break;
	            }
	            case R.id.seekbar_call:{
	            	int call = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
	            	if(progress < call) {//调小音量
	            		for(int i=0; i<call-progress; i++){
	            			//setVolume = true;//广播相关
	            			audioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_LOWER, AudioManager.FLAG_VIBRATE);
	            		}
	            	}else if(progress > call) {//调大音量
	            		for(int i=0; i<progress-call; i++){
	            			//setVolume = true;//广播相关
	            			audioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_RAISE, AudioManager.FLAG_VIBRATE);
	            		}
	            	}
	            	break;
	            }
	            default:
	                break;
	        }
    	}
    }
    
//    public void onDestoty() {
//    	super.onDestroy();
//    	////广播相关,取消注册广播接收器
//    	unregisterReceiver(mVolumeReceiver);
//    }

}



三:实现一个非全屏的窗口
1.在AndroidManifest.xml中指定活动的theme,若在application标签指定则作用于整个应用
<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:theme="@style/MyTheme" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

若报如下错误:You need to use a Theme.AppCompat theme (or descendant) with this activity.
则按如下解决:一般是由于activity是Eclipse自动创建的,其中MainActivity继承自兼容包的ActionBarActivity;把后面的ActionBarActivity改成Activity,然后导入相关的包即可


2.在res的values目录下创建styles.xml实现theme
<resources>
    <style name="MyTheme">
        <!-- 悬浮窗模式 ,没有这句窗口变全屏-->
        <item name="android:windowIsFloating">true</item>
        <!-- 窗口外的背景变暗 -->
        <item name="android:backgroundDimEnabled">true</item>
        <!-- 背景 -->
        <item name="android:windowBackground">@drawable/background</item>
        <!-- 无标题 -->
        <item name="android:windowNoTitle">true</item>
        
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
    </style>
</resources>


3.在res的drawable目录下创建background.xml实现自定义theme的背景
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
   <padding android:left="10dp" android:top="20dp"
            android:right="10dp" android:bottom="20dp" />
   <stroke android:width="5dp" android:color="#000000" />
   <corners android:radius="30dp" />
   <solid android:color="#FFFFFF" />
</shape>


4.activity_main.xml相关布局
使用LinearLayout垂直布局,用的控件TextView和SeekBar以及分隔线
  • 分隔线
<View
    android:layout_width="match_parent"
    android:layout_height="2px"
    android:background="#666666"
    />

  • SeekBar
<SeekBar
    android:id="@+id/seekbar_call"
    android:layout_width="fill_parent"  
    android:layout_height="23dip"  
    android:paddingLeft="20dip"  
    android:paddingRight="20dip"  
    android:paddingBottom="3dip"   
    android:thumb="@layout/thumb" />


其中thumb为滑动条中的按钮样式,thumb.xml内容如下
<selector xmlns:android="http://schemas.android.com/apk/res/android">           
    <!-- 按下状态 -->    
    <item       
        android:state_pressed="true"       
        android:drawable="@drawable/thumb_bt" />      
                
    <!-- 普通无焦点状态 -->    
    <item       
        android:state_focused="false"       
        android:state_pressed="false"     
        android:drawable="@drawable/thumb_bt_pressed" />   
</selector> 


效果图Android实现简易音量调节(AudioManager)_第1张图片

你可能感兴趣的:(Android实现简易音量调节(AudioManager))