@hyman 還是空指針的問題
我認真的排查過,mMediaRECORDER只有release()里置空過
package?com.imoc_recorder.view; ? import?java.io.File; import?java.io.IOException; import?java.util.UUID; ? import?android.R.integer; import?android.media.MediaRecorder; import?android.util.Log; ? public?class?AudioManager?{ ????? ????private?MediaRecorder?mMediaRecorder; ????private?String?mDir; ????private?String?mCurrentFilePath; ????private?boolean?isPrepared; ????? ????private?static?AudioManager?mInstance; ????private?AudioManager(String?dir){ ????????mDir?=?dir; ????} ????/* ?????*?回調準備完畢 ?????*/ ????public??interface?AudioStateListener?{ ????????void?wellPrepared(); ????} ????? ????public?AudioStateListener?mListener; ????? ????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(); ????????????????//設置輸出文件 ????????????????mMediaRecorder.setOutputFile(file.getAbsolutePath()); ????????????????//設置MediaRecorder的音頻源為麥克風 ????????????????mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); ????????????????//設置音頻的格式 ????????????????mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR); ????????????????//設置音頻編碼為amr ????????????????mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); ????????????????mMediaRecorder.prepare(); ????????????????mMediaRecorder.start(); ????????????????isPrepared?=?true; ????? ????????????????if?(mListener?!=?null)?{ ????????????????????mListener.wellPrepared(); ????????????????} ????????????} ????????}?catch?(Exception?e)?{ ????????????? ????????????e.printStackTrace(); ????????} ????} ????//隨機生成文件名 ????private?String?generateFileName()?{ ????????return?UUID.randomUUID().toString()+".amr"; ????} ? ????public?int?getVoiceLevel(int?maxLevel)?{ ????????if(isPrepared) ????????{ ????????????try?{ ????????????????return?maxLevel*mMediaRecorder.getMaxAmplitude()/32768+1;?//音頻的最大振幅1!32767~1 ????????????}?catch?(Exception?e)?{ ????????????? ????????????????e.printStackTrace(); ????????????} ????????} ????????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; ????????} ????} ????public?String?getCurrentFilePath()?{ ????????return?mCurrentFilePath; ????} ? ????? }
2015-05-13
那怎么會空呢~~記得拿真機測試~~
2015-07-10
我這邊也是報setAudioFinishRecorderListener空指針
2015-05-13
我就是在真機測試的有這個錯誤,換了虛擬機測試了還是同樣的錯誤?????
import com.example.imoc_recorder.R;
import com.imoc_recorder.view.AudioManager.AudioStateListener;
import android.R.integer;
import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
public class AudioRecorderButton extends Button implements AudioStateListener {
?? ?
?? ?private final int DISTANCE_Y_CANCEL = 50; //y方向的移動距離
?? ?private static final int STATE_NORNMAL =1;
?? ?private static final int STATE_RECORDING =2;
?? ?private static final int STATE_WANT_TO_CANCEL =3;
?? ?
?? ?private int mCurState = STATE_NORNMAL;
?? ?private boolean isRecording=false; //已經開始錄音
?? ?
?? ?private DailogManager mDailogManager;
?? ?
?? ?private AudioManager mAudioManager;
?? ?
?? ?private float mTime=0;
?? ?//是否觸發longclick
?? ?private boolean mReady;
?? ?
?? ?public AudioRecorderButton(Context context) {
?? ??? ?this(context,null);
?? ?}
?? ?public AudioRecorderButton(Context context, AttributeSet attrs) {
?? ??? ?super(context, attrs);
?? ??? ?
?? ??? ?mDailogManager = new DailogManager(getContext());
?? ??? ?setOnLongClickListener(new OnLongClickListener() {
?? ??? ??? ?
?? ??? ??? ?@Override
?? ??? ??? ?public boolean onLongClick(View v) {
?? ??? ??? ??? ?mReady = true;
?? ??? ??? ??? ?mAudioManager.prepareAudio();
?? ??? ??? ??? ?return false;
?? ??? ??? ?}
?? ??? ?});
?? ??? ?
?? ??? ?String dir = Environment.getExternalStorageDirectory()+"/imooc_recorder_audios";
?? ??? ?mAudioManager = AudioManager.getInstance(dir);
?? ??? ?mAudioManager.setOnAudioStateListener(this); //注冊回調
?? ??? ??? ??? ?
?? ??? ??? ?}
?? ?
?? ?//錄音完成后的回調
?? ?public interface AudioFinishRecorderListener {
?? ??? ?void onFinished(float seconds,String filePath);
?? ?}
?? ?
?? ?private AudioFinishRecorderListener mListener;
?? ?
?? ?public void setAudioFinishRecorderListener(AudioFinishRecorderListener listener) {
?? ??? ?mListener = listener;
?? ?}
?? ?
?? ?@Override
?? ?public void wellPrepared() {
?? ??? ?mHandler.sendEmptyMessage(MSG_AUDIO_PREPARED);
?? ?}
?? ?/*
?? ? * 獲取音量大小
?? ? */
?? ?private Runnable mGetVoiceLevelRunnable=new Runnable() {
?? ??? ?
?? ??? ?@Override
?? ??? ?public void run() {
?? ??? ??? ?while (isRecording) {
?? ??? ??? ??? ?
?? ??? ??? ??? ??? ?try {
?? ??? ??? ??? ??? ??? ?Thread.sleep(100);
?? ??? ??? ??? ??? ??? ?mTime+=0.1f;
?? ??? ??? ??? ??? ??? ?mHandler.sendEmptyMessage(MSG_VOICE_CHANGE);
?? ??? ??? ??? ??? ?} catch (InterruptedException e) {
?? ??? ??? ??? ??? ??? ?// TODO Auto-generated catch block
?? ??? ??? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ?
?? ??? ??? ?}
?? ??? ?}
?? ?};
?? ?
?? ?private static final int MSG_AUDIO_PREPARED = 0X110;
?? ?private static final int MSG_VOICE_CHANGE = 0X111;
?? ?private static final int MSG_DIALOG_DIMISS = 0X112;
?? ?
?? ?private? Handler mHandler = new Handler()
?? ?{
?? ??? ?
?? ??? ?public void handleMessage(android.os.Message msg) {
?? ??? ??? ?switch (msg.what) {
?? ??? ??? ?case MSG_AUDIO_PREPARED:
?? ??? ??? ??? ?// 正真顯示dialog在audio end prepared以后
?? ??? ??? ??? ?mDailogManager.showRecordingDialog();
?? ??? ??? ??? ?isRecording = true;
?? ??? ??? ??? ?//開啟線程獲取音量
?? ??? ??? ??? ?new Thread(mGetVoiceLevelRunnable).start();
?? ??? ??? ??? ?break;
?? ??? ??? ?case MSG_VOICE_CHANGE:
?? ??? ??? ??? ?mDailogManager.updateVoiceLevel(mAudioManager.getVoiceLevel(7));
?? ??? ??? ??? ?break;
?? ??? ??? ?case MSG_DIALOG_DIMISS:
?? ??? ??? ??? ?mDailogManager.dimissDialog();
?? ??? ??? ??? ?break;
?? ??? ??? ?}
?? ??? ?};
?? ?};
?? ?@Override
?? ?public boolean onTouchEvent(MotionEvent event) {
?? ??? ?int action = event.getAction();
?? ??? ?int x = (int) event.getX();
?? ??? ?int y = (int) event.getY();
?? ??? ?
//?? ??? ?try {
?? ??? ??? ?switch (action) {
?? ??? ??? ?case MotionEvent.ACTION_DOWN:
?? ??? ??? ??? ?changeState(STATE_RECORDING);
?? ??? ??? ??? ?break;
?? ??? ??? ?case MotionEvent.ACTION_MOVE:
?? ??? ??? ??? ?if (isRecording) {
?? ??? ??? ??? ??? ?if (wantToCancel(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) {//時間短,還沒有來得及repared
?? ??? ??? ??? ??? ?mDailogManager.tooShort();
?? ??? ??? ??? ??? ?mAudioManager.cancel();
?? ??? ??? ??? ??? ?mHandler.sendEmptyMessageDelayed(MSG_DIALOG_DIMISS, 1300);//1.3秒后關閉tooshort
?? ??? ??? ??? ?}else?? ?if (mCurState==STATE_RECORDING) {//正常錄制結束
?? ??? ??? ??? ??? ?//release
?? ??? ??? ??? ??? ?mDailogManager.dimissDialog();
?? ??? ??? ??? ??? ?mAudioManager.release();
?? ??? ??? ??? ??? ?//callbackToAct
?? ??? ??? ??? ??? ?if (mListener != null) {
?? ??? ??? ??? ??? ??? ?mListener.onFinished(mTime, mAudioManager.getCurrentFilePath());
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}else if (mCurState==STATE_WANT_TO_CANCEL) {
?? ??? ??? ??? ??? ?//cancel
?? ??? ??? ??? ??? ?mDailogManager.dimissDialog();
?? ??? ??? ??? ??? ?mAudioManager.cancel();
?? ??? ??? ??? ?}
?? ??? ??? ??? ?reset();
?? ??? ??? ??? ?break;
?? ??? ??? ?}
//?? ??? ?} catch (Exception e) {
//?? ??? ??? ?System.out.println("1111111111111111111111111111");
//?? ??? ??? ?e.printStackTrace();
//?? ??? ?}
?? ??? ?
?? ??? ?return super.onTouchEvent(event);
?? ??? ?
?? ?}
?? ??? ?//恢復標志位
?? ?private void reset() {
?? ??? ?isRecording = false;
?? ??? ?changeState(STATE_NORNMAL);
?? ??? ?mTime = 0;
?? ??? ?mReady = false;
?? ?}
?? ?private boolean wantToCancel(int x, int y) {
?? ??? ?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) {//state是將要邊車的狀態
?? ??? ?if (mCurState!=state) {
?? ??? ??? ?mCurState = state;
?? ??? ??? ?switch (state) {
?? ??? ??? ?case STATE_NORNMAL:
?? ??? ??? ??? ?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) {
?? ??? ??? ??? ?
?? ??? ??? ??? ??? ?mDailogManager.recording();
?? ??? ??? ??? ?}
?? ??? ??? ??? ?break;
?? ??? ??? ?case STATE_WANT_TO_CANCEL:
?? ??? ??? ??? ?setBackgroundResource(R.drawable.btn_recording);
?? ??? ??? ??? ?setText(R.string.str_recorder_cancel);
?? ??? ??? ??? ?
?? ??? ??? ??? ?mDailogManager.wantToCancel();
?? ??? ??? ??? ?break;
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?
}