中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用Android仿微信語音對講錄音功能

發布時間:2021-09-27 11:42:51 來源:億速云 閱讀:142 作者:小新 欄目:編程語言

這篇文章主要介紹如何使用Android仿微信語音對講錄音功能,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

實現思路:

1.在微信中我們可以看到實現語音對講的是通過點按按鈕來完成的,因此在這里我選擇重新自己的控件使其繼承自Button并重寫onTouchEvent方法,來實現對錄音的判斷。

2.在onTouchEvent方法中,

當我們按下按鈕時,首先顯示錄音的對話框,然后調用錄音準備方法并開始錄音,接著開啟一個計時線程,每隔0.1秒的時間獲取一次錄音音量的大小,并通過Handler根據音量大小更新Dialog中的顯示圖片;

當我們移動手指時,若手指向上移動距離大于50,在Dialog中顯示松開手指取消錄音的提示,并將isCanceled變量(表示我們最后是否取消了錄音)置為true,上移動距離小于20時,我們恢復Dialog的圖片,并將isCanceled置為false; 當抬起手指時,我們首先關閉錄音對話框,接著調用錄音停止方法并關閉計時線程,然后我們判斷是否取消錄音,若是的話則刪除錄音文件,否則判斷計時時間是否太短,最后調用回調接口中的recordEnd方法。

3.在這里為了適應不同的錄音需求,我使用了策略模式來進行處理,將每一個不同的錄音方法視為一種不同的策略,根據自己的需要去改寫。

注意問題

1.在onTouchEvent的返回值中應該返回true,這樣才能屏蔽之后其他的觸摸事件,否則當手指滑動離開Button之后將不能在響應我們的觸摸方法。 2.不要忘記為自己的App添加權限:

<uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

代碼參考

RecordButton 類,我們的自定義控件,重新復寫了onTouchEvent方法

package com.example.recordtest;import android.annotation.SuppressLint;import android.app.Dialog;import android.content.Context;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.Gravity;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;public class RecordButton extends Button {  private static final int MIN_RECORD_TIME = 1; // 最短錄音時間,單位秒  private static final int RECORD_OFF = 0; // 不在錄音  private static final int RECORD_ON = 1; // 正在錄音  private Dialog mRecordDialog;  private RecordStrategy mAudioRecorder;  private Thread mRecordThread;  private RecordListener listener;  private int recordState = 0; // 錄音狀態  private float recodeTime = 0.0f; // 錄音時長,如果錄音時間太短則錄音失敗  private double voiceValue = 0.0; // 錄音的音量值  private boolean isCanceled = false; // 是否取消錄音  private float downY;  private TextView dialogTextView;  private ImageView dialogImg;  private Context mContext;  public RecordButton(Context context) {    super(context);    // TODO Auto-generated constructor stub    init(context);  }  public RecordButton(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);    // TODO Auto-generated constructor stub    init(context);  }  public RecordButton(Context context, AttributeSet attrs) {    super(context, attrs);    // TODO Auto-generated constructor stub    init(context);  }  private void init(Context context) {    mContext = context;    this.setText("按住 說話");  }  public void setAudioRecord(RecordStrategy record) {    this.mAudioRecorder = record;  }  public void setRecordListener(RecordListener listener) {    this.listener = listener;  }  // 錄音時顯示Dialog  private void showVoiceDialog(int flag) {    if (mRecordDialog == null) {      mRecordDialog = new Dialog(mContext, R.style.Dialogstyle);      mRecordDialog.setContentView(R.layout.dialog_record);      dialogImg = (ImageView) mRecordDialog          .findViewById(R.id.record_dialog_img);      dialogTextView = (TextView) mRecordDialog          .findViewById(R.id.record_dialog_txt);    }    switch (flag) {    case 1:      dialogImg.setImageResource(R.drawable.record_cancel);      dialogTextView.setText("松開手指可取消錄音");      this.setText("松開手指 取消錄音");      break;    default:      dialogImg.setImageResource(R.drawable.record_animate_01);      dialogTextView.setText("向上滑動可取消錄音");      this.setText("松開手指 完成錄音");      break;    }    dialogTextView.setTextSize(14);    mRecordDialog.show();  }  // 錄音時間太短時Toast顯示  private void showWarnToast(String toastText) {    Toast toast = new Toast(mContext);    View warnView = LayoutInflater.from(mContext).inflate(        R.layout.toast_warn, null);    toast.setView(warnView);    toast.setGravity(Gravity.CENTER, 0, 0);// 起點位置為中間    toast.show();  }  // 開啟錄音計時線程  private void callRecordTimeThread() {    mRecordThread = new Thread(recordThread);    mRecordThread.start();  }  // 錄音Dialog圖片隨錄音音量大小切換  private void setDialogImage() {    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);    }  }  // 錄音線程  private Runnable recordThread = new Runnable() {    @Override    public void run() {      recodeTime = 0.0f;      while (recordState == RECORD_ON) {        {          try {            Thread.sleep(100);            recodeTime += 0.1;            // 獲取音量,更新dialog            if (!isCanceled) {              voiceValue = mAudioRecorder.getAmplitude();              recordHandler.sendEmptyMessage(1);            }          } catch (InterruptedException e) {            e.printStackTrace();          }        }      }    }  };  @SuppressLint("HandlerLeak")  private Handler recordHandler = new Handler() {    @Override    public void handleMessage(Message msg) {      setDialogImage();    }  };  @Override  public boolean onTouchEvent(MotionEvent event) {    // TODO Auto-generated method stub    switch (event.getAction()) {    case MotionEvent.ACTION_DOWN: // 按下按鈕      if (recordState != RECORD_ON) {        showVoiceDialog(0);        downY = event.getY();        if (mAudioRecorder != null) {          mAudioRecorder.ready();          recordState = RECORD_ON;          mAudioRecorder.start();          callRecordTimeThread();        }      }      break;    case MotionEvent.ACTION_MOVE: // 滑動手指      float moveY = event.getY();      if (downY - moveY > 50) {        isCanceled = true;        showVoiceDialog(1);      }      if (downY - moveY < 20) {        isCanceled = false;        showVoiceDialog(0);      }      break;    case MotionEvent.ACTION_UP: // 松開手指      if (recordState == RECORD_ON) {        recordState = RECORD_OFF;        if (mRecordDialog.isShowing()) {          mRecordDialog.dismiss();        }        mAudioRecorder.stop();        mRecordThread.interrupt();        voiceValue = 0.0;        if (isCanceled) {          mAudioRecorder.deleteOldFile();        } else {          if (recodeTime < MIN_RECORD_TIME) {            showWarnToast("時間太短 錄音失敗");            mAudioRecorder.deleteOldFile();          } else {            if (listener != null) {              listener.recordEnd(mAudioRecorder.getFilePath());            }          }        }        isCanceled = false;        this.setText("按住 說話");      }      break;    }    return true;  }  public interface RecordListener {    public void recordEnd(String filePath);  }}

Dialog布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="vertical"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_gravity="center"  android:gravity="center"  android:background="@drawable/record_bg"  android:padding="20dp" >  <ImageView    android:id="@+id/record_dialog_img"    android:layout_width="wrap_content"    android:layout_height="wrap_content" />  <TextView    android:id="@+id/record_dialog_txt"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:textColor="@android:color/white"    android:layout_marginTop="5dp" /></LinearLayout>

錄音時間太短的Toast布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:background="@drawable/record_bg"  android:padding="20dp"  android:gravity="center"  android:orientation="vertical" >  <ImageView    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/voice_to_short" />  <TextView    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:textColor="@android:color/white"    android:textSize="15sp"    android:text="時間太短 錄音失敗" /></LinearLayout>

自定義的Dialogstyle,對話框樣式

<style name="Dialogstyle">    <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>

RecordStrategy 錄音策略接口

package com.example.recordtest;/** * RecordStrategy 錄音策略接口 * @author acer */public interface RecordStrategy {  /**   * 在這里進行錄音準備工作,重置錄音文件名等   */  public void ready();  /**   * 開始錄音   */  public void start();  /**   * 錄音結束   */  public void stop();  /**   * 錄音失敗時刪除原來的舊文件   */  public void deleteOldFile();  /**   * 獲取錄音音量的大小   * @return   */  public double getAmplitude();  /**   * 返回錄音文件完整路徑   * @return   */  public String getFilePath();}

個人寫的一個錄音實踐策略

package com.example.recordtest;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import android.media.MediaRecorder;import android.os.Environment;public class AudioRecorder implements RecordStrategy {  private MediaRecorder recorder;  private String fileName;  private String fileFolder = Environment.getExternalStorageDirectory()      .getPath() + "/TestRecord";  private boolean isRecording = false;  @Override  public void ready() {    // TODO Auto-generated method stub    File file = new File(fileFolder);    if (!file.exists()) {      file.mkdir();    }    fileName = getCurrentDate();    recorder = new MediaRecorder();    recorder.setOutputFile(fileFolder + "/" + fileName + ".amr");    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 設置MediaRecorder的音頻源為麥克風    recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);// 設置MediaRecorder錄制的音頻格式    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 設置MediaRecorder錄制音頻的編碼為amr  }  // 以當前時間作為文件名  private String getCurrentDate() {    SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HHmmss");    Date curDate = new Date(System.currentTimeMillis());// 獲取當前時間    String str = formatter.format(curDate);    return str;  }  @Override  public void start() {    // TODO Auto-generated method stub    if (!isRecording) {      try {        recorder.prepare();        recorder.start();      } catch (IllegalStateException e) {        // TODO Auto-generated catch block        e.printStackTrace();      } catch (IOException e) {        // TODO Auto-generated catch block        e.printStackTrace();      }      isRecording = true;    }  }  @Override  public void stop() {    // TODO Auto-generated method stub    if (isRecording) {      recorder.stop();      recorder.release();      isRecording = false;    }  }  @Override  public void deleteOldFile() {    // TODO Auto-generated method stub    File file = new File(fileFolder + "/" + fileName + ".amr");    file.deleteOnExit();  }  @Override  public double getAmplitude() {    // TODO Auto-generated method stub    if (!isRecording) {      return 0;    }    return recorder.getMaxAmplitude();  }  @Override  public String getFilePath() {    // TODO Auto-generated method stub    return fileFolder + "/" + fileName + ".amr";  }}

MainActivity

package com.example.recordtest;import android.os.Bundle;import android.app.Activity;import android.view.Menu;public class MainActivity extends Activity {  RecordButton button;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    button = (RecordButton) findViewById(R.id.btn_record);    button.setAudioRecord(new AudioRecorder());  }  @Override  public boolean onCreateOptionsMenu(Menu menu) {    // Inflate the menu; this adds items to the action bar if it is present.    getMenuInflater().inflate(R.menu.main, menu);    return true;  }}

以上是“如何使用Android仿微信語音對講錄音功能”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

荔波县| 那坡县| 郎溪县| 六枝特区| 灌阳县| 黄浦区| 北安市| 泉州市| 岢岚县| 雅江县| 贵德县| 海伦市| 齐齐哈尔市| 拉孜县| 深州市| 清徐县| 长丰县| 布拖县| 呼伦贝尔市| 连云港市| 勃利县| 辉县市| 灵璧县| 本溪市| 磐安县| 大名县| 福海县| 普安县| 雷山县| 南乐县| 手游| 内江市| 阜宁县| 西畴县| 鄄城县| 湘潭市| 吴堡县| 滦南县| 江门市| 平南县| 曲周县|