公司项目做的差不多了,,闲下来了,,就写一篇关于android利用MediaRecorder实现录音的文章吧,并且录音的时候声音的大小可以控制话筒实现动画效果,
效果如图所示:
录音的文件最后保存在SD卡下名为”luyin.3gp”这个文件,
直接看代码咯:
主要就一个MainActivity:
import java.io.File;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
//存储很多张话筒图片的数组
private Drawable[] micImages;
//话筒的图片
private ImageView micImage;
private RelativeLayout recordingContainer;
private TextView recordingHint;
private Button buttonPressToSpeak;
private MediaRecorder recorder=null;
//录音存储在SD卡的路径
private String output_Path=Environment.getExternalStorageDirectory().getAbsolutePath()
+File.separator+"luyin.3gp";
//录音文件
private File soundFile;
private int BASE = 600;
private int SPACE = 200;// 间隔取样时间
private final Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
int what=msg.what;
//根据mHandler发送what的大小决定话筒的图片是哪一张
//说话声音越大,发送过来what值越大
if(what>13){
what=13;
}
micImage.setImageDrawable(micImages[what]);
};
};
private Runnable mUpdateMicStatusTimer = new Runnable() {
public void run() {
updateMicStatus();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
micImage=(ImageView) findViewById(R.id.mic_image);
recordingHint=(TextView) findViewById(R.id.recording_hint);
recordingContainer=(RelativeLayout) findViewById(R.id.recording_container);
buttonPressToSpeak=(Button) findViewById(R.id.buttonPressToSpeak);
buttonPressToSpeak.setOnTouchListener(new PressToSpeakListen());
// 动画资源文件,用于录制语音时
micImages = new Drawable[] {
getResources().getDrawable(R.drawable.record_animate_01),
getResources().getDrawable(R.drawable.record_animate_02),
getResources().getDrawable(R.drawable.record_animate_03),
getResources().getDrawable(R.drawable.record_animate_04),
getResources().getDrawable(R.drawable.record_animate_05),
getResources().getDrawable(R.drawable.record_animate_06),
getResources().getDrawable(R.drawable.record_animate_07),
getResources().getDrawable(R.drawable.record_animate_08),
getResources().getDrawable(R.drawable.record_animate_09),
getResources().getDrawable(R.drawable.record_animate_10),
getResources().getDrawable(R.drawable.record_animate_11),
getResources().getDrawable(R.drawable.record_animate_12),
getResources().getDrawable(R.drawable.record_animate_13),
getResources().getDrawable(R.drawable.record_animate_14), };
}
/**
* 按住说话listener
*
*/
class PressToSpeakListen implements View.OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!isExitsSdcard()) {
Toast.makeText(MainActivity.this, "未检测到SD卡", Toast.LENGTH_SHORT).show();
return false;
}
if(recorder!=null){
recorder.stop();
recorder.release();
recorder=null;
}
soundFile=new File(output_Path);
recorder=new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//声音来源是话筒
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置格式
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置解码方式
recorder.setOutputFile(soundFile.getAbsolutePath());
try {
recorder.prepare();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
recorder.start();
updateMicStatus();
recordingContainer.setVisibility(View.VISIBLE);
recordingHint.setText("手指上滑,取消发送");
recordingHint.setBackgroundColor(Color.TRANSPARENT);
return true;
case MotionEvent.ACTION_MOVE: {
//在这里只是做了监听,并没有做与发送相关的处理
if (event.getY() < 0) {
recordingHint.setText("松开手指,取消发送");
recordingHint.setBackgroundResource(R.drawable.recording_text_hint_bg);
} else {
recordingHint.setText("手指上滑,取消发送");
recordingHint.setBackgroundColor(Color.TRANSPARENT);
}
return true;
}
case MotionEvent.ACTION_UP:
//抬起手指,停止录音
recordingContainer.setVisibility(View.INVISIBLE);
stopRecoder();
Toast.makeText(getApplicationContext(), "录音存储到了"+soundFile.getAbsolutePath(), 1).show();
return true;
default:
return false;
}
}
}
private void stopRecoder(){
if (soundFile != null && soundFile.exists())
{
// 停止录音
recorder.stop();
// 释放资源
recorder.release();
recorder = null;
}
}
private void updateMicStatus() {
if(recorder!=null){
int ratio = recorder.getMaxAmplitude() / BASE;
int db = 0;// 分贝
if (ratio > 1)
db = (int) (20 * Math.log10(ratio));
System.out.println("分贝值:"+db+" "+Math.log10(ratio));
//我对着手机说话声音最大的时候,db达到了35左右,
mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
//所以除了2,为的就是对应14张图片
mHandler.sendEmptyMessage(db/2);
}
}
/**
* 检测Sdcard是否存在
*
* @return
*/
public boolean isExitsSdcard() {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
return true;
else
return false;
}
}
然后是activity_main.xml:
<RelativeLayout 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"
>
<RelativeLayout
android:id="@+id/recording_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/recording_hint_bg"
android:padding="10dp"
android:visibility="invisible" >
<ImageView
android:id="@+id/mic_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@drawable/record_animate_01" />
<TextView
android:id="@+id/recording_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/mic_image"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:padding="2dp"
android:text="手指上滑,取消发送"
android:textSize="10sp" />
RelativeLayout>
<Button
android:id="@+id/buttonPressToSpeak"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dip"
android:layout_centerHorizontal="true"
android:text="摁下录音" />
RelativeLayout>
最后不要忘了加权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>