您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
在安卓中实现麦克风录音并监听音量大小改变麦克风图标音量大小
发布时间:2021-08-24 23:17:58编辑:雪饮阅读()
这次实践是基于一个录音功能上进行扩展ui的展示效果。
那么开始录音如:
public void startRecord() {
pause();
if (mMediaRecorder == null)
mMediaRecorder = new MediaRecorder();
try {
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置麦克风
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
String fileName = DateFormat.format("yyyyMMdd_HHmmss", Calendar.getInstance(Locale.CHINA)) + ".m4a";
File destDir = new File(voice_record_dir);
if (!destDir.exists()) {
destDir.mkdirs();
}
voice_record_filePath = voice_record_dir+File.separator+ fileName;
File file_output=new File(voice_record_filePath);
Uri uri = FileProvider.getUriForFile(this,"com.example.penguinvideoedit.fileprovider",file_output);
//mMediaRecorder.setOutputFile(voice_record_filePath);
mMediaRecorder.setOutputFile(String.valueOf(voice_record_filePath));
mMediaRecorder.prepare();
mMediaRecorder.start();
showVoiceDialog();
setVoiceTimer(mean_voice_start);
} catch (IllegalStateException e) {
Log.i("failed!" , e.getMessage());
} catch (IOException e) {
Log.i("failed!" ,e.getMessage());
}
}
这里有看到两个重要的方法showVoiceDialog和setVoiceTimer
首先来看看showVoiceDialog这个方法:
// 录音时显示Dialog
public void showVoiceDialog() {
if (mRecordDialog == null) {
View vw = getLayoutInflater().inflate(R.layout.activity_audio_replace_dialog_record, null);
mRecordDialog=new VideoHandle.DiyDialog(this, 0, 0, vw, R.style.DialogTheme);
dialogImg = (ImageView) mRecordDialog.findViewById(R.id.record_dialog_img);
dialogImg.setImageResource(R.drawable.record_animate_00);
dialogTextView = (TextView) mRecordDialog.findViewById(R.id.record_dialog_txt);
}
dialogTextView.setText("松开保存");
dialogTextView.setTextSize(14);
mRecordDialog.show();
}
showVoiceDialog方法中的activity_audio_replace_dialog_record布局是那个音频图片即麦克风图片以及提示用户如“松开录音按钮即可录音保存完成”之类的提示。那么其xml如:
layout/activity_audio_replace_dialog_record.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:layout_gravity="center"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
>
<!--
android:background="@drawable/record_bg"
-->
<ImageView
android:id="@+id/record_dialog_img"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
<!--
android:layout_margintop="5dp"
-->
<TextView
android:id="@+id/record_dialog_txt"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:textColor="@android:color/white"/>
</LinearLayout>
那么dialogImg.setImageResource(R.drawable.record_animate_00);在showVoiceDialog方法中是为了设置一个麦克风的默认图片
像是这样,没有说话时候大概是这样,说话之后根据音量不同,这个麦克风中的图片有可能是下面这些
那么接下来还有一个重要的就是
mRecordDialog=new VideoHandle.DiyDialog(this, 0, 0, vw, R.style.DialogTheme);
这个是在showVoiceDialog方法中负责以一个窗口(遮罩)形式打开这个上面这个麦克风和提示用户一些文本的界面的。
这里R.style.DialogTheme参数指向一个对话框的风格,那么在我这里这个风格配置如:
Values/styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DialogTheme" parent="@android:style/Theme.Dialog">
<!-- 边框 -->
<item name="android:windowFrame">@null</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 无标题 -->
<item name="android:windowNoTitle">true</item>
<item name="android:background">@android:color/transparent</item>
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 模糊 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 遮罩层 -->
<item name="android:backgroundDimAmount">0.5</item>
</style>
<!--
<style name="Dialogstyle" type="text/css">
-->
<!--
<style name="Dialogstyle" parent="@android:style/Theme.Dialog">
-->
<style name="Dialogstyle" parent="@android:style/Theme.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<!-- 显示对话框时当前的屏幕是否变暗 -->
<item name="android:backgroundDimEnabled">false</item>
</style>
</resources>
这里有两个风格,这里用的就是第一个风格。
那么这里调用的这个VideoHandle.DiyDialog方法,主要就是实现了自定义dialog的,其实现如:
public static class DiyDialog extends Dialog {
// style引用style样式
public DiyDialog(Context context, int width, int height, View layout, int style) {
super(context, style);
setContentView(layout);
Window window = getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.CENTER;
window.setAttributes(params);
}
}
像是这个实现方法的形参中width和height,我们一般都是给传参为0
那么接下来我们来看看另外的setVoiceTimer方法
public void setVoiceTimer(String voiceStatus){
if(voiceStatus.equals(mean_voice_start)){
if(TT_Voice==null){
TT_Voice=new TimerTask() {
@Override
public void run() {
Message msg=new Message();
msg.obj=mean_voice_start;
handler.sendMessage(msg);
}
};
voice_timer.schedule(TT_Voice,0,300);
}
}
if(voiceStatus.equals(mean_voice_stop)){
TT_Voice.cancel();
TT_Voice=null;
}
}
这个方法我们有两个判断mean_voice_start和mean_voice_stop
这两个分别表示了音频开始录制和音频录制结束,那么这里的目的就是通过传递过来音频是开始录制时候我们就定时器每300毫秒去读取下当前音频的音量大小,如果是录制结束了咱们就停止这个定时器。
那么定时器TT_Voice其实就是一个TimerTask,下面这个是部分的全局变量如:
TimerTask TT;
TimerTask TT_Voice;
Timer voice_timer=new Timer();
private double voiceValue = 0.0; // 录音的音量值
String mean_voice_start="startRecord";
String mean_voice_stop="stopRecord";
那么这里setVoiceTimer我们通过传递过来音频是开始录制时候我们就定时器每300毫秒去读取下当前音频的音量大小是以handler的消息机制来异步操作的
那么这个handler的定义如:
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
String mean=(String)msg.obj;
if(mean.equals("videoProcessToSeekBar")){
int CurrentPosition=videoView.getCurrentPosition();
String currentTime=videoPlayProcessFormatDateTime(CurrentPosition);
Log.i("CurrentPosition", String.valueOf(CurrentPosition));
seekbar.setProgress(CurrentPosition);
seekbar_linearLayout_t1.setText(currentTime);
seekbar_linearLayout_t2.setText(videoPlayProcessFormatDateTime(select_video_duration));
}
if(mean.equals(mean_voice_start)){
if(mMediaRecorder!=null){
voiceValue = mMediaRecorder.getMaxAmplitude();
setDialogImage();
}
}
}
};
可以看到这里又出现了setDialogImage方法:
// 录音Dialog图片随录音音量大小切换
private void setDialogImage() {
Log.i("voiceValue", String.valueOf(voiceValue));
if (voiceValue < 600.0) {
dialogImg.setImageResource(R.drawable.record_animate_01);
} else if (voiceValue > 600.0 && voiceValue < 1000.0) {
dialogImg.setImageResource(R.drawable.record_animate_02);
} else if (voiceValue > 1000.0 && voiceValue < 1200.0) {
dialogImg.setImageResource(R.drawable.record_animate_03);
} else if (voiceValue > 1200.0 && voiceValue < 1400.0) {
dialogImg.setImageResource(R.drawable.record_animate_04);
} else if (voiceValue > 1400.0 && voiceValue < 1600.0) {
dialogImg.setImageResource(R.drawable.record_animate_05);
} else if (voiceValue > 1600.0 && voiceValue < 1800.0) {
dialogImg.setImageResource(R.drawable.record_animate_06);
} else if (voiceValue > 1800.0 && voiceValue < 2000.0) {
dialogImg.setImageResource(R.drawable.record_animate_07);
} else if (voiceValue > 2000.0 && voiceValue < 3000.0) {
dialogImg.setImageResource(R.drawable.record_animate_08);
} else if (voiceValue > 3000.0 && voiceValue < 4000.0) {
dialogImg.setImageResource(R.drawable.record_animate_09);
} else if (voiceValue > 4000.0 && voiceValue < 6000.0) {
dialogImg.setImageResource(R.drawable.record_animate_10);
} else if (voiceValue > 6000.0 && voiceValue < 8000.0) {
dialogImg.setImageResource(R.drawable.record_animate_11);
} else if (voiceValue > 8000.0 && voiceValue < 10000.0) {
dialogImg.setImageResource(R.drawable.record_animate_12);
} else if (voiceValue > 10000.0 && voiceValue < 12000.0) {
dialogImg.setImageResource(R.drawable.record_animate_13);
} else if (voiceValue > 12000.0) {
dialogImg.setImageResource(R.drawable.record_animate_14);
}
}
就是说我用了14张图片对应不同的音量大小等级,以此来蒙混视听(让用户看到不同的音频音量大小效果)。
这里的dialogImg当然是imageView类型了
private ImageView dialogImg;
这样一来,我们的任务算是基本完成了。
最后我们来看看具体的效果
关键字词:安卓,录音,麦克风,音量大小,ui,监听