Android进阶——声波振幅显示
最近博主想做一个app,中间有一个是录音的功能。于是博主想把UI做的好看一些,想仿照微信或者QQ语音输入时,能够随着声音的大小显示声波振幅。于是查找了一些资料,现在把这个功能的Demo分享给大家,以后也会把更多的项目学习到的知识分享给大家。
其实这个功能主要是依靠MediaRecorder的getMaxAmplitude()方法来获得声音的振幅,然后依据计算公式分贝的计算公式K=20lg(Vo/Vi) Vo当前的振幅值,Vi基准值为600来获得分贝数然后在根据分贝来显示ImageView上的不同图片。这样就实现了声波振幅显示了。
下面列出主要的函数,后面会给出录音显示声波振幅的Demo下载链接:
public RecordDialog(Context context){
this.context=context;
dialog_view=LayoutInflater.from(context).inflate(R.layout.dialog_sound, null);
//初始化振幅图片
progressImg[0]=context.getResources().getDrawable(R.drawable.mic_1);
progressImg[1]=context.getResources().getDrawable(R.drawable.mic_2);
progressImg[2]=context.getResources().getDrawable(R.drawable.mic_3);
progressImg[3]=context.getResources().getDrawable(R.drawable.mic_4);
progressImg[4]=context.getResources().getDrawable(R.drawable.mic_5);
progressImg[5]=context.getResources().getDrawable(R.drawable.mic_6);
progressImg[6]=context.getResources().getDrawable(R.drawable.mic_7);
dialog=new AlertDialog.Builder(context).setView(dialog_view).show();
// dialog.cancel();
progress=(ImageView) dialog_view.findViewById(R.id.sound_progress);
btn_cancel=(ImageView) dialog_view.findViewById(R.id.cancel);
btn_submit=(TextView) dialog_view.findViewById(R.id.submit);
mic_icon=(ImageView) dialog.findViewById(R.id.mic);
dialog_title=(TextView) dialog.findViewById(R.id.title);
txt_msg=(TextView) dialog.findViewById(R.id.msg);
btn_cancel.setOnClickListener(onCancel);
btn_submit.setOnClickListener(onSubmit);
}
然后我们实现一个自定义的接口SoundAmplitudeListen用来处理获取分贝值之后显示不同的波动图片:
private SoundAmplitudeListen onSoundAmplitudeListen=new SoundAmplitudeListen() {
@SuppressWarnings("deprecation")
@Override
public void amplitude(int amplitude, int db, int value) {
// TODO Auto-generated method stub
if(value>=6){
value=6;
}
progress.setBackgroundDrawable(progressImg[value]);
}
};
最后就是录音时处理分贝的RecodeManager类了:
package com.example.voiceviewdemo; import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Locale; import android.R.integer;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Handler;
import android.text.format.DateFormat; public class RecodeManager { private File file;//录音文件
private MediaRecorder mediaRecorder;//android 媒体录音类
private SoundAmplitudeListen soundAmplitudeListen;//声波振幅监听器
private final Handler mHandler=new Handler();
private Runnable mUpdateMicStatusTimer=new Runnable() {
/**
* 分贝的计算公式K=20lg(Vo/Vi) Vo当前的振幅值,Vi基准值为600
*/
private int BASE=500;
private int RATIO=5;
private int postDelayed=200;
@Override
public void run() {
int ratio=mediaRecorder.getMaxAmplitude()/BASE;
int db=(int)(20*Math.log10(Math.abs(ratio)));
int value=db/RATIO;
if(value<0) value=0;
if(soundAmplitudeListen!=null){
soundAmplitudeListen.amplitude(ratio, db, value);
mHandler.postDelayed(mUpdateMicStatusTimer,postDelayed);
}
}
}; public void startRecordCreateFile() throws IOException{
if(!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)){
return ;
}
file=new File(Environment.getExternalStorageDirectory()+File.separator+"1"+File.separator+
new DateFormat().format("yyyyMMdd_HHmmss", Calendar.getInstance(Locale.CHINA))+".amr");
mediaRecorder=new MediaRecorder();//创建录音对象
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);//从麦克风源进行录音
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//设置输出格式
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);//设置编码格式
mediaRecorder.setOutputFile(file.getAbsolutePath()); //创建文件
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
file.createNewFile();
mediaRecorder.prepare();
mediaRecorder.start();
mHandler.post(mUpdateMicStatusTimer);
} public File stopRecord(){
if(mediaRecorder!=null){
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder=null;
mHandler.removeCallbacks(mUpdateMicStatusTimer);
}
return file;
}
public void setSoundAmplitudeListen(SoundAmplitudeListen soundAmplitudeListen){
this.soundAmplitudeListen=soundAmplitudeListen;
}
public interface SoundAmplitudeListen{
public void amplitude(int amplitude,int db,int value);
}
}
效果如下:
Demo 资源: http://download.csdn.net/detail/u014132820/9369346
下面给出博主自己开发的一些小App,分享给大家:
Android进阶——声波振幅显示的更多相关文章
- 我的Android进阶之旅------> Android在TextView中显示图片方法
面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包括图像的文本信息).并简要说明实现方法. 答案:Android SDK支持例如以下显示富文本信息的方式. 1.使用T ...
- 我的Android进阶之旅------> Android为TextView组件中显示的文本添加背景色
通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...
- 我的Android进阶之旅------> Android在TextView中显示图片方法
面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包含图像的文本信息),并简要说明实现方法. 答案:Android SDK支持如下显示富文本信息的方式. 1.使用Tex ...
- 我的Android进阶之旅------> Android为TextView组件中显示的文本加入背景色
通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...
- 我的Android进阶之旅------> Android为TextView组件中显示的文本加入背景色
通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...
- Android 进阶 Android 中的 IOC 框架 【ViewInject】 (下)
上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...
- Android开发面试经——4.常见Android进阶笔试题(更新中...)
Android开发(29) 版权声明:本文为寻梦-finddreams原创文章,请关注:http://blog.csdn.net/finddreams 关注finddreams博客:http:/ ...
- [置顶] 我的Android进阶之旅------>介绍一款集录制与剪辑为一体的屏幕GIF 动画制作工具 GifCam
由于上一篇文章:我的Android进阶之旅------>Android之动画之Frame Animation实例 中展示的是Frame动画效果,但是之前我是将图片截取下来,不好说明确切的动画过程 ...
- 我的Android进阶之旅------>经典的大牛博客推荐(排名不分先后)!!
本文来自:http://blog.csdn.net/ouyang_peng/article/details/11358405 今天看到一篇文章,收藏了很多大牛的博客,在这里分享一下 谦虚的天下 柳志超 ...
随机推荐
- 关于ANSI 和 Unicode
关于ANSI和Unicode 1.ANSI American National Standards Institute(美国国家标准学会),ANSI编码不是一种具体的编码方式,而是一种指定在某些环境下 ...
- Serach
1.二分查找 public class BubbleSort { public static int binarySerach(int[] a,int value){ int low=0; int h ...
- POJ3666-Making the Grade(左偏树 or DP)
左偏树 炒鸡棒的论文<左偏树的特点及其应用> 虽然题目要求比论文多了一个条件,但是……只需要求非递减就可以AC……数据好弱…… 虽然还没想明白为什么,但是应该觉得应该是这样——求非递减用大 ...
- 软件开发中的单一职责(转至INFOQ)
最近在实践微服务化过程中,对其“单一职责”原则深有体会.那么只有微服务化才可以单一职责,才可以解耦吗?答案是否定的. 单一职责原则是这样定义的:单一的功能,并且完全封装起来. 我们做后端Java开发的 ...
- [C语言 - 12] Union联合
union Student { int age; char *name; } stu; union只按照最长的数据成员分配控件,适用于有N个数据不会同时出现的情况,用以压缩空间.
- Objective-C中的Block(闭包) (轉載)
来源: 伯乐在线 - 青玉伏案 链接:http://ios.jobbole.com/83229/ 学习OC有接触到一个新词Block(个人感觉又是一个牛气冲天的词),但不是新的概念,不是新的东西.学过 ...
- 【转】Netty那点事(二)Netty中的buffer
[原文]https://github.com/code4craft/netty-learning/blob/master/posts/ch2-buffer.md 上一篇文章我们概要介绍了Netty的原 ...
- ASP.NET线程与异步
什么是线程? 线程简单来说就是一种数据结构,用来管理这个程序的执行状态,其中包括 1.线程核心对象->寄存器的状态 2.线程环境块,是一块用户模式下的内存,包含线程的异常处理链的头部.线程的局部 ...
- Struts的类型转换
struts中jsp提交的数据,struts会自动转换为action中的属性类型: 对于基本的数据类型以及日期类型会自动转换: 就像前面那一篇博客的代码封装一样,会把字符串类型传过来的数据转化为相应的 ...
- hadoop安装详解
1.hadoop简介 Hadoop是Apache软件基金会旗下的一个开源分布式计算平台.以Hadoop分布式文件系统(HDFS,Hadoop Distributed Filesystem)和MapRe ...