Android中AudioManager和MediaRecorder讲解

AudioManager

官方解释AudioManager是位于Android.media下

AudioManager provides access to volume and ringer mode control.
Use Context.getSystemService(Context.AUDIO_SERVICE) to get an instance of this class.

意思是AudioManager提供体积和振铃器模式控制。
使用Context.getSystemService(Context.AUDIO_SERVICE)这个类的一个实例。

AudioManager主要方法介绍:

方法:setRingerMode(int ringerMode)

解释:设置铃声模式。

方法:setStreamVolume(int streamType, int index, int flags)

解释:设置特定流物量指数。

方法:adjustVolume(int direction, int flags) 
解释:这个方法用来控制手机音量大小,当传入的第一个参数为AudioManager.ADJUST_LOWER时,可将音量调小一个单位,传入 AudioManager.ADJUST_RAISE 时,则可以将音量调大一个单位。

方法:getMode() 
解释:返回当前音频模式。

方法:getRingerMode() 
解释:返回当前的铃声模式。

方法:getStreamVolume(int streamType) 
解释:取得当前手机的音量,最大值为7,最小值为0,当为0时,手机自动将模式调整为“震动模式”。


在本例中,我们将了解如何改变振铃器模式(大声,震动,沉默)和振铃器设备的体积通过我们的应用程序。

activity.main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical" >

    <TextView
	    android:id="@+id/text"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:text="Current Ring Mode: -"
	    android:textAppearance="?android:attr/textAppearanceLarge" />
    
   <RadioGroup
        android:id="@+id/radioRinger"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp" >
 
	   <RadioButton
	       android:id="@+id/radioNormal"
	       android:layout_width="wrap_content"
	       android:layout_height="wrap_content"
	       android:layout_marginTop="10dp"
	       android:checked="true"
	       android:text="Normal" />
	
	    <RadioButton
	        android:id="@+id/radioSilent"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:layout_marginTop="10dp"
	        android:text="Silent" />
	    
	    <RadioButton
	       android:id="@+id/vibrate"
	       android:layout_width="wrap_content"
	       android:layout_height="wrap_content"
	       android:layout_marginTop="10dp"
	       android:text="Vibrate" /> 
     </RadioGroup>

   <Button
       android:id="@+id/mode"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginTop="20dp"
       android:text="Choose Mode" />
   
    <TextView
	       android:id="@+id/text1"
	       android:layout_width="wrap_content"
	       android:layout_height="wrap_content"
	       android:layout_marginTop="20dp"
	       android:text="Adjust the volume:" />


   <LinearLayout
	   android:layout_width="match_parent"
	   android:layout_height="match_parent"
	   android:layout_marginTop="10dp"
	   android:orientation="horizontal" >
	   
	   <Button
	       android:id="@+id/increase"
	       style="?android:attr/buttonStyleSmall"
	       android:layout_width="wrap_content"
	       android:layout_height="wrap_content"
	       android:text="+" />
	
	   <Button
	       android:id="@+id/decrease"
	       style="?android:attr/buttonStyleSmall"
	       android:layout_width="wrap_content"
	       android:layout_height="wrap_content"
	       android:text="-" />
   </LinearLayout>
</LinearLayout>


MainActivity .class
package com.javacodegeeks.android.audiomanagertest;
import android.media.AudioManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends Activity {


   private Button modeBtn;
   private Button increaseBtn;
   private Button decreaseBtn;
   private RadioButton normal;
   private RadioButton silent;
   private RadioGroup ringGroup;
   private TextView status;
   private AudioManager myAudioManager;
   
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);


      normal = (RadioButton) findViewById(R.id.radioNormal);
      silent = (RadioButton) findViewById(R.id.radioSilent);
      status = (TextView) findViewById(R.id.text);
      ringGroup = (RadioGroup) findViewById(R.id.radioRinger);
      myAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);


      modeBtn = (Button)findViewById(R.id.mode);
      modeBtn.setOnClickListener(new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stu
			int selectedId = ringGroup.getCheckedRadioButtonId();
			 
			// find which radioButton is checked by id
		        if(selectedId == silent.getId()) {
		        	silentEnable(v);
		        } else if(selectedId == normal.getId()) {
		        	 normalEnable(v);
		        } else {
		        	vibrateEnable(v);
		        }	
		}
	  });
      
   
      increaseBtn = (Button) findViewById(R.id.increase);
      increaseBtn.setOnClickListener(new OnClickListener() {
  		
  		@Override
  		public void onClick(View v) {
  			// increase the volume and show the ui
  			 myAudioManager.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
  			Toast.makeText(getApplicationContext(), "increase volume", 
 					 Toast.LENGTH_SHORT).show();
  		}
  	  });
      
 
      
      decreaseBtn = (Button) findViewById(R.id.decrease);
      decreaseBtn.setOnClickListener(new OnClickListener() {
  		
  		@Override
  		public void onClick(View v) {
  			// decrease the volume and show the ui
  			 myAudioManager.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
  			 Toast.makeText(getApplicationContext(), "decrease volume", 
  					 Toast.LENGTH_SHORT).show();
  		}
  	  });
   
    
   }
   
  
   /**
    
    * @param view
    */
  


   public void vibrateEnable(View view){
	   // set the ring mode to vibrate
       myAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
       status.setText("Current Status: Vibrate Mode");
   }
   public void normalEnable(View view){
	  // set the ring mode to loud
      myAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
      status.setText("Current Status: Ring Mode");
   }
   public void silentEnable(View view){
	  // set the ring mode to silent
      myAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
      status.setText("Current Status: Silent Mode");
   }
}

效果如下:

 




MediaRecorder


感谢http://www.cnblogs.com/plokmju/p/android_mediarecorder.html提供

官方解释:Used to record audio and video. The recording control is based on a simple state machine(see belown)。

  意思是用于记录音频和视频。录音控制是基于一个简单的状态机(下图)


 


MediaRecorder主要用于记录音频与视频,它位于"android.media.MediaRecorder"下。它为开发人员提供了详尽的AIP以完成记录音频与视频的工作,下面简单介绍一些常用的。

void prepar():准备录制。
void start():开始录制。
void stop():停止录制。
void reset():重置MediaRecorder。
void release():释放MediaRecorder占用的资源。
void setAudioEncoder(int):设置音频记录的编码格式。
void setAudoSource(int):设置音频记录的音频源。
void setOutoutFormat(int):设置记录的媒体文件的输出转换格式。
void setPreviewDisplay(Surface):设置视频的预览界面。
void setVideoEncoder(int):设置视频记录的编码格式。
void setVideoSource(int):设置视频记录的视频源。
void setOutputFile(String):媒体文件输出路径。
void setMaxDuration(int):设置最大记录时长,单位为毫秒。

上面仅仅列出了一些常用的方法,但是通过这个方法可以看出MediaRecorder是需要在多个状态之间切换的,准备、开始、停止、重置等等。MediaRecorder也为我们提供了一套状态切换的规则,只有在既定的状态下,才能完成对应的操作。


上图非常直观的展示了MediaRecorder的状态间的转换,这里只说几点需要注意的地方:

当为MediaRecorder设定媒体录入源之后即初始化完成,这个时候才可以为其设定其他的参数。
在开始录制前必须先调用prepare()准备录制。
只有在Initial初始化状态,才可以对MediaRecorder调用release()释放资源,其他状态必须先stop()或者reset()。
错误状态是游离在所有状态之外的,当发生错误的时候,只有进行reset()才会进入Initial初始状态。
 
  MediaRecorder录制视频必不可少的步骤:

调用new MediaRecorder()构造函数得到MediaRecorder的实例。
调用setOutputFormat()设定媒体文件的输出格式,必须在设定音频与视频的编码格式之前设定。
如果需要记录音频,则调用setAudioSource()设定音频的录入源以及调用setAudioEncoder()设定音频的编码方式。
如果需要记录视频,则调用setVideoSource()设定视频的录入员以及调用setVideoEncoder()设定视频的编码方式。
调用setOutputFile()设定记录的媒体文件保存的路径。
先调用prepare()准备录制,准备完成之后调用start()开始录制。
记录完成后,调用stop()停止录制。


MediaRecorder录制音频


  上面介绍了使用MediaRecorder录制视频必不可少的步骤,因为录制音频无需捕获图像,所以更简单一些。下面直接通过一个简单的示例,演示如何录制音频,录制的音频文件保存在sd根目录下,注释很详细,这里不在累述了。布局很简单,只有两个Button,开始录音、结束录音,就不提供布局代码了。



  实现代码:

package cn.bgxt.mediarecorderdemo;


import java.io.File;
import android.app.Activity;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;


public class RecordActivity extends Activity {
    private Button btn_RecordStart, btn_RecordStop;
    private MediaRecorder mediaRecorder;
    private boolean isRecording;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_record);


        btn_RecordStart = (Button) findViewById(R.id.btn_RecordStart);
        btn_RecordStop = (Button) findViewById(R.id.btn_RecordStop);
        
        btn_RecordStop.setEnabled(false);
        
        btn_RecordStart.setOnClickListener(click);
        btn_RecordStop.setOnClickListener(click);
    }


    private View.OnClickListener click = new OnClickListener() {


        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btn_RecordStart:
                start();
                break;
            case R.id.btn_RecordStop:
                stop();
                break;
            default:
                break;
            }
        }
    };


    /**
     * 开始录音
     */
    protected void start() {
        try {
            File file = new File("/sdcard/mediarecorder.amr");
            if (file.exists()) {
                // 如果文件存在,删除它,演示代码保证设备上只有一个录音文件
                file.delete();
            }
            mediaRecorder = new MediaRecorder();
            // 设置音频录入源
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            // 设置录制音频的输出格式
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            // 设置音频的编码格式
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            // 设置录制音频文件输出文件路径
            mediaRecorder.setOutputFile(file.getAbsolutePath());


            mediaRecorder.setOnErrorListener(new OnErrorListener() {
                
                @Override
                public void onError(MediaRecorder mr, int what, int extra) {
                    // 发生错误,停止录制
                    mediaRecorder.stop();
                    mediaRecorder.release();
                    mediaRecorder = null;
                    isRecording=false;
                    btn_RecordStart.setEnabled(true);
                    btn_RecordStop.setEnabled(false);
                    Toast.makeText(RecordActivity.this, "录音发生错误", 0).show();
                }
            });
            
            // 准备、开始
            mediaRecorder.prepare();
            mediaRecorder.start();
            
            isRecording=true;
            btn_RecordStart.setEnabled(false);
            btn_RecordStop.setEnabled(true);
            Toast.makeText(RecordActivity.this, "开始录音", 0).show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 录音结束
     */
    protected void stop() {
        if (isRecording) {
            // 如果正在录音,停止并释放资源
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
            isRecording=false;
            btn_RecordStart.setEnabled(true);
            btn_RecordStop.setEnabled(false);
            Toast.makeText(RecordActivity.this, "录音结束", 0).show();
        }
    }


    @Override
    protected void onDestroy() {
        if (isRecording) {
            // 如果正在录音,停止并释放资源
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
        }
        super.onDestroy();
    }


}

录制音频需要访问麦克风设备,访问设备需要添加权限:

 <uses-permission android:name="android.permission.RECORD_AUDIO"/>

效果展示:




MediaRecorder录制视频

  上面已经介绍了使用MediaRecorder录制视频的步骤,这里依照步骤一步一步写代码就可以了。下面通过一个简单的Demo演示如何使用MediaRecorder录制一段从摄像头捕获到的视频,录制的视频文件将保持在SD卡上。布局很简单,两个Button,开始、停止,然后还有一个SurfaceView显示预览效果,就不给出布局代码了。


  实现代码:

package cn.bgxt.mediarecorderdemo;


import java.io.File;
import java.io.IOException;


import android.app.Activity;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;


public class VideoActivity extends Activity {
    private Button btn_VideoStart, btn_VideoStop;
    private SurfaceView sv_view;
    private boolean isRecording;
    private MediaRecorder mediaRecorder;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video);


        btn_VideoStart = (Button) findViewById(R.id.btn_VideoStart);
        btn_VideoStop = (Button) findViewById(R.id.btn_VideoStop);
        sv_view = (SurfaceView) findViewById(R.id.sv_view);


        btn_VideoStop.setEnabled(false);


        btn_VideoStart.setOnClickListener(click);
        btn_VideoStop.setOnClickListener(click);
        
        // 声明Surface不维护自己的缓冲区,针对Android3.0以下设备支持
        sv_view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }


    private View.OnClickListener click = new OnClickListener() {


        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btn_VideoStart:
                start();
                break;
            case R.id.btn_VideoStop:
                stop();
                break;
            default:
                break;
            }
        }
    };


    protected void start() {
        try {
            File file = new File("/sdcard/video.mp4");
            if (file.exists()) {
                // 如果文件存在,删除它,演示代码保证设备上只有一个录音文件
                file.delete();
            }
            
            mediaRecorder = new MediaRecorder();
            mediaRecorder.reset();
            // 设置音频录入源
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            // 设置视频图像的录入源
            mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            // 设置录入媒体的输出格式
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            // 设置音频的编码格式
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
            // 设置视频的编码格式
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
            // 设置视频的采样率,每秒4帧
            mediaRecorder.setVideoFrameRate(4);
            // 设置录制视频文件的输出路径
            mediaRecorder.setOutputFile(file.getAbsolutePath());
            // 设置捕获视频图像的预览界面
            mediaRecorder.setPreviewDisplay(sv_view.getHolder().getSurface());
            
            mediaRecorder.setOnErrorListener(new OnErrorListener() {
                
                @Override
                public void onError(MediaRecorder mr, int what, int extra) {
                    // 发生错误,停止录制
                    mediaRecorder.stop();
                    mediaRecorder.release();
                    mediaRecorder = null;
                    isRecording=false;
                    btn_VideoStart.setEnabled(true);
                    btn_VideoStop.setEnabled(false);
                    Toast.makeText(VideoActivity.this, "录制出错", 0).show();
                }
            });
            
            // 准备、开始
            mediaRecorder.prepare();
            mediaRecorder.start();


            btn_VideoStart.setEnabled(false);
            btn_VideoStop.setEnabled(true);
            isRecording = true;
            Toast.makeText(VideoActivity.this, "开始录像", 0).show();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    protected void stop() {
        if (isRecording) {
            // 如果正在录制,停止并释放资源
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
            isRecording=false;
            btn_VideoStart.setEnabled(true);
            btn_VideoStop.setEnabled(false);
            Toast.makeText(VideoActivity.this, "停止录像,并保存文件", 0).show();
        }
    }


    @Override
    protected void onDestroy() {
        if (isRecording) {
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
        }
        super.onDestroy();
    }


}

录制视频需要用到麦克风和摄像头硬件,还需要赋予一些相应的权限。


1     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
2     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
3     <uses-permission android:name="android.permission.CAMERA"/>
4     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>


效果如下:




 MediaRecorder的内部类


  通过上面录制视频的Demo可以看出,使用MediaRecorder录制视频,需要设置一些录入源、编码格式、输出格式等。这些方法都是以int类型的参数设定的,它们其实都是在MediaRecorder的内部类中已经以常量的形式定义好了,直接适用场景进行选择即可。


MediaRecorder.AudioEncoder:音频的编码格式。
MediaRecorder.AudioSource:录制的音频源。
MediaRecorder.OutputFormat:媒体文件的输出编码格式。
MediaRecorder.VideoEncoder:视频的编码格式。
MediaRecorder.VideoSource:录制的视频源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值