最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android實(shí)現(xiàn)錄音方法(仿微信語(yǔ)音、麥克風(fēng)錄音、發(fā)送語(yǔ)音、解決5.0以上BUG)

 更新時(shí)間:2018年04月11日 11:21:10   作者:張中文  
大家平時(shí)在使用微信qq聊天時(shí)經(jīng)常會(huì)發(fā)送語(yǔ)音功能,今天小編給大家?guī)?lái)了基于android實(shí)現(xiàn)錄音的方法仿微信語(yǔ)音、麥克風(fēng)錄音、發(fā)送語(yǔ)音、解決5.0以上BUG,需要的朋友參考下吧

先給大家展示下效果圖,如果大家感覺(jué)不錯(cuò),請(qǐng)參考使用方法,

效果圖如下所示:

使用方法:

錄音工具類(lèi):AudioRecoderUtils.java,代碼如下:

public class AudioRecoderUtils {
 //文件路徑
 private String filePath;
 //文件夾路徑
 private String FolderPath;
 private MediaRecorder mMediaRecorder;
 private final String TAG = "fan";
 public static final int MAX_LENGTH = 1000 * 60 * 10;// 最大錄音時(shí)長(zhǎng)1000*60*10;
 private OnAudioStatusUpdateListener audioStatusUpdateListener;
 /**
  * 文件存儲(chǔ)默認(rèn)sdcard/record
  */
 public AudioRecoderUtils(){
  //默認(rèn)保存路徑為/sdcard/record/下
  this(Environment.getExternalStorageDirectory()+"/record/");
 }
 public AudioRecoderUtils(String filePath) {
  File path = new File(filePath);
  if(!path.exists())
   path.mkdirs();
  this.FolderPath = filePath;
 }
 private long startTime;
 private long endTime;
 /**
  * 開(kāi)始錄音 使用amr格式
  *  錄音文件
  * @return
  */
 public void startRecord() {
  // 開(kāi)始錄音
  /* ①I(mǎi)nitial:實(shí)例化MediaRecorder對(duì)象 */
  if (mMediaRecorder == null)
   mMediaRecorder = new MediaRecorder();
  try {
   /* ②setAudioSource/setVedioSource */
   mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 設(shè)置麥克風(fēng)
   /* ②設(shè)置音頻文件的編碼:AAC/AMR_NB/AMR_MB/Default 聲音的(波形)的采樣 */
   mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
   /*
    * ②設(shè)置輸出文件的格式:THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式
    * ,H263視頻/ARM音頻編碼)、MPEG-4、RAW_AMR(只支持音頻且音頻編碼要求為AMR_NB)
    */
   mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
   filePath = FolderPath + TimeUtils.getCurrentTime() + ".amr" ;
   /* ③準(zhǔn)備 */
   mMediaRecorder.setOutputFile(filePath);
   mMediaRecorder.setMaxDuration(MAX_LENGTH);
   mMediaRecorder.prepare();
   /* ④開(kāi)始 */
   mMediaRecorder.start();
   // AudioRecord audioRecord.
   /* 獲取開(kāi)始時(shí)間* */
   startTime = System.currentTimeMillis();
   updateMicStatus();
   Log.e("fan", "startTime" + startTime);
  } catch (IllegalStateException e) {
   Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage());
  } catch (IOException e) {
   Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage());
  }
 }
 /**
  * 停止錄音
  */
 public long stopRecord() {
  if (mMediaRecorder == null)
   return 0L;
  endTime = System.currentTimeMillis();
  //有一些網(wǎng)友反應(yīng)在5.0以上在調(diào)用stop的時(shí)候會(huì)報(bào)錯(cuò),翻閱了一下谷歌文檔發(fā)現(xiàn)上面確實(shí)寫(xiě)的有可能會(huì)報(bào)錯(cuò)的情況,捕獲異常清理一下就行了,感謝大家反饋!
  try {
   mMediaRecorder.stop();
   mMediaRecorder.reset();
   mMediaRecorder.release();
   mMediaRecorder = null;
   audioStatusUpdateListener.onStop(filePath);
   filePath = "";
  }catch (RuntimeException e){
   mMediaRecorder.reset();
   mMediaRecorder.release();
   mMediaRecorder = null;
   File file = new File(filePath);
   if (file.exists())
    file.delete();
   filePath = "";
  }
  return endTime - startTime;
 }
 /**
  * 取消錄音
  */
 public void cancelRecord(){
  try {
   mMediaRecorder.stop();
   mMediaRecorder.reset();
   mMediaRecorder.release();
   mMediaRecorder = null;
  }catch (RuntimeException e){
   mMediaRecorder.reset();
   mMediaRecorder.release();
   mMediaRecorder = null;
  }
  File file = new File(filePath);
  if (file.exists())
   file.delete();
  filePath = "";
 }
 private final Handler mHandler = new Handler();
 private Runnable mUpdateMicStatusTimer = new Runnable() {
  public void run() {
   updateMicStatus();
  }
 };
 private int BASE = 1;
 private int SPACE = 100;// 間隔取樣時(shí)間
 public void setOnAudioStatusUpdateListener(OnAudioStatusUpdateListener audioStatusUpdateListener) {
  this.audioStatusUpdateListener = audioStatusUpdateListener;
 }
 /**
  * 更新麥克狀態(tài)
  */
 private void updateMicStatus() {
  if (mMediaRecorder != null) {
   double ratio = (double)mMediaRecorder.getMaxAmplitude() / BASE;
   double db = 0;// 分貝
   if (ratio > 1) {
    db = 20 * Math.log10(ratio);
    if(null != audioStatusUpdateListener) {
     audioStatusUpdateListener.onUpdate(db,System.currentTimeMillis()-startTime);
    }
   }
   mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
  }
 }
 public interface OnAudioStatusUpdateListener {
  /**
   * 錄音中...
   * @param db 當(dāng)前聲音分貝
   * @param time 錄音時(shí)長(zhǎng)
   */
  public void onUpdate(double db,long time);
  /**
   * 停止錄音
   * @param filePath 保存路徑
   */
  public void onStop(String filePath);
 }
}

使用很簡(jiǎn)單,主要就是開(kāi)始錄音startRecord()、取消錄音cancelRecord()、結(jié)束錄音stopRecord()和錄音監(jiān)聽(tīng)setOnAudioStatusUpdateListener(),注意,取消錄音不保存文件,結(jié)束錄音會(huì)保存文件!

在布局文件中添加一個(gè)控件(任意一個(gè)都行)

<Button
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="按住說(shuō)話(huà)"
 android:textColor="@android:color/white"
 android:id="@+id/button"
 android:background="@color/colorPrimary"
 />

在A(yíng)ctivity中使用:    

//當(dāng)前布局文件的根layout
  final RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl);
  mButton = (Button) findViewById(R.id.button);
  //PopupWindow的布局文件
  final View view = View.inflate(this, R.layout.layout_microphone, null);
  final PopupWindowFactory mPop = new PopupWindowFactory(this,view);
  //PopupWindow布局文件里面的控件
  mImageView = (ImageView) view.findViewById(R.id.iv_recording_icon);
  mTextView = (TextView) view.findViewById(R.id.tv_recording_time);
  mAudioRecoderUtils = new AudioRecoderUtils();
  //錄音回調(diào)
  mAudioRecoderUtils.setOnAudioStatusUpdateListener(new AudioRecoderUtils.OnAudioStatusUpdateListener() {
   //錄音中....db為聲音分貝,time為錄音時(shí)長(zhǎng)
   @Override
   public void onUpdate(double db, long time) {
    //根據(jù)分貝值來(lái)設(shè)置錄音時(shí)話(huà)筒圖標(biāo)的上下波動(dòng),下面有講解
    mImageView.getDrawable().setLevel((int) (3000 + 6000 * db / 100));
    mTextView.setText(TimeUtils.long2String(time));
   }
   //錄音結(jié)束,filePath為保存路徑
   @Override
   public void onStop(String filePath) {
    Toast.makeText(MainActivity.this, "錄音保存在:" + filePath, Toast.LENGTH_SHORT).show();
    mTextView.setText(TimeUtils.long2String(0));
   }
  });
  //Button的touch監(jiān)聽(tīng)
  mButton.setOnTouchListener(new View.OnTouchListener() {
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()){
     case MotionEvent.ACTION_DOWN:
      mPop.showAtLocation(rl,Gravity.CENTER,0,0);
      mButton.setText("松開(kāi)保存");
      mAudioRecoderUtils.startRecord();
      break;
     case MotionEvent.ACTION_UP:
      mAudioRecoderUtils.stopRecord();  //結(jié)束錄音(保存錄音文件)
//      mAudioRecoderUtils.cancelRecord(); //取消錄音(不保存錄音文件)
      mPop.dismiss();
      mButton.setText("按住說(shuō)話(huà)");
      break;
    }
    return true;
   }
  });

總結(jié)

以上所述是小編給大家介紹的Android實(shí)現(xiàn)錄音方法(仿微信語(yǔ)音、麥克風(fēng)錄音、發(fā)送語(yǔ)音、解決5.0以上BUG),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Android去除AlertDialog的按鈕欄的分隔線(xiàn)

    Android去除AlertDialog的按鈕欄的分隔線(xiàn)

    這篇文章主要介紹了Android去除AlertDialog的按鈕欄的分隔線(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • Android自定義折線(xiàn)圖控件的完整步驟

    Android自定義折線(xiàn)圖控件的完整步驟

    折線(xiàn)圖是常用的圖表之一,最近的工作中又遇到了相關(guān)的需求,所以下面這篇文章主要給大家介紹了關(guān)于A(yíng)ndroid自定義折線(xiàn)圖控件的完整步驟,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Android Studio下載、安裝和配置+SDK+tools下載(無(wú)敵超級(jí)詳細(xì)版本)

    Android Studio下載、安裝和配置+SDK+tools下載(無(wú)敵超級(jí)詳細(xì)版本)

    這篇文章主要介紹了Android Studio下載、安裝和配置+SDK+tools下載(無(wú)敵超級(jí)詳細(xì)版本),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • SimpleCommand實(shí)現(xiàn)圖片下載(二)

    SimpleCommand實(shí)現(xiàn)圖片下載(二)

    這篇文章主要為大家詳細(xì)介紹了SimpleCommand實(shí)現(xiàn)圖片下載,并顯示到ImageView控件上,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Android 中 退出多個(gè)activity的經(jīng)典方法

    Android 中 退出多個(gè)activity的經(jīng)典方法

    這篇文章主要介紹了Android 中 退出多個(gè)activity的經(jīng)典方法 的相關(guān)資料,本文給大家分享兩種方法,在這小編給大家推薦使用第一種方法,對(duì)此文感興趣的朋友可以參考下
    2016-09-09
  • android應(yīng)用實(shí)現(xiàn)開(kāi)機(jī)自動(dòng)啟動(dòng)方法

    android應(yīng)用實(shí)現(xiàn)開(kāi)機(jī)自動(dòng)啟動(dòng)方法

    這篇文章主要介紹了android應(yīng)用實(shí)現(xiàn)開(kāi)機(jī)自動(dòng)啟動(dòng)方法,本文講解了原理和編碼實(shí)例,需要的朋友可以參考下
    2015-05-05
  • Android自定義View實(shí)現(xiàn)心形圖案

    Android自定義View實(shí)現(xiàn)心形圖案

    這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)心形圖案,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Android實(shí)現(xiàn)下載m3u8視頻文件問(wèn)題解決

    Android實(shí)現(xiàn)下載m3u8視頻文件問(wèn)題解決

    這篇文章主要介紹了Android實(shí)現(xiàn)下載m3u8視頻文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-01-01
  • Android PopupWindow實(shí)現(xiàn)遮罩層效果

    Android PopupWindow實(shí)現(xiàn)遮罩層效果

    這篇文章主要為大家詳細(xì)介紹了Android PopupWindow實(shí)現(xiàn)遮罩層效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • Android搜索框組件SearchView的基本使用方法

    Android搜索框組件SearchView的基本使用方法

    這篇文章主要為大家詳細(xì)介紹了Android搜索框組件SearchView的基本使用方法,感興趣的小伙伴們可以參考一下
    2016-05-05

最新評(píng)論

珲春市| 平舆县| 株洲市| 灯塔市| 成都市| 台南市| 大方县| 永宁县| 南丰县| 罗田县| 阳春市| 孝义市| 如皋市| 江源县| 兴城市| 灵丘县| 南宫市| 布尔津县| 新干县| 清丰县| 儋州市| 秦皇岛市| 梅河口市| 左权县| 游戏| 克山县| 财经| 忻城县| 庆元县| 河东区| 玉溪市| 息烽县| 丽水市| 桑日县| 新津县| 丰镇市| 北碚区| 新绛县| 卢氏县| 三河市| 治多县|