Android怎样实现仿微信录音功能
发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,这篇文章主要介绍了Android怎样实现仿微信录音功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。实现方法:1.在xml文件中添加
千家信息网最后更新 2024年09月22日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安全错误
数据库的锁怎样保障安全
中文wiki图片数据库
登录王者一直显示服务器未响应
四级网络技术考试
知网怎么根据来源数据库分组浏览
以月份分组查数据库
幼儿网络安全图片简笔画
网络技术便捷高效
北京服务器散热片厂家
苹果软件开发商怎么设置信任
郑州上位机软件开发
csci文献数据库是什么
剑灵 新开的服务器
怎么解决多线程访问数据库
汇盈互联网科技
软件开发人员外包有什么用
怎样连接远程服务器
db2 查看数据库状态6
华为软件开发云招聘
信息发布系统数据库表
软件开发收费标准文件
数据库管理工程师无忧考网
小飞侠网络安全
网络安全 活动
致教职工的网络安全的一封信
昌平区网络营销网络技术一体化
当今社会网络安全现状
网络安全通报制度
网络安全监督举报电话
作业盒子互联网教育科技
智能锁软件开发合同