package?com.example.wechattest;
import?android.app.Dialog;
import?android.content.Context;
import?android.view.LayoutInflater;
import?android.view.View;
import?android.widget.ImageView;
import?android.widget.TextView;
public?class?DialogManager?{
private?Dialog?mDialog;
private?ImageView?mIcon;
private?ImageView?mVoice;
private?TextView?mLable;
private?Context?mContext;
public?DialogManager(Context?context)?{
mContext?=?context;
}
public?void?showRecordingDialog()?{
mDialog?=?new?Dialog(mContext,R.style.AudioDialogTheme);
LayoutInflater?inflater?=?LayoutInflater.from(mContext);
View?view?=?inflater.inflate(R.layout.dialog_recorder,?null);
mDialog.setContentView(view);
mIcon?=?(ImageView)?mDialog.findViewById(R.id.iv_dialog_icon);
mVoice?=?(ImageView)?mDialog.findViewById(R.id.iv_dialog_voice);
mLable?=?(TextView)?mDialog.findViewById(R.id.tv_dialog_lable);
mDialog.show();
}
public?void?recording()?{
if?(mDialog?!=?null?&&?mDialog.isShowing())?{
mIcon.setVisibility(View.VISIBLE);
mVoice.setVisibility(View.VISIBLE);
mLable.setVisibility(View.VISIBLE);
mIcon.setImageResource(R.drawable.recorder);
mLable.setText(R.string.recorder_to_cancel);
}
}
public?void?wantToCancel()?{
if?(mDialog?!=?null?&&?mDialog.isShowing())?{
mIcon.setVisibility(View.VISIBLE);
mVoice.setVisibility(View.GONE);
mLable.setVisibility(View.VISIBLE);
mIcon.setImageResource(R.drawable.cancel);
mLable.setText(R.string.recorder_cancel);
}
}
public?void?tooShort()?{
if?(mDialog?!=?null?&&?mDialog.isShowing())?{
mIcon.setVisibility(View.VISIBLE);
mVoice.setVisibility(View.GONE);
mLable.setVisibility(View.VISIBLE);
mIcon.setImageResource(R.drawable.voice_to_short);
mLable.setText(R.string.recorder_too_short);
}
}
public?void?dimissDialog()?{
if?(mDialog?!=?null?&&?mDialog.isShowing())?{
mDialog.dismiss();
mDialog?=?null;
}
}
/**
?*?通過level更新voice上的圖片
?*?@param?level
?*/
public?void?updateVoiceLevel(int?level)?{
if?(mDialog?!=?null?&&?mDialog.isShowing())?{
// mIcon.setVisibility(View.VISIBLE);
// mVoice.setVisibility(View.VISIBLE);
// mLable.setVisibility(View.VISIBLE);
int?resid?=?mContext.getResources().getIdentifier("v"?+?level,
"drawable",?mContext.getPackageName());
mIcon.setImageResource(resid);
mLable.setText(R.string.recorder_too_short);
}
}
}
/////////////////////////////////////////////////////////////////////
package?com.example.wechattest;
import?java.io.File;
import?java.io.IOException;
import?java.security.GeneralSecurityException;
import?java.util.UUID;
import?android.media.MediaRecorder;
public?class?AudioManager?{
private?MediaRecorder?mMediaRecorder;
private?String?mCurrentFilePath;
private?String?mDir;
private?static?AudioManager?mInstance;
private?boolean?isPrepared;
private?AudioManager(String?dir)?{
mDir?=?dir;
}
public?interface?AudioStateListenner?{
void?wellPrepared();
}
public?AudioStateListenner?mListenner;
public?void?setOnAudioAudioStateListenner(AudioStateListenner?listenner)?{
mListenner?=?listenner;
}
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());
//?音源
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//?音頻的格式
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
//?音頻的編碼
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.prepare();
mMediaRecorder.start();
//?準備結束
isPrepared?=?true;
if?(mListenner?!=?null)
mListenner.wellPrepared();
}?catch?(IllegalStateException?e)?{
//?TODO?Auto-generated?catch?block
e.printStackTrace();
}?catch?(IOException?e)?{
//?TODO?Auto-generated?catch?block
e.printStackTrace();
}
}
private?String?generateFileName()?{
return?UUID.randomUUID().toString()?+?".amr";
}
public?int?getVoiceLevel(int?maxLevel)?{
if?(isPrepared)?{
//?mMediaRecorder.getMaxAmplitude()值在1-32767之間
try?{
return?maxLevel?*?mMediaRecorder.getMaxAmplitude()?/?32768?+?1;
}?catch?(IllegalStateException?e)?{
}
}
return?1;
}
public?void?release()?{
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder?=?null;
}
public?void?cancel()?{
release();
if?(mCurrentFilePath?!=?null)?{
File?f?=?new?File(mCurrentFilePath);
f.delete();
mCurrentFilePath?=?null;
}
}
public?String?getCurrentFilePath()?{
//?TODO?Auto-generated?method?stub
return?mCurrentFilePath;
}
}
/////////////////////////////////////////////////////////////////////
package?com.example.wechattest;
import?com.example.wechattest.AudioManager.AudioStateListenner;
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?AudioButtonView?extends?Button?implements?AudioStateListenner?{
private?static?final?int?DISTANCE?=?50;
private?static?final?int?STATE_NORMAL?=?1;
private?static?final?int?STATE_RECORDING?=?2;
private?static?final?int?STATE_CANCEL?=?3;
private?int?mState?=?STATE_NORMAL;
private?boolean?isRecording?=?false;
private?DialogManager?mDialogManager;
private?AudioManager?mAudioManager;
private?float?mTime;
//?是否出發長按
private?boolean?mReady?=?false;
public?AudioButtonView(Context?context,?AttributeSet?attrs)?{
super(context,?attrs);
mDialogManager?=?new?DialogManager(getContext());
String?dir?=?Environment.getDataDirectory()?+?"/wechat_self";
mAudioManager?=?AudioManager.getInstance(dir);
mAudioManager.setOnAudioAudioStateListenner(this);
setOnLongClickListener(new?OnLongClickListener()?{
@Override
public?boolean?onLongClick(View?v)?{
mReady?=?true;
mAudioManager.prepareAudio();
return?false;
}
});
}
/**
?*?錄音完成后的回調
?*?
?*?@author?Administrator
?*?
?*/
public?interface?audioFinishRecorderListener?{
void?onFinish(float?seconds,?String?filePath);
}
private?audioFinishRecorderListener?mListener;
public?void?setAudioFinishRecorderListener(
audioFinishRecorderListener?listener)?{
mListener?=?listener;
}
/**
?*?獲取音量大小的Runnable
?*/
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?=?0X110;
private?static?final?int?MSG_VOICE_CHANGED?=?0X111;
private?static?final?int?MSG_DIALOG_DIMISS?=?0X112;
private?Handler?mHandler?=?new?Handler()?{
public?void?handlerMessage(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_DIMISS:
break;
}
};
};
@Override
public?void?wellPrepared()?{
mHandler.sendEmptyMessage(MSG_AUDIO_PREPARED);
}
public?AudioButtonView(Context?context)?{
this(context,?null);
//?TODO?Auto-generated?constructor?stub
}
@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?(wantToCancel(x,?y))?{
changeState(STATE_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_DIMISS,?1300);
}?else?if?(mState?==?STATE_RECORDING)?{
//?正常錄制結束
mDialogManager.dimissDialog();
mAudioManager.release();
if?(mListener?!=?null)?{
mListener.onFinish(mTime,
mAudioManager.getCurrentFilePath());
}
}?else?if?(mState?==?STATE_CANCEL)?{
mDialogManager.dimissDialog();
mAudioManager.cancel();
}
reset();
break;
}
return?super.onTouchEvent(event);
}
private?void?reset()?{
//?TODO?Auto-generated?method?stub
isRecording?=?false;
mReady?=?false;
changeState(STATE_NORMAL);
mTime?=?0;
}
private?boolean?wantToCancel(int?x,?int?y)?{
if?(x?<?0?||?x?>?getWidth())?{
return?true;
}?else?if?(y?<?-DISTANCE?||?y?>?getHeight()?+?DISTANCE)?{
return?true;
}
return?false;
}
private?void?changeState(int?state)?{
//?TODO?Auto-generated?method?stub
if?(mState?!=?state)?{
mState?=?state;
switch?(state)?{
case?STATE_NORMAL:
setBackgroundResource(R.drawable.state_recorder_normal);
setText(R.string.recorder_normal);
break;
case?STATE_RECORDING:
setBackgroundResource(R.drawable.state_recorder_pressed);
setText(R.string.recorder_recording);
if?(isRecording)?{
//?todo?show?dialog.recording
mDialogManager.recording();
}
break;
case?STATE_CANCEL:
setBackgroundResource(R.drawable.state_recorder_pressed);
setText(R.string.recorder_cancel);
if?(isRecording)?{
//?todo?show?dialog.cancel
mDialogManager.wantToCancel();
}
break;
}
}
}
}
///////////////下面這是log日志/////////////////////////////
03-11?11:26:20.292:?E/Trace(5189):?error?opening?trace?file:?No?such?file?or?directory?(2)
03-11?11:26:24.732:?E/MediaRecorder(5189):?stop?called?in?an?invalid?state:?4
03-11?11:26:24.732:?E/InputEventReceiver(5189):?Exception?dispatching?input?event.
03-11?11:26:24.732:?E/MessageQueue-JNI(5189):?Exception?in?MessageQueue?callback:?handleReceiveCallback
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):?java.lang.IllegalStateException
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.media.MediaRecorder.native_stop(Native?Method)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.media.MediaRecorder.stop(MediaRecorder.java:777)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?com.example.wechattest.AudioManager.release(AudioManager.java:101)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?com.example.wechattest.AudioManager.cancel(AudioManager.java:108)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?com.example.wechattest.AudioButtonView.onTouchEvent(AudioButtonView.java:142)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.View.dispatchTouchEvent(View.java:7143)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1942)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1396)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.app.Activity.dispatchTouchEvent(Activity.java:2399)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1890)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.View.dispatchPointerEvent(View.java:7323)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3200)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3145)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4181)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4160)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4252)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.os.MessageQueue.nativePollOnce(Native?Method)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.os.MessageQueue.next(MessageQueue.java:125)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.os.Looper.loop(Looper.java:124)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?android.app.ActivityThread.main(ActivityThread.java:4825)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?java.lang.reflect.Method.invokeNative(Native?Method)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?java.lang.reflect.Method.invoke(Method.java:511)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
03-11?11:26:24.762:?E/MessageQueue-JNI(5189):? at?dalvik.system.NativeStart.main(Native?Method)
03-11?11:26:24.782:?E/dalvikvm(5189):?GC_CONCURRENT?freed?343K,?8%?free?8403K/9095K,?paused?12ms+2ms,?total?41ms
2016-04-04
430行錯誤代碼??error?opening?trace?file:?No?such?file?or?directory?(2) ? 是不是沒有創建對應的文件夾路徑所致
2016-03-28
? 應該是報空指針異常了吧? ?mMediaRecorder.prepare(); 這句話這里出現了異常,但不是RuntimeException,所以不會馬上崩潰。但是mMediaRecorder.prepare();下面的語句執行不了。就導致有東西報空指針了。仔細檢查MediaRecorder的準備步驟,看看哪里有問題。或者權限的添加是否有問題。
2016-03-17
在release()方法里面先判斷一下MediaRecorder是不是為空,不為空的情況下再去stop和release。還有就是你SD卡的讀寫權限有沒添加?