为了账号安全,请及时绑定邮箱和手机立即绑定

按下按钮之后没有dialog出现,松开后就闪退,是真机测试的log,请教老师……

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


正在回答

3 回答

430行错误代码  error opening trace file: No such file or directory (2)   是不是没有创建对应的文件夹路径所致

0 回复 有任何疑惑可以回复我~

  应该是报空指针异常了吧?  mMediaRecorder.prepare(); 这句话这里出现了异常,但不是RuntimeException,所以不会马上崩溃。但是mMediaRecorder.prepare();下面的语句执行不了。就导致有东西报空指针了。仔细检查MediaRecorder的准备步骤,看看哪里有问题。或者权限的添加是否有问题。

0 回复 有任何疑惑可以回复我~

在release()方法里面先判断一下MediaRecorder是不是为空,不为空的情况下再去stop和release。还有就是你SD卡的读写权限有没添加?

1 回复 有任何疑惑可以回复我~
#1

可得藏好哟

是没开权限 谢谢啦
2018-12-19 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
Android-仿微信语音聊天
  • 参与学习       43182    人
  • 解答问题       248    个

结合自定义View和API,Dialog管理等实现实现微信语音

进入课程

按下按钮之后没有dialog出现,松开后就闪退,是真机测试的log,请教老师……

我要回答 关注问题
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号