文档章节

android 录音操作

短短的歼击机
 短短的歼击机
发布于 2015/12/01 14:13
字数 1071
阅读 458
收藏 0
package cn.shinobi.uitl;

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

import android.media.MediaRecorder;
import android.os.Environment;

public class AudioRecorder {
	private static int SAMPLE_RATE_IN_HZ = 8000;

	final MediaRecorder recorder = new MediaRecorder();
	final String path;

	public AudioRecorder(String path) {
		this.path = sanitizePath(path);
	}

	private String sanitizePath(String path) {
		if (!path.startsWith("/")) {
			path = "/" + path;
		}
		if (!path.contains(".")) {
			path += ".amr";
		}
		return Environment.getExternalStorageDirectory().getAbsolutePath()
				+ "/my" + path;
	}

	public void start() throws IOException {
		String state = android.os.Environment.getExternalStorageState();
		if (!state.equals(android.os.Environment.MEDIA_MOUNTED)) {
			throw new IOException("SD Card is not mounted,It is  " + state
					+ ".");
		}
		File directory = new File(path).getParentFile();
		if (!directory.exists() && !directory.mkdirs()) {
			throw new IOException("Path to file could not be created");
		}
		recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
		recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
		recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
		recorder.setAudioSamplingRate(SAMPLE_RATE_IN_HZ);
		recorder.setOutputFile(path);
		recorder.prepare();
		recorder.start();
	}

	public void stop() throws IOException {
		recorder.stop();
		recorder.release();
	}

	public double getAmplitude() {
		if (recorder != null) {
			return (recorder.getMaxAmplitude());
		} else
			return 0;
	}
}



package cn.shinobi.Activity;


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

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import cn.shinobi.R;
import cn.shinobi.uitl.AudioRecorder;

public class RecordActivity extends Activity {
	
	private Button record;
	private Dialog dialog;
	private AudioRecorder mr;
	private MediaPlayer mediaPlayer;
	private Thread recordThread;
	private Button player;
	private TextView luyin_txt, luyin_path;
	
	private static int MAX_TIME = 15; // 最长录制时间,单位秒,0为无时间限制
	private static int MIX_TIME = 1; // 最短录制时间,单位秒,0为无时间限制,建议设为1
	
	private static int RECORD_NO = 0; // 不在录音
	private static int RECORD_ING = 1; // 正在录音
	private static int RECODE_ED = 2; // 完成录音
	
	private static int RECODE_STATE = 0; // 录音的状态
	
	private static float recodeTime = 0.0f; // 录音的时间
	private static double voiceValue = 0.0; // 麦克风获取的音量值
	
	private ImageView dialog_img;
	private static boolean playState = false; // 播放状态
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.record_audio);
		player = (Button) findViewById(R.id.player);
		luyin_txt = (TextView) findViewById(R.id.luyin_time);
		luyin_path = (TextView) findViewById(R.id.luyin_path);
		
		// 播放
		player.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (!playState) {
					mediaPlayer = new MediaPlayer();
					String url = "file:///sdcard/my/voice.amr";
					try {
						// 模拟器里播放传url,真机播放传getAmrPath()
						// mediaPlayer.setDataSource(url);
						mediaPlayer.setDataSource(getAmrPath());
						mediaPlayer.prepare();
						mediaPlayer.start();
						player.setText("正在播放");
						playState = true;
						// 设置播放结束时监听
						mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
							
							@Override
							public void onCompletion(MediaPlayer mp) {
								if (playState) {
									player.setText("播放声音");
									playState = false;
								}
							}
						});
					}
					catch (IllegalArgumentException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					catch (IllegalStateException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
				else {
					if (mediaPlayer.isPlaying()) {
						mediaPlayer.stop();
						playState = false;
					}
					else {
						playState = false;
					}
					player.setText("播放录音");
				}
				
			}
		});
		record = (Button) this.findViewById(R.id.record);
		
		// 录音
		record.setOnTouchListener(new OnTouchListener() {
			@SuppressLint("ClickableViewAccessibility")
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
					case MotionEvent.ACTION_DOWN:
						// 当按下的时候开启录音操作
						if (RECODE_STATE != RECORD_ING) {
							scanOldFile();
							mr = new AudioRecorder("voice");
							RECODE_STATE = RECORD_ING;
							showVoiceDialog();
							try {
								mr.start();
							}
							catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							mythread();
						}
						
						break;
					case MotionEvent.ACTION_UP:
						if (RECODE_STATE == RECORD_ING) {
							RECODE_STATE = RECODE_ED;
							if (dialog.isShowing()) {
								dialog.dismiss();
							}
							try {
								mr.stop();
								voiceValue = 0.0;
							}
							catch (IOException e) {
								e.printStackTrace();
							}
							// 如果录音时间小于最小时
							if (recodeTime < MIX_TIME) {
								showWarnToast();
								record.setText("按住开始录音");
								RECODE_STATE = RECORD_NO;
							}
							else {
								record.setText("录音完成!点击重新录音");
								luyin_txt.setText("录音时间:" + ((int) recodeTime));
								luyin_path.setText("文件路径:" + getAmrPath());
							}
						}
						break;
				}
				return false;
			}
		});
	}
	
	// 删除老文件
	void scanOldFile() {
		File file = new File(Environment.getExternalStorageDirectory(), "my/voice.amr");
		if (file.exists()) {
			file.delete();
		}
	}
	
	// 录音时显示Dialog
	void showVoiceDialog() {
		dialog = new Dialog(RecordActivity.this, R.style.DialogStyle);
		dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		dialog.setContentView(R.layout.my_dialog);
		dialog_img = (ImageView) dialog.findViewById(R.id.dialog_img);
		dialog.show();
	}
	
	// 录音时间太短时Toast显示
	void showWarnToast() {
		Toast toast = new Toast(RecordActivity.this);
		LinearLayout linearLayout = new LinearLayout(RecordActivity.this);
		linearLayout.setOrientation(LinearLayout.VERTICAL);
		linearLayout.setPadding(20, 20, 20, 20);
		
		// 定义一个ImageView
		ImageView imageView = new ImageView(RecordActivity.this);
		imageView.setImageResource(R.drawable.voice_to_short); // 图标
		
		TextView mTv = new TextView(RecordActivity.this);
		mTv.setText("时间太短   录音失败");
		mTv.setTextSize(14);
		mTv.setTextColor(Color.WHITE);// 字体颜色
		// mTv.setPadding(0, 10, 0, 0);
		
		// 将ImageView和ToastView合并到Layout中
		linearLayout.addView(imageView);
		linearLayout.addView(mTv);
		linearLayout.setGravity(Gravity.CENTER);// 内容居中
		linearLayout.setBackgroundResource(R.drawable.record_bg);// 设置自定义toast的背景
		
		toast.setView(linearLayout);
		toast.setGravity(Gravity.CENTER, 0, 0);// 起点位置为中间 100为向下移100dp
		toast.show();
	}
	
	// 获取文件手机路径
	private String getAmrPath() {
		File file = new File(Environment.getExternalStorageDirectory(), "my/voice.amr");
		return file.getAbsolutePath();
	}
	
	// 录音计时线程
	void mythread() {
		recordThread = new Thread(ImgThread);
		recordThread.start();
	}
	
	// 录音Dialog图片随声音大小切换
	void setDialogImage() {
		if (voiceValue < 200.0) {
			dialog_img.setImageResource(R.drawable.record_animate_01);
		}
		else if (voiceValue > 200.0 && voiceValue < 400) {
			dialog_img.setImageResource(R.drawable.record_animate_02);
		}
		else if (voiceValue > 400.0 && voiceValue < 800) {
			dialog_img.setImageResource(R.drawable.record_animate_03);
		}
		else if (voiceValue > 800.0 && voiceValue < 1600) {
			dialog_img.setImageResource(R.drawable.record_animate_04);
		}
		else if (voiceValue > 1600.0 && voiceValue < 3200) {
			dialog_img.setImageResource(R.drawable.record_animate_05);
		}
		else if (voiceValue > 3200.0 && voiceValue < 5000) {
			dialog_img.setImageResource(R.drawable.record_animate_06);
		}
		else if (voiceValue > 5000.0 && voiceValue < 7000) {
			dialog_img.setImageResource(R.drawable.record_animate_07);
		}
		else if (voiceValue > 7000.0 && voiceValue < 10000.0) {
			dialog_img.setImageResource(R.drawable.record_animate_08);
		}
		else if (voiceValue > 10000.0 && voiceValue < 14000.0) {
			dialog_img.setImageResource(R.drawable.record_animate_09);
		}
		else if (voiceValue > 14000.0 && voiceValue < 17000.0) {
			dialog_img.setImageResource(R.drawable.record_animate_10);
		}
		else if (voiceValue > 17000.0 && voiceValue < 20000.0) {
			dialog_img.setImageResource(R.drawable.record_animate_11);
		}
		else if (voiceValue > 20000.0 && voiceValue < 24000.0) {
			dialog_img.setImageResource(R.drawable.record_animate_12);
		}
		else if (voiceValue > 24000.0 && voiceValue < 28000.0) {
			dialog_img.setImageResource(R.drawable.record_animate_13);
		}
		else if (voiceValue > 28000.0) {
			dialog_img.setImageResource(R.drawable.record_animate_14);
		}
	}
	
	// 录音线程
	private Runnable ImgThread = new Runnable() {
		
		@Override
		public void run() {
			recodeTime = 0.0f;
			while (RECODE_STATE == RECORD_ING) {
				if (recodeTime >= MAX_TIME && MAX_TIME != 0) {
					imgHandle.sendEmptyMessage(0);
				}
				else {
					try {
						Thread.sleep(200);
						recodeTime += 0.2;
						if (RECODE_STATE == RECORD_ING) {
							voiceValue = mr.getAmplitude();
							imgHandle.sendEmptyMessage(1);
						}
					}
					catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
		
		Handler imgHandle = new Handler() {
			@SuppressLint("HandlerLeak")
			@Override
			public void handleMessage(Message msg) {
				
				switch (msg.what) {
					case 0:
						// 录音超过15秒自动停止
						if (RECODE_STATE == RECORD_ING) {
							RECODE_STATE = RECODE_ED;
							if (dialog.isShowing()) {
								dialog.dismiss();
							}
							try {
								mr.stop();
								voiceValue = 0.0;
							}
							catch (IOException e) {
								e.printStackTrace();
							}
							
							if (recodeTime < 1.0) {
								showWarnToast();
								record.setText("按住开始录音");
								RECODE_STATE = RECORD_NO;
							}
							else {
								record.setText("录音完成!点击重新录音");
								luyin_txt.setText("录音时间:" + ((int) recodeTime));
								luyin_path.setText("文件路径:" + getAmrPath());
							}
						}
						break;
					case 1:
						setDialogImage();
						break;
					default:
						break;
				}
				
			}
		};
	};
	
	public boolean dispatchKeyEvent(android.view.KeyEvent event) {
		System.out.println("fq activity dispatch");
		return super.dispatchKeyEvent(event);
		
	};
}



© 著作权归作者所有

短短的歼击机

短短的歼击机

粉丝 82
博文 268
码字总数 269797
作品 0
武汉
高级程序员
私信 提问
Android中的录音效果

其实我们要是想实现录音效果的话,大脑里第一个想的就是先把布局写好,完事以后我们在设置录音按钮点击事件。完事创建录音对象,我们还应该想到的就是设置输出格式、设置编码格式、设置输出文...

长平狐
2012/08/14
587
1
Android中的录音效果

其实我们要是想实现录音效果的话,大脑里第一个想的就是先把布局写好,完事以后我们在设置录音按钮点击事件。完事创建录音对象,我们还应该想到的就是设置输出格式、设置编码格式、设置输出文...

长平狐
2012/08/21
245
1
Android中的录音效果

其实我们要是想实现录音效果的话,大脑里第一个想的就是先把布局写好,完事以后我们在设置录音按钮点击事件。完事创建录音对象,我们还应该想到的就是设置输出格式、设置编码格式、设置输出文...

长平狐
2012/08/09
1K
0
Android 调用系统api录音的两种方式(MediaRecorder、AudioRecord)

废话 权限、权限、权限,必须要先获取了录音权限,其他的事情晚点再说。 另外,新版本的Android 10系统会对录音有调整,引入了一个录音焦点的概念,也就是说以前的麦克风只能一个APP使用,必...

她叫我小渝
04/18
192
0
android使用MediaRecorder实现录音

有四个按钮,分别是“录音”、“停止”、“播放”、“删除”。如图1所示。 图1:录音机的界面 MediaRecorder的生命周期 MediaRecorder可以用来录制音频或视频。它具有以下几个状态: Initial:...

苍海一粟
2011/11/15
10.6K
2

没有更多内容

加载失败,请刷新页面

加载更多

只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常

统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生。 比较通用的返回值格式如下:...

晓月寒丶
昨天
59
0
区块链应用到供应链上的好处和实际案例

区块链可以解决供应链中的很多问题,例如记录以及追踪产品。那么使用区块链应用到各产品供应链上到底有什么好处?猎头悬赏平台解优人才网小编给大家做个简单的分享: 使用区块链的最突出的优...

猎头悬赏平台
昨天
28
0
全世界到底有多少软件开发人员?

埃文斯数据公司(Evans Data Corporation) 2019 最新的统计数据(原文)显示,2018 年全球共有 2300 万软件开发人员,预计到 2019 年底这个数字将达到 2640万,到 2023 年达到 2770万。 而来自...

红薯
昨天
65
0
Go 语言基础—— 通道(channel)

通过通信来共享内存(Java是通过共享内存来通信的) 定义 func service() string {time.Sleep(time.Millisecond * 50)return "Done"}func AsyncService() chan string {retCh := mak......

刘一草
昨天
58
0
Apache Flink 零基础入门(一):基础概念解析

Apache Flink 的定义、架构及原理 Apache Flink 是一个分布式大数据处理引擎,可对有限数据流和无限数据流进行有状态或无状态的计算,能够部署在各种集群环境,对各种规模大小的数据进行快速...

Vincent-Duan
昨天
60
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部