Android怎样实现仿微信录音功能
发表于:2024-12-05 作者:千家信息网编辑
千家信息网最后更新 2024年12月05日,这篇文章主要介绍了Android怎样实现仿微信录音功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。实现方法:1.在xml文件中添加
千家信息网最后更新 2024年12月05日Android怎样实现仿微信录音功能
这篇文章主要介绍了Android怎样实现仿微信录音功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
实现方法:
1.在xml文件中添加
2.别忘了申请录音权限
AndPermission.with(MainActivity.this) .permission(Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE) .onGranted(permissions -> { showSelect(); }) .onDenied(permissions -> { Toast.makeText(MainActivity.this,"请同意录音权限",Toast.LENGTH_SHORT).show(); }) .start();private void showSelect() { SoundTextView recordAudio = findViewById(R.id.record_audio); recordAudio.setOnRecordFinishedListener(new SoundTextView.OnRecordFinishedListener() { @Override public void newMessage(String path, int duration) { int index = path.lastIndexOf("/"); String fileName = path.substring(index + 1); Log.e("录音文件", "path=: "+path ); } }); }
使用方法如上非常简单:
主要的类
package ant.muxi.com.audiodemo.view; import android.app.Activity;import android.app.Dialog;import android.content.Context;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.TextView;import android.widget.Toast;import androidx.appcompat.widget.AppCompatTextView;import java.io.File;import ant.muxi.com.audiodemo.R;import ant.muxi.com.audiodemo.audio.ProgressTextUtils;import ant.muxi.com.audiodemo.audio.RecordManager;public class SoundTextView extends AppCompatTextView { private Context mContext; private Dialog recordIndicator; private TextView mVoiceTime; private File file; private String type = "1";//默认开始录音 type=2,录音完毕 RecordManager recordManager; File fileto; int level; private long downT; String sountime; public SoundTextView(Context context) { super(context); init(); } public SoundTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.mContext = context; init(); } public SoundTextView(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; init(); } private void init() { recordIndicator = new Dialog(getContext(), R.style.jmui_record_voice_dialog); recordIndicator.setContentView(R.layout.jmui_dialog_record_voice); mVoiceTime = (TextView) recordIndicator.findViewById(R.id.voice_time); file = new File(Environment.getExternalStorageDirectory() + "/recoder.amr"); fileto = new File(Environment.getExternalStorageDirectory() + "/recoder.mp3"); recordManager = new RecordManager( (Activity) mContext, String.valueOf(file), String.valueOf(fileto)); recordManager.setOnAudioStatusUpdateListener(new RecordManager.OnAudioStatusUpdateListener() { @Override public void onUpdate(double db) { //得到分贝 if (null != recordIndicator) { level = (int) db; handler.sendEmptyMessage(0x111); } } }); } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0x111: sountime = ProgressTextUtils.getSecsProgress(System.currentTimeMillis() - downT); long time = System.currentTimeMillis() - downT; mVoiceTime.setText(ProgressTextUtils.getProgressText(time)); //判断时间 judetime(Integer.parseInt(sountime)); break; } } }; public void judetime(int time) { if (time > 14) { //结束录制 Toast.makeText(mContext, "录音不能超过十五秒", Toast.LENGTH_SHORT).show(); recordManager.stop_mp3(); new Thread() { @Override public void run() { super.run(); recordManager.saveData(); finishRecord(fileto.getPath(), sountime); } }.start(); recordIndicator.dismiss(); type = "2"; } } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: if (type.equals("1")) { //开始发送时间 downT = System.currentTimeMillis(); recordManager.start_mp3(); recordIndicator.show(); } else { Log.e("-log-", "您已经录制完毕: "); } return true; case MotionEvent.ACTION_UP: if (type.equals("1")) { try { if (Integer.parseInt(sountime) > 2) { recordManager.stop_mp3(); new Thread() { @Override public void run() { super.run(); recordManager.saveData(); finishRecord(fileto.getPath(), sountime); } }.start(); if (recordIndicator.isShowing()) { recordIndicator.dismiss(); } type = "2"; } else { recordManager.stop_mp3(); if (recordIndicator.isShowing()) { recordIndicator.dismiss(); } sountime = null; Toast.makeText(mContext, "录音时间少于3秒,请重新录制", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { recordManager.stop_mp3(); if (recordIndicator.isShowing()) { recordIndicator.dismiss(); } sountime = null; Toast.makeText(mContext, "录音时间少于3秒,请重新录制", Toast.LENGTH_SHORT).show(); } } break; case MotionEvent.ACTION_CANCEL: if (recordIndicator.isShowing()) { recordIndicator.dismiss(); } break; } return super.onTouchEvent(event); } //录音完毕加载 ListView item private void finishRecord(String path, String time) { if (onRecordFinishedListener != null) { onRecordFinishedListener.newMessage(path, Integer.parseInt(time)); type = "1"; } //发送语音 // Toasts.toast(getContext(),"您已经录完了一条语音"+myRecAudioFile); } private OnRecordFinishedListener onRecordFinishedListener; public void setOnRecordFinishedListener(OnRecordFinishedListener onRecordFinishedListener) { this.onRecordFinishedListener = onRecordFinishedListener; } public interface OnRecordFinishedListener { void newMessage(String path, int duration); }}
主要的录音管理类
public class RecordManager { //录制成MP3格式.............................................. /**构造时候需要的Activity,主要用于获取文件夹的路径*/ private Activity activity; /**文件代号*/ public static final int RAW = 0X00000001; public static final int MP3 = 0X00000002; /**文件路径*/ private String rawPath = null; private String mp3Path = null; /**采样频率*/ private static final int SAMPLE_RATE = 11025; /**录音需要的一些变量*/ private short[] mBuffer; private AudioRecord mRecorder; /**录音状态*/ private boolean isRecording = false; /**是否转换ok*/ private boolean convertOk = false; public RecordManager(Activity activity, String rawPath, String mp3Path) { this.activity = activity; this.rawPath = rawPath; this.mp3Path = mp3Path; } /**开始录音*/ public boolean start_mp3() { // 如果正在录音,则返回 if (isRecording) { return isRecording; } // 初始化 if (mRecorder == null) { initRecorder(); } getFilePath(); mRecorder.startRecording(); startBufferedWrite(new File(rawPath)); isRecording = true; return isRecording; } /**停止录音,并且转换文件,这很可能是个耗时操作,建议在后台中做*/ public boolean stop_mp3() { if (!isRecording) { return isRecording; } // 停止 mRecorder.stop(); isRecording = false;//TODO // 开始转换(转换代码就这两句)// FLameUtils lameUtils = new FLameUtils(1, SAMPLE_RATE, 96);// convertOk = lameUtils.raw2mp3(rawPath, mp3Path);// return isRecording ^ convertOk;// convertOk==true,return true return isRecording; } public void saveData(){ FLameUtils lameUtils = new FLameUtils(1, SAMPLE_RATE, 96); convertOk = lameUtils.raw2mp3(rawPath, mp3Path); } /**获取文件的路径*/ public String getFilePath(int fileAlias) { if (fileAlias == RAW) { return rawPath; } else if (fileAlias == MP3) { return mp3Path; } else return null; } /**清理文件*/ public void cleanFile(int cleanFlag) { File f = null; try { switch (cleanFlag) { case MP3: f = new File(mp3Path); if (f.exists()) f.delete(); break; case RAW: f = new File(rawPath); if (f.exists()) f.delete(); break; case RAW | MP3: f = new File(rawPath); if (f.exists()) f.delete(); f = new File(mp3Path); if (f.exists()) f.delete(); break; } f = null; } catch (Exception e) { e.printStackTrace(); } } /**关闭,可以先调用cleanFile来清理文件*/ public void close() { if (mRecorder != null) mRecorder.release(); activity = null; } /**初始化*/ private void initRecorder() { int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); mBuffer = new short[bufferSize]; mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); } /**设置路径,第一个为raw文件,第二个为mp3文件*/ private void getFilePath() { try { String folder = "audio_recorder_2_mp3"; String fileName = String.valueOf(System.currentTimeMillis()); if (rawPath == null) { File raw = new File(activity.getDir(folder, activity.MODE_PRIVATE), fileName + ".raw"); raw.createNewFile(); rawPath = raw.getAbsolutePath(); raw = null; } if (mp3Path == null) { File mp3 = new File(activity.getDir(folder, activity.MODE_PRIVATE), fileName + ".mp3"); mp3.createNewFile(); mp3Path = mp3.getAbsolutePath(); mp3 = null; } Log.d("rawPath", rawPath); Log.d("mp3Path", mp3Path); } catch (Exception e) { e.printStackTrace(); } } /**执行cmd命令,并等待结果*/ private boolean runCommand(String command) { boolean ret = false; Process process = null; try { process = Runtime.getRuntime().exec(command); process.waitFor(); ret = true; } catch (Exception e) { e.printStackTrace(); } finally { try { process.destroy(); } catch (Exception e) { e.printStackTrace(); } } return ret; } /**写入到raw文件*/ private void startBufferedWrite(final File file) { Object mLock = new Object(); new Thread(new Runnable() { @Override public void run() { DataOutputStream output = null; try { output = new DataOutputStream(new BufferedOutputStream( new FileOutputStream(file))); while (isRecording) {//开始录制 int readSize = mRecorder.read(mBuffer, 0, mBuffer.length);//是实际读取的数据长度 for (int i = 0; i < readSize; i++) { output.writeShort(mBuffer[i]); } long v = 0; // 将 buffer 内容取出,进行平方和运算 for (int i = 0; i < mBuffer.length; i++) { v += mBuffer[i] * mBuffer[i]; } // 平方和除以数据总长度,得到音量大小。 double mean = v / (double) readSize; double volume = 10 * Math.log10(mean); synchronized (mLock) { try { if(null != audioStatusUpdateListener) { audioStatusUpdateListener.onUpdate(volume); } mLock.wait(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } catch (IOException e) { e.printStackTrace(); } finally { if (output != null) { try { output.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { output.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }).start(); } public RecordManager.OnAudioStatusUpdateListener audioStatusUpdateListener; public void setOnAudioStatusUpdateListener(RecordManager.OnAudioStatusUpdateListener audioStatusUpdateListener) { this.audioStatusUpdateListener = audioStatusUpdateListener; } public interface OnAudioStatusUpdateListener { public void onUpdate(double db); }}
感谢你能够认真阅读完这篇文章,希望小编分享的"Android怎样实现仿微信录音功能"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!
文件
时间
篇文章
路径
功能
平方和
数据
方法
权限
语音
长度
代号
代码
价值
使用方法
兴趣
内容
变量
同时
后台
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库中表明可以是中文吗
网络安全科普竞赛
软件开发过程输出文档
高光谱数据库matlab
江西好的软件开发材料
easyui+数据库连接
不是信息网络技术发展
网络技术开票项目
世善源互联网科技云南有限公司
农业银行数据库系统
网络安全报告大厅利润排行
大同软件开发公司招聘
魔兽世界TBC维希度斯服务器
互联网科技媒体排名
六零数据库冲破牢笼任务
手机软件开发培训报名入口
在大地保险软件开发
平板代理服务器怎么设置
catia v6数据库
游戏辅助服务器
应用软件开发公司简介
腾讯云服务器ip映射本地电脑
跨越速运网络安全工程师面试
美国网络技术大学
阿里云数据库怎么实现字段递增
上海一站式软件开发来电咨询
山西点音网络技术有限责任公司
浦东新区信息软件开发价钱
网络安全人才需求武汉
软件开发兼职郑州