最近有小伙伴经常android的录音怎么实现,有没有相关的案例。今天给大家推荐一个android中实现录音和播放的小案例。

效果图:

一、实现录音的 Service 关键代码:

// 开始录音
public void startRecording() {
setFileNameAndPath(); mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); //录音文件保存的格式,这里保存为 mp4
mRecorder.setOutputFile(mFilePath); // 设置录音文件的保存路径
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setAudioChannels(1);
// 设置录音文件的清晰度
mRecorder.setAudioSamplingRate(44100);
mRecorder.setAudioEncodingBitRate(192000); try {
mRecorder.prepare();
mRecorder.start();
mStartingTimeMillis = System.currentTimeMillis();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
} // 设置录音文件的名字和保存路径
public void setFileNameAndPath() {
File f; do {
count++;
mFileName = getString(R.string.default_file_name)
+ "_" + (System.currentTimeMillis()) + ".mp4";
mFilePath = Environment.getExternalStorageDirectory().getAbsolutePath();
mFilePath += "/SoundRecorder/" + mFileName;
f = new File(mFilePath);
} while (f.exists() && !f.isDirectory());
} // 停止录音
public void stopRecording() {
mRecorder.stop();
mElapsedMillis = (System.currentTimeMillis() - mStartingTimeMillis);
mRecorder.release(); getSharedPreferences("sp_name_audio", MODE_PRIVATE)
.edit()
.putString("audio_path", mFilePath)
.putLong("elpased", mElapsedMillis)
.apply();
if (mIncrementTimerTask != null) {
mIncrementTimerTask.cancel();
mIncrementTimerTask = null;
} mRecorder = null;
}

二、显示录音界面的 RecordAudioDialogFragment

用户进行的时候,总不能让 App 跳转到另外一个界面吧,这样用户体验并不是很好,比较好的方法是显示一个对话框,让用户进行操作,既然要用对话框,必然离不开 DialogFragment

在 RecordAudioDialogFragment 有一个 newInstance(int maxTime) 的静态方法供外部调用,如果想设置录音的最大时长,直接传参数进去就行了。

好的,敲黑板,重点来了,其实这个对话框的重点部分就是在 onCreateDialog()中,我们先加载了我们自定义的对话框的布局,当点击录音的按钮的时候,先进行相关权限的申请,这里有个巨坑,录音权限 android.permission.RECORD_AUDIO 在不久前还是普通权限的,不知道什么时候突然变成了危险权限,需要我们进行申请,Google 真是会玩。

public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_record_audio, null); mFabRecord.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity()
, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, 1);
}else {
onRecord(mStartRecording);
mStartRecording = !mStartRecording;
}
}
}); builder.setView(view);
return builder.create();
}

三、播放录音的 PlaybackDialogFragment

其实,如果只是录音这一块的话,写个 MediaPlayer 就可以了,然而还要写播放的时间进度,以及显示一个稍微好看点的进度条,我能怎样,我也很烦啊。

外部调用这个对话框的时候,只需要传入一个包含录音文件信息的 RecordingItem,因为包含的信息比较多,所以最好将 RecordingItem 进行序列化。

public static PlaybackDialogFragment newInstance(RecordingItem item) {
PlaybackDialogFragment fragment = new PlaybackDialogFragment();
Bundle bundle = new Bundle();
bundle.putParcelable(ARG_ITEM, item);
fragment.setArguments(b);
return fragment;
}

好,重点又来了,来看看 onCreateDialog() 方法,在加载了布局之后,给 mSeekBar 设置监听,mSeekBar 是一个显示进度条的控件,当开始播放录音时候,将录音文件的时长,设置进 mSeekBar 里面,播放录音的同时,运行 mSeekBar,通过监听 mSeekBar 的进度,刷新显示的播放进度。

public Dialog onCreateDialog(Bundle savedInstanceState) {

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_media_playback, null); mFileLengthTextView.setText(String.valueOf(mFileLength));
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(mMediaPlayer != null && fromUser) {
mMediaPlayer.seekTo(progress);
mHandler.removeCallbacks(mRunnable); long minutes = TimeUnit.MILLISECONDS.toMinutes(mMediaPlayer.getCurrentPosition());
long seconds = TimeUnit.MILLISECONDS.toSeconds(mMediaPlayer.getCurrentPosition())
- TimeUnit.MINUTES.toSeconds(minutes);
mCurrentProgressTextView.setText(String.format("%02d:%02d", minutes,seconds)); updateSeekBar(); } else if (mMediaPlayer == null && fromUser) {
prepareMediaPlayerFromPoint(progress);
updateSeekBar();
}
} }); mPlayButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onPlay(isPlaying);
isPlaying = !isPlaying;
}
}); mFileLengthTextView.setText(String.format("%02d:%02d", minutes,seconds));
builder.setView(view);
return builder.create();
}

当点击播放录音的按钮之后,会调用 onPlay() 方法,然后根据 isPlaying(标识当前是否播放录音)的值,来调用不同的方法

private void onPlay(boolean isPlaying){
if (!isPlaying) {
//currently MediaPlayer is not playing audio
if(mMediaPlayer == null) {
startPlaying(); //start from beginning
}
} else {
pausePlaying();
}
}

我们最关心的,莫过于 startPlaying() 这个方法,这个方法便是来开启播放录音的,我们首先将外部传入的有关的录音信息,设置给 MediaPlayer,然后开始调用 mMediaPlayer.start() 进行录音的播放,然后调用 updateSeekbar() 实时更新进度条的内容。当 MediaPlayer 的内容播放完成后,调用 stopPlaying() 方法,关闭 mMediaPlayer

项目地址:

https://github.com/developerHaoz/SoundRecorderUtils

更多文章

2017上半年技术文章集合—184篇文章分类汇总

NDK项目实战—高仿360手机助手之卸载监听

相信自己,没有做不到的,只有想不到的

如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :644196190 微信公众号:终端研发部

android录音实现不再担心—一个案例帮你解决你的问题的更多相关文章

  1. 【Android】【录音】Android录音--AudioRecord、MediaRecorder

    [Android][录音]Android录音--AudioRecord.MediaRecorder Android提供了两个API用于实现录音功能:android.media.AudioRecord. ...

  2. 从此不再担心键盘遮住输入框OC(一)

    文/Jiar_(简书作者)原文链接:http://www.jianshu.com/p/48993ff982c1著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 新版本在这里:从此不再担心 ...

  3. Vue一个案例引发「内容分发slot」的最全总结

    今天我们继续来说说 Vue,目前一直在自学 Vue 然后也开始做一个项目实战,我一直认为在实战中去发现问题然后解决问题的学习方式是最好的,所以我在学习一些 Vue 的理论之后,就开始自己利用业余时间做 ...

  4. Android 录音和播放

    今天工作上需要做一个一边录音一边播放的功能,大致原因是有一个外部设备输入音频到我们机器,然后我们机器需要马上把音频播放出来.所以了解了一些有关录音和播放的知识.接到这个任务的第一反应就是看看Andro ...

  5. [Android] 录音与播放录音实现

    http://blog.csdn.net/cxf7394373/article/details/8313980 android开发文档中有一个关于录音的类MediaRecord,一张图介绍了基本的流程 ...

  6. android菜鸟学习笔记5----第一个android程序

    程序功能:点击一个按钮,然后弹出一个提示信息 Step 1:在eclipse中新建一个android application project,在创建过程中不勾选create activity,这样就创 ...

  7. Android开发技巧--引用另一个工程

    现在已经有了一个Android工程A.我们想扩展A的功能,但是不想在A的基础上做开发,于是新建了另外一个Android工程B,想在B中引用A. 1:把工程A做成纯Jar包,这样其他的工程就可以直接引用 ...

  8. sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)

    sql server 关于表中只增标识问题   由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错 ...

  9. 通过Android录音进行简单音频分析

    Android录音有MediaRecorder和AudioRecord两种方式,前者使用方便,可以直接生成录音文件,但是录音格式为aac和amr等等,都经过压缩处理,不方便进行音频分析. 而用Audi ...

随机推荐

  1. npm install 报错Unexpected end of JSON input while parsing near...

    安装node http://nodejs.cn/download/ 克隆代码 ....... 执行安装 npm install 然后就报了一坨错误 清理一下缓存 sudo npm cache veri ...

  2. free命令常用参数详解

    free命令常用参数详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在运维期间我们会经常去查看服务器硬件信息,比如说内存,大家可能知道看内存用“[root@yinzhengji ...

  3. Hbase记录-Hbase Web管理工具

    1.Hmaster的Web接口-端口参数:hbase.master.info.port  默认为16010 http://hbase_master_server:16010 可查看hbase的版本信息 ...

  4. Jmeter调用 Json接口测试之关键点申明Content-Type类型

    背景: 最近,在做接口测试发现创建运单接口,通过普通表单请求总是失败,开始我以为是后端接口出现问题,但通过前端页面都能创建运单,F12打开浏览器开发者模式,获取该接口请求入参发现,请求的数据格式是js ...

  5. Eclipse中将web项目自动发布到Tomcat webapps下(转)

    A:FileàDynamic Web Project[工程名:test] B:右键WebContent,New-->Jsp File C:右键test,Run AsàRun on Serverà ...

  6. u-boot移植(十三)---代码修改---裁剪及环境变量 一

    一.内核裁剪 内核的裁剪首先就是修改我们的配置文件,即 include/configs/jz2440.h 文件,里面定义的很多宏,我们也许用不上的就要去掉. /* * (C) Copyright 20 ...

  7. Ribbon实现Office开始菜单

    Ribbon实现Office开始菜单 界面效果: 首先:在主窗体上拖入popupMenu控件和imageCollection控件 然后选中popupMenu点击三角,再点击Run Designer在弹 ...

  8. Extmail 批量添加邮箱用户

    Extmail  设置批量添加邮箱用户 需要修改  userctl.pl  文件 修改 userctl.pl 文件 cd /var/www/extsuite/extman/tools 编辑 userc ...

  9. python中enumerate()的用法

    enumerate()函数用于遍历一个可遍历的数据对象(如列表.元组或字符串等)的索引和其对应的元素,一般用于for循环中. enumerate(sequence, [start=0]) sequen ...

  10. luogu P1593 因子和

    不要吐槽博主总做这些数论氵题 首先我们看到这种因数问题,果断质因数分解 所以当前数\(a=p_1^{k_1}*p_2^{k_2}...*p_m^{k_m}\) 可得\(a^b=p_1^{k_1*b}* ...