長按然后就自動崩潰了,代碼也對著視頻看了幾遍,問答區(qū)也經(jīng)常來關(guān)注,就是解決不了我的問題,只能來求老師幫忙了!
package?com.fy.recorder.view; import?java.io.File; import?java.io.IOException; import?java.util.UUID; import?android.media.MediaRecorder; public?class?AudioManager { ???private?MediaRecorder?mMediaRecorder; ???private?String?mDir; ???private?String?mCurrentFilePath; ???private?static?AudioManager?mInstance; ???private?AudioManager(String?dir)? ???{ ???mDir=dir; ???} ? public?interface?AudioStateListener ???{ ???void?wellPrepared(); ???} ???public?AudioStateListener?mListener; ???public?boolean?isPrepared; public?String?getCurrentfilePath() { return?mCurrentFilePath; } ???public?void?setOnAudioStateListener(AudioStateListener?listener) ???{ ???mListener=listener; ???} ???public?static?AudioManager?getInstance(String?dir) ???{ ???if(mInstance==null) ???{ ???synchronized(AudioManager.class) ???{ ???if(mInstance==null) ???mInstance=new?AudioManager(dir); ???} ???} ???return?mInstance; ???} ?? ???public?void?prepareAudio() ???{ ???try{ isPrepared=false; ???File?dir=new?File(mDir); ???if(!dir.exists()) ???dir.mkdirs(); String?fileName=generateFileName(); File?file?=new?File(dir,fileName); mCurrentFilePath=file.getAbsolutePath(); mMediaRecorder=new?MediaRecorder(); //設(shè)置音頻源 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); //設(shè)置音頻格式 mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR); //設(shè)置音頻編碼 mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //設(shè)置輸出文件 mMediaRecorder.setOutputFile(file.getAbsolutePath()); mMediaRecorder.prepare(); mMediaRecorder.start(); isPrepared=true; if(mListener!=null) { mListener.wellPrepared(); } ???}catch(IllegalStateException|IOException?e) ???{ ???e.printStackTrace(); ???} ???} ???private?String?generateFileName()? ??? ???{ return?UUID.randomUUID().toString()+".amr"; } public?int?getVoiceLevel(int?maxLevel) ???{ ??if(isPrepared) ??{ ?try?{ ?//?maxLevel*mMediaRecorder.getMaxAmplitude()?1-32767 ??return?maxLevel*mMediaRecorder.getMaxAmplitude()/32768+1; }?catch?(Exception?e)? { } ??} ??return?1; ???} ???public?void?release() ???{ ???mMediaRecorder.stop(); ???mMediaRecorder.release(); ???mMediaRecorder=null; ???} ???public?void?cancel() ???{ ??? ???release(); ???if(mCurrentFilePath!=null) ???{ ???File?file=new?File(mCurrentFilePath); ???file.delete(); ???mCurrentFilePath=null; ???????} ??? ???} }
然后是Button的
package?com.fy.recorder.view; import?com.fy.recorder.R; import?com.fy.recorder.view.AudioManager.AudioStateListener; import?android.content.Context; import?android.os.Environment; import?android.os.Handler; import?android.util.AttributeSet; import?android.view.MotionEvent; import?android.view.View; import?android.widget.Button; public?class?recorderButton?extends?Button?implements?AudioStateListener?{ private?static?final?int?DISTANCE_Y_CANCEL=50; private?static?final?int?STATE_NORMAL=1; private?static?final?int?STATE_RECORDING=2; private?static?final?int?STATE_WANT_TO_CANCEL=3; private?int?mCurState=STATE_NORMAL; private?boolean?isRecording=false; private?DialogManager?mDialogManager; private?AudioManager?mAudioManager; private?float?mTime=0; // private?boolean?mReady; public?recorderButton(Context?context)?{ this(context,null); } public?recorderButton(Context?context,?AttributeSet?attrs)?{ super(context,?attrs); mDialogManager=new?DialogManager(getContext()); String?dir=Environment.getExternalStorageState()+"/recorder_audios"; mAudioManager=AudioManager.getInstance(dir); mAudioManager.setOnAudioStateListener(this); setOnLongClickListener(new?OnLongClickListener()?{ @Override public?boolean?onLongClick(View?v) { mReady=true; ????mAudioManager.prepareAudio(); return?false; } }); } //回調(diào) public?interface?AudioFinishRecorderListener { void?onFinish(float?seconds,String?filePath); } private?AudioFinishRecorderListener?mListener; public?void?setAudioFinishRecorderListener(AudioFinishRecorderListener?listener) { mListener=listener; } //獲取音量大小 private?Runnable?mGetVOiceLevelRunnable=new?Runnable() { @Override public?void?run() { while(isRecording) { try?{ Thread.sleep(100); mTime+=0.1f; mHandler.sendEmptyMessage(MSG_VOICE_CHANGED); }?catch?(InterruptedException?e) { e.printStackTrace(); } } } }; private?static?final?int?MSG_AUDIO_PREPARED=0X111; private?static?final?int?MSG_VOICE_CHANGED=0X112; private?static?final?int?MSG_DIALOG_DIMSS=0X113; private?Handler?mHandler=new?Handler() { public?void?handleMessage(android.os.Message?msg) { switch?(msg.what)?{ case?MSG_AUDIO_PREPARED: // mDialogManager.showRecordingDialog(); isRecording=true; new?Thread(mGetVOiceLevelRunnable).start(); break; case?MSG_VOICE_CHANGED: mDialogManager.updateVoiceLevel(mAudioManager.getVoiceLevel(7)); break; case?MSG_DIALOG_DIMSS: mDialogManager.dimissDialog(); break; } } }; ? @Override public?void?wellPrepared()? { ???????mHandler.sendEmptyMessage(MSG_AUDIO_PREPARED); } @Override public?boolean?onTouchEvent(MotionEvent?event)?{ int?action=event.getAction(); int?x=(int)event.getX(); int?y=(int)event.getY(); switch(action) { case?MotionEvent.ACTION_DOWN: changeState(STATE_RECORDING); break; case?MotionEvent.ACTION_MOVE: if(isRecording) { if(wangtToCancel(x,y)) { changeState(STATE_WANT_TO_CANCEL); }else{ changeState(STATE_RECORDING); } } break; case?MotionEvent.ACTION_UP: if(!mReady){ reset(); return?super.onTouchEvent(event); } if(isRecording||mTime<0.6f) { mDialogManager.tooShort(); mAudioManager.cancel(); mHandler.sendEmptyMessageDelayed(MSG_DIALOG_DIMSS,?1300); }else?if(mCurState==STATE_RECORDING)//正常錄制結(jié)束 { mDialogManager.dimissDialog(); mAudioManager.release(); if(mListener!=null) { mListener.onFinish(mTime,?mAudioManager.getCurrentfilePath()); } }else?if(mCurState==STATE_WANT_TO_CANCEL) { mDialogManager.dimissDialog(); mAudioManager.cancel(); } reset(); break; } return?super.onTouchEvent(event); } private?void?reset()?{ isRecording=false; mReady=false; mTime=0; changeState(STATE_NORMAL); } private?boolean?wangtToCancel(int?x,?int?y)?{ //?TODO?Auto-generated?method?stub if(x<0||x>getWidth()) { return?true; } if(y<-DISTANCE_Y_CANCEL||y>getHeight()+DISTANCE_Y_CANCEL) { return?true; } return?false; } private?void?changeState(int?state)?{ //?TODO?Auto-generated?method?stub if(mCurState!=state) { mCurState=state; switch?(state)?{ case?STATE_NORMAL: ????????????????setBackgroundResource(R.drawable.btn_recorder_normal); ????????????????setText(R.string.str_recorder_normal); break; ????????????case?STATE_RECORDING: ????????????setBackgroundResource(R.drawable.btn_recording); ????????????????setText(R.string.str_recorder_recording); if(isRecording) { mDialogManager.recording(); } ????????????????break; ????????????case?STATE_WANT_TO_CANCEL: ????????????setBackgroundResource(R.drawable.btn_recording); ????????????????setText(R.string.str_recorder_want_cancel); ??????????mDialogManager.wantToCancel();???????? ??????????break; default: break; } } } }
不知道怎么上傳代碼只能復(fù)制了,謝謝老師??!
2015-05-17
首先感謝你對慕課的支持,我詳細查看了你貼出的代碼,沒有發(fā)現(xiàn)問題。根據(jù)你貼出的異常信息,出錯是因為MediaRecorder的狀態(tài)轉(zhuǎn)移出現(xiàn)的問題,建議你還是根據(jù)log排查下,ps:記得使用真機測試。