笔记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 条评论
登录 后参与评论

相关文章

来自专栏刘望舒

打造一个灵活易用的Banner组件

之前做项目时候出于各种考虑,自己开发了Banner组件FBanner,欢迎大家的Star和PR。github上成熟的轮播图库已经有非常多了,比如banner和A...

1135
来自专栏刘望舒

RxBinding使用和源码解析

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

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

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

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

1011
来自专栏james大数据架构

列表视图(ListView和ListActivity)

在ListView中显示网络图片  ImageView 类虽然有一个 setImageUri 方法,但不能直接接受一个由网络地址生成的uri作为参数从而显示图片...

2827
来自专栏林冠宏的技术文章

android 布局 使用 viewPager 时,如何解决 和 子页面 长按滑动 冲突问题

使用 viewPager 时,如何解决 和 子页面 长按滑动 冲突问题。 我的问题原型:      这个问题,我相信遇到的人会比较少,我是在 一个 viewPa...

20210
来自专栏Android-JessYan

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

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

1254
来自专栏Android开发小工

View的事件分发机制

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

681
来自专栏Vamei实验室

安卓第五夜 维纳斯的诞生

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

1877
来自专栏何俊林

Android View框架总结(八)ViewGroup事件分发机制

前言:昨天获得了CSDN博客专家殊荣,也意味着,文章可有有更多的人看到,也让我确信:要得到别人的关注,关键是要让自己的产出对别人有用,也可关注我的csdn:ht...

18210
来自专栏一个会写诗的程序员的博客

第14章 使用Kotlin 进行 Android 开发(2)

我们使用 fastjson 来解析这个数据。在 app 下面的 build.gradle中添加依赖

912

扫码关注云+社区