[Android] 录音与播放录音实现
http://blog.csdn.net/cxf7394373/article/details/8313980
android开发文档中有一个关于录音的类MediaRecord,一张图介绍了基本的流程:
- MediaRecorder recorder = new MediaRecorder();
- recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- recorder.setOutputFile(PATH_NAME);
- recorder.prepare();
- recorder.start(); // Recording is now started
- ...
- recorder.stop();
- recorder.reset(); // You can reuse the object by going back to setAudioSource() step
- recorder.release(); // Now the object cannot be reused
我在这里实现了一个简单的程序,过程和上述类似,录音以及录音的播放。
- package com.cxf;
- import java.io.IOException;
- import android.app.Activity;
- import android.media.MediaPlayer;
- import android.media.MediaRecorder;
- import android.os.Bundle;
- import android.os.Environment;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class RecordActivity extends Activity {
- private static final String LOG_TAG = "AudioRecordTest";
- //语音文件保存路径
- private String FileName = null;
- //界面控件
- private Button startRecord;
- private Button startPlay;
- private Button stopRecord;
- private Button stopPlay;
- //语音操作对象
- private MediaPlayer mPlayer = null;
- private MediaRecorder mRecorder = null;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //开始录音
- startRecord = (Button)findViewById(R.id.startRecord);
- startRecord.setText(R.string.startRecord);
- //绑定监听器
- startRecord.setOnClickListener(new startRecordListener());
- //结束录音
- stopRecord = (Button)findViewById(R.id.stopRecord);
- stopRecord.setText(R.string.stopRecord);
- stopRecord.setOnClickListener(new stopRecordListener());
- //开始播放
- startPlay = (Button)findViewById(R.id.startPlay);
- startPlay.setText(R.string.startPlay);
- //绑定监听器
- startPlay.setOnClickListener(new startPlayListener());
- //结束播放
- stopPlay = (Button)findViewById(R.id.stopPlay);
- stopPlay.setText(R.string.stopPlay);
- stopPlay.setOnClickListener(new stopPlayListener());
- //设置sdcard的路径
- FileName = Environment.getExternalStorageDirectory().getAbsolutePath();
- FileName += "/audiorecordtest.3gp";
- }
- //开始录音
- class startRecordListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- mRecorder = new MediaRecorder();
- mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- mRecorder.setOutputFile(FileName);
- mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- try {
- mRecorder.prepare();
- } catch (IOException e) {
- Log.e(LOG_TAG, "prepare() failed");
- }
- mRecorder.start();
- }
- }
- //停止录音
- class stopRecordListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- mRecorder.stop();
- mRecorder.release();
- mRecorder = null;
- }
- }
- //播放录音
- class startPlayListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- mPlayer = new MediaPlayer();
- try{
- mPlayer.setDataSource(FileName);
- mPlayer.prepare();
- mPlayer.start();
- }catch(IOException e){
- Log.e(LOG_TAG,"播放失败");
- }
- }
- }
- //停止播放录音
- class stopPlayListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- mPlayer.release();
- mPlayer = null;
- }
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello" />
- <Button
- android:id="@+id/startRecord"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/stopRecord"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/startPlay"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/stopPlay"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.cxf"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="4" />
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity
- android:name=".RecordActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- <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" />
- </manifest>
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="hello"></string>
- <string name="app_name">Record</string>
- <string name="startRecord">开始录音</string>
- <string name="stopRecord">结束录音</string>
- <string name="startPlay">开始播放</string>
- <string name="stopPlay">结束播放</string>
- </resources>
今天在调用MediaRecorder.stop(),报错了,Java.lang.RuntimeException: stop failed.
- E/AndroidRuntime(7698): Cause by: java.lang.RuntimeException: stop failed.
- E/AndroidRuntime(7698): at android.media.MediaRecorder.stop(Native Method)
- E/AndroidRuntime(7698): at com.tintele.sos.VideoRecordService.stopRecord(VideoRecordService.java:298)
报错代码如下:
- if (mediarecorder != null) {
- mediarecorder.stop();
- mediarecorder.release();
- mediarecorder = null;
- if (mCamera != null) {
- mCamera.release();
- mCamera = null;
- }
- }
stop()方法源代码如下:
- /**
- * Stops recording. Call this after start(). Once recording is stopped,
- * you will have to configure it again as if it has just been constructed.
- * Note that a RuntimeException is intentionally thrown to the
- * application, if no valid audio/video data has been received when stop()
- * is called. This happens if stop() is called immediately after
- * start(). The failure lets the application take action accordingly to
- * clean up the output file (delete the output file, for instance), since
- * the output file is not properly constructed when this happens.
- *
- * @throws IllegalStateException if it is called before start()
- */
- public native void stop() throws IllegalStateException;
源代码中说了:Note that a RuntimeException is intentionally thrown to the application, if no valid audio/video data has been received when stop() is called. This happens if stop() is called immediately after start().The failure lets the application take action accordingly to clean up the output file (delete the output file, for instance), since the output file is not properly constructed when this happens.
现在,在mediarecorder.stop();这一句报错了,现在在mediarecorder.stop();这句之前加几句就不会报错了
mediarecorder.setOnErrorListener(null);
mediarecorder.setOnInfoListener(null);
mediarecorder.setPreviewDisplay(null);
改后代码如下:
- if (mediarecorder != null) {
- //added by ouyang start
- try {
- //下面三个参数必须加,不加的话会奔溃,在mediarecorder.stop();
- //报错为:RuntimeException:stop failed
- mediarecorder.setOnErrorListener(null);
- mediarecorder.setOnInfoListener(null);
- mediarecorder.setPreviewDisplay(null);
- mediarecorder.stop();
- } catch (IllegalStateException e) {
- // TODO: handle exception
- Log.i("Exception", Log.getStackTraceString(e));
- }catch (RuntimeException e) {
- // TODO: handle exception
- Log.i("Exception", Log.getStackTraceString(e));
- }catch (Exception e) {
- // TODO: handle exception
- Log.i("Exception", Log.getStackTraceString(e));
- }
- //added by ouyang end
- mediarecorder.release();
- mediarecorder = null;
- if (mCamera != null) {
- mCamera.release();
- mCamera = null;
- }
- }
相关文章
- Android内存泄漏的八种可能
- Android数字跳动的TextView实现
- Android实现将View转化为图片并保存到本地
- JNI 开发基础篇:Android开发中os文件的探索
- Android简易“吹一吹实现”以及录音和播放示例
- Android实现推送方式解决方案 - 长连接+心跳机制(MQTT协议)
- activity的android:name所指的Activity实现类的简写问题
- 【Android】LayoutInflater
- Android平台第三方库资料整理
- android自定义UI模板图文详解
- 使用Broadcast实现android组件之间的通信 分类: android 学习笔记 2015-07-09 14:16 110人阅读 评论(0) 收藏
- 拉模式和推模式,命令式和响应式 – 响应式编程 [Android RxJava2](这到底是什么):第二部分
- Android代码实现APK文件的安装与卸载
- Android实现渐显按钮的左右滑动效果
- Android 实现图片的自动缩放,适应分辨率不同的手机
- android添加购物车动画实现
- Android在滚动列表中实现视频的播放(ListView & RecyclerView)
- React Native调用Android相机图库
- 【React Native开发】React Native 控件之Modal详解-Android/iOS双平台通用(56)
- Android自动登录 记住用户名密码实现 SharedPreferences
- Android RecyclerView 实现position列表倒序排列(汇总)