千家信息网

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怎样实现仿微信录音功能"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

0