笔记18 | 利用MediaRecorder简单实现录音

前言

MediaRecorder可以实现录音和录像,使用MediaRecorder录音录像时需要严格遵守API说明中的函数调用先后顺序,否则不能成功执行。

地址

CSDN 地址:http://blog.csdn.net/xiangyong_1521/article/details/50681230 官方说明:http://developer.android.com/reference/android/media/MediaRecorder.html

MediaRecorder类的常用方法

  • MediaRecorder() 构造方法
  • getMaxAmplitude() 得到目前为止最大的幅度
  • prepare() 准备录音机
  • release() 释放MediaRecorder对象
  • reset() 重置MediaRecorder对象,使其为空闲状态
  • setAudioEncoder() 设置音频编码
  • setAudioSource() 设置音频源
  • setCamera() 设置摄像机
  • setMaxDuration() 设置最大期限
  • setMaxFileSize() 设置文件的最大尺寸
  • setOnErrorListener() 错误监听
  • setOutputFile() 设置输出文件
  • setOutputFormat() 设置输出文件的格式
  • setPreviewDisplay() 设置预览
  • setVideoEncoder() 设置视频编码
  • setVideoFrameRate() 设置视频帧的频率
  • setVideoSize() 设置视频的宽度和高度(分辨率)
  • setVideoSource() 设置视频源
  • start() 开始录制
  • stop() 停止录制

实现效果

2017年10月16日拓展:

主要代码

  • MainActivity
package com.example.book_mediarecorder;

import java.io.File;
import java.sql.Date;
import java.text.SimpleDateFormat;
import android.app.Activity;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

	Boolean isRecording=false;
	TextView rTimer;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		final Button button = (Button) findViewById(R.id.bRecourd);
		rTimer = (TextView) findViewById(R.id.rTimer);
		if (isRecording) {
			button.setText("正在录制中...");
		}else{
			button.setText("开始录制");
		}
		button.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (!isRecording) {
					isRecording=true;
					button.setText("正在录制中...");
					startRecord();
				}else{
					isRecording=false;
					button.setText("开始录制");
					stopRecord();
				}
			}
		});
	}

	private MediaRecorder mr=null; 
	int Count;
	//开始录制
	private void startRecord() {
		if (mr == null) {
			File dir = new File(Environment.getExternalStorageDirectory(), "sounds"); //创建音频存放的目录
			if (!dir.exists()) {
				dir.mkdirs();
			}
			File soundFile = new File(dir, getCurrentTime()+".amr"); //创建的音频名称
			if (!soundFile.exists()) {
				try {
					soundFile.createNewFile();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			mr = new MediaRecorder();
			mr.setAudioSource(MediaRecorder.AudioSource.MIC);//拿到机器的MIC
			mr.setOutputFormat(MediaRecorder.OutputFormat.AMR_WB);//设置输出格式
			mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);//设置编码格式
			mr.setOutputFile(soundFile.getAbsolutePath());
			try {
				mr.prepare();
				mr.start();
			} catch (Exception e) {
				e.printStackTrace();
			}
			Count = 0;
			handler = new Handler();
			runnable = new Runnable() {

				@Override
				public void run() {
					if (Count == 1800) {//限制录制时间1800s
						mr.stop();
						mr.release();
						mr = null;
					}
					Count ++;
					str = showTimeCount((long)Count)+"/30:00";
					rTimer.setText(str);
					if (handler!=null) {
						handler.postDelayed(this, 1000);
					}
				}
			};
			runnable.run();
		}
	}
	Handler handler;
	Runnable runnable ;
	String str;
	//停止录制
	private void stopRecord() {
		if (mr != null) {
			mr.stop();
			mr.release();
			mr = null;
		}
		str="";
		handler=null;
		runnable=null;
	}


	//获取当前时间,以其为名来保存录音  
	private String getCurrentTime(){  
		SimpleDateFormat format=new SimpleDateFormat("yyyyMMddHHmmss");  
		Date date=new Date(System.currentTimeMillis());  
		String str=format.format(date);  
		return str;  

	} 

	////将时间转为计时格式
	String showTimeCount(long time){
		String s = null;
		if (time <= 59) {
			s = "00:";
			return time<10 ? s+"0"+String.valueOf(time) : s+String.valueOf(time);
		}else{
			return (time%60 <10 ? s+"0"+String.valueOf(time) : s+String.valueOf(time))+ ":"+(time/60<10 ? s+"0"+String.valueOf(time) : s+String.valueOf(time));  
		}
	}


}
  • 权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

原文发布于微信公众号 - 项勇(xiangy_life)

原文发表时间:2017-10-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏刘望舒

RxBinding使用和源码解析

作者 | juexingzhe 地址 | https://www.jianshu.com/u/ea71bb3770b4 声明 | 本文是 juexingzhe...

45510
来自专栏Vamei实验室

安卓第五夜 维纳斯的诞生

之前各讲中,分别讲解了安卓的开发环境、架构和基本概念。从这一讲开始,我将制作一个简单的应用,并通过逐步升级它的功能,连带出安卓开发的多个情境。 《维纳斯的诞生》...

2047
来自专栏Android-JessYan

我一行代码都不写实现Toolbar!你却还在封装BaseActivity?

原文地址: http://www.jianshu.com/p/75a5c24174b2 qq群:301733278

1744
来自专栏刘望舒

感受LiveData与ViewModel结合之美

虽说这篇是说LiveData与ViewModel,但是或多或少都有涉及另外一个组件:Lifecycles 。它们连同Room都是在17年谷歌IO大会推出的,当时...

1412
来自专栏GIS讲堂

Arcgis for Androd API开发系列教程(一)——地图显示与GPS定位

序:最近呢,工作鸭梨不是怎么大,对于自己爱折腾的想法又冒出了水面,开始自己的android开发的学习之旅。但是呢,本人是做GIS的,所以呢,就打算从这方面入手看...

1665
来自专栏Android开发小工

View的事件分发机制

当一个点击事件产生后,他的传递过程遵循Activity->Window->View的逐级传递。我们这里讨论的是在Android系统View里事件传递。

771
来自专栏Android干货园

Android谈谈封装那些事--BaseActivity和BaseFragment(一)

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/53...

6693
来自专栏青蛙要fly的专栏

Android技能树 — View事件体系小结

这次是讲View的事件体系。特别是不同情况下的事件分发,我会用很简单的方式教会大家。

1211
来自专栏Vamei实验室

安卓第五夜 维纳斯的诞生

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

2003
来自专栏飞雪无情的博客

Android EditText使用详解-包含很多教程上看不到的功能演示

标题有点大,说是详解,其实就是对EditText的一些常用功能的介绍,包括密码框,电话框,空白提示文字等等的讲解,尽量的介绍详细一点,也就是所谓的详解了。。呵呵

6612

扫码关注云+社区

领取腾讯云代金券