有段時間沒有看視頻了,昨天晚上抽了點空時間,又看了下鴻洋大神的視頻教程,又抽時間寫了個學習記錄。代碼和老師講的基本一樣,網上也有很多相同的博客。我只是在AndroidStudio環境下寫的。
―-主界面代碼――
public class MainActivity extends Activity { private ListView mListView; private ArrayAdapter<Recorder> mAdapter; private List<Recorder> mDatas = new ArrayList<Recorder>(); private AudioRecorderButton mAudioRecorderButton; private View animView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.id_listview); mAudioRecorderButton = (AudioRecorderButton) findViewById(R.id.id_recorder_button); mAudioRecorderButton.setFinishRecorderCallBack(new AudioRecorderButton.AudioFinishRecorderCallBack() { public void onFinish(float seconds, String filePath) { Recorder recorder = new Recorder(seconds, filePath); mDatas.add(recorder); //更新數據 mAdapter.notifyDataSetChanged(); //設置位置 mListView.setSelection(mDatas.size() - 1); } }); mAdapter = new RecoderAdapter(this, mDatas); mListView.setAdapter(mAdapter); //listView的item點擊事件 mListView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> arg0, View view, int position, long id) { // 聲音播放動畫 if (animView != null) { animView.setBackgroundResource(R.drawable.adj); animView = null; } animView = view.findViewById(R.id.id_recoder_anim); animView.setBackgroundResource(R.drawable.play_anim); AnimationDrawable animation = (AnimationDrawable) animView.getBackground(); animation.start(); // 播放錄音 MediaPlayerManager.playSound(mDatas.get(position).filePath, new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { //播放完成后修改圖片 animView.setBackgroundResource(R.drawable.adj); } }); } }); } @Override protected void onPause() { super.onPause(); MediaPlayerManager.pause(); } @Override protected void onResume() { super.onResume(); MediaPlayerManager.resume(); } @Override protected void onDestroy() { super.onDestroy(); MediaPlayerManager.release(); }―自定義Button――-
/** * @param * @author ldm * @description 自定義Button * @time 2016/6/25 9:26 */public class AudioRecorderButton extends Button { // 按鈕正常狀態(默認狀態) private static final int STATE_NORMAL = 1; //正在錄音狀態 private static final int STATE_RECORDING = 2; //錄音取消狀態 private static final int STATE_CANCEL = 3; //記錄當前狀態 private int mCurrentState = STATE_NORMAL; //是否開始錄音標志 private boolean isRecording = false; //判斷在Button上滑動距離,以判斷 是否取消 private static final int DISTANCE_Y_CANCEL = 50; //對話框管理工具類 private DialogManager mDialogManager; //錄音管理工具類 private AudioManager mAudioManager; //記錄錄音時間 private float mTime; // 是否觸發longClick private boolean mReady; //錄音準備 private static final int MSG_AUDIO_PREPARED = 0x110; //音量發生改變 private static final int MSG_VOICE_CHANGED = 0x111; //取消提示對話框 private static final int MSG_DIALOG_DIMISS = 0x112; /** * @description 獲取音量大小的線程 * @author ldm * @time 2016/6/25 9:30 * @param */ private Runnable mGetVoiceLevelRunnable = new Runnable() { public void run() { while (isRecording) {//判斷正在錄音 try { Thread.sleep(100); mTime += 0.1f;//錄音時間計算 mHandler.sendEmptyMessage(MSG_VOICE_CHANGED);//每0.1秒發送消息 } catch (InterruptedException e) { e.printStackTrace(); } } } }; private Handler mHandler = new Handler() { @Override public void handleMessage(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: //取消對話框 mDialogManager.dimissDialog(); break; } super.handleMessage(msg); } }; public AudioRecorderButton(Context context, AttributeSet attrs) { super(context, attrs); mDialogManager = new DialogManager(context); //錄音文件存放地址 String dir = Environment.getExternalStorageDirectory() + "/ldm_voice"; mAudioManager = AudioManager.getInstance(dir); mAudioManager.setOnAudioStateListener(new AudioManager.AudioStateListener() { public void wellPrepared() { mHandler.sendEmptyMessage(MSG_AUDIO_PREPARED); } }); // 由于這個類是button所以在構造方法中添加監聽事件 setOnLongClickListener(new OnLongClickListener() { public boolean onLongClick(View v) { mReady = true; mAudioManager.prepareAudio(); return false; } }); } public AudioRecorderButton(Context context) { this(context, null); } /** * @description 錄音完成后的回調 * @author ldm * @time 2016/6/25 11:18 * @param */ public interface AudioFinishRecorderCallBack { void onFinish(float seconds, String filePath); } private AudioFinishRecorderCallBack finishRecorderCallBack; public void setFinishRecorderCallBack(AudioFinishRecorderCallBack listener) { finishRecorderCallBack = listener; } /** * @param * @description 處理Button的OnTouchEvent事件 * @author ldm * @time 2016/6/25 9:35 */ @Override public boolean onTouchEvent(MotionEvent event) { //獲取TouchEvent狀態 int action = event.getAction(); // 獲得x軸坐標 int x = (int) event.getX(); // 獲得y軸坐標 int y = (int) event.getY(); switch (action) { case MotionEvent.ACTION_DOWN://手指按下 changeState(STATE_RECORDING); break; case MotionEvent.ACTION_MOVE://手指移動 if (isRecording) { //根據x,y的坐標判斷是否需要取消 if (wantToCancle(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) {//如果時間少于0.6s,則提示錄音過短 mDialogManager.tooShort(); mAudioManager.cancel(); // 延遲顯示對話框 mHandler.sendEmptyMessageDelayed(MSG_DIALOG_DIMISS, 1000); } else if (mCurrentState == STATE_RECORDING) { //如果狀態為正在錄音,則結束錄制 mDialogManager.dimissDialog(); mAudioManager.release(); if (finishRecorderCallBack != null) { finishRecorderCallBack.onFinish(mTime, mAudioManager.getCurrentFilePath()); } } else if (mCurrentState == STATE_CANCEL) { // 想要取消 mDialogManager.dimissDialog(); mAudioManager.cancel(); } reset(); break; } return super.onTouchEvent(event); } /** * 恢復狀態及標志位 */ private void reset() { isRecording = false; mTime = 0; mReady = false; changeState(STATE_NORMAL); } private boolean wantToCancle(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; } /** * @param * @description 根據狀態改變Button顯示 * @author ldm * @time 2016/6/25 9:36 */ private void changeState(int state) { if (mCurrentState != state) { mCurrentState = 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_recorder_recording); setText(R.string.str_recorder_recording); if (isRecording) { mDialogManager.recording(); } break; case STATE_CANCEL: setBackgroundResource(R.drawable.btn_recorder_recording); mDialogManager.wantToCancel(); setText(R.string.str_recorder_want_cancel); break; } } }}―-對話框管理工具類――
/** * @description 對話框管理工具類 * @author ldm * @time 2016/6/25 11:53 * @param */public class DialogManager { //彈出對話框 private Dialog mDialog; //錄音圖標 private ImageView mIcon; //音量顯示 圖標 private ImageView mVoice; //對話框上提示文字 private TextView mLable; //上下文對象 private Context mContext; public DialogManager(Context context) { this.mContext = context; } /** * @param * @description 顯示對話框 * @author ldm * @time 2016/6/25 9:56 */ public void showRecordingDialog() { //根據指定sytle實例化Dialog mDialog = new Dialog(mContext, R.style.AudioDialog); LayoutInflater inflater = LayoutInflater.from(mContext); View view = inflater.inflate(R.layout.dialog_recorder, null); mDialog.setContentView(view); mIcon = (ImageView) view.findViewById(R.id.id_recorder_dialog_icon); mVoice = (ImageView) view.findViewById(R.id.id_recorder_dialog_voice); mLable = (TextView) view.findViewById(R.id.id_recorder_dialog_label); mDialog.show(); } /** * @param * @description 正在錄音狀態的對話框 * @author ldm * @time 2016/6/25 10:08 */ 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("手指上滑,取消發送"); } } /** * @param * @description 取消錄音狀態對話框 * @author ldm * @time 2016/6/25 10:08 */ 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("松開手指,取消發送"); } } /** * @param * @description時間過短提示的對話框 * @author ldm * @time 2016/6/25 10:09 */ 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("錄音時間過短"); } } /** * @param * @description * @author ldm * @time 2016/6/25 取消(關閉)對話框 */ public void dimissDialog() { if (mDialog != null && mDialog.isShowing()) { //顯示狀態 mDialog.dismiss(); mDialog = null; } } // 顯示更新音量級別的對話框 public void updateVoiceLevel(int level) { if (mDialog != null && mDialog.isShowing()) { //顯示狀態 mIcon.setVisibility(View.VISIBLE); mVoice.setVisibility(View.VISIBLE); mLable.setVisibility(View.VISIBLE); //設置圖片的id,我們放在drawable中的聲音圖片是以v+數字格式的 int resId = mContext.getResources().getIdentifier("v" + level, "drawable", mContext.getPackageName()); mVoice.setImageResource(resId); } }}―-聲音播放工具類――
/** * @param * @author ldm * @description 播放聲音工具類 * @time 2016/6/25 11:29 */public class MediaPlayerManager { //播放音頻API類:MediaPlayer private static MediaPlayer mMediaPlayer; //是否暫停 private static boolean isPause; /** * @param * filePath:文件路徑 * onCompletionListener:播放完成監聽 * @description 播放聲音 * @author ldm * @time 2016/6/25 11:30 */ public static void playSound(String filePath, MediaPlayer.OnCompletionListener onCompletionListener) { if (mMediaPlayer == null) { mMediaPlayer = new MediaPlayer(); //設置一個error監聽器 mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { public boolean onError(MediaPlayer arg0, int arg1, int arg2) { mMediaPlayer.reset(); return false; } }); } else { mMediaPlayer.reset(); } try { mMediaPlayer.setAudioStreamType(android.media.AudioManager.STREAM_MUSIC); mMediaPlayer.setOnCompletionListener(onCompletionListener); mMediaPlayer.setDataSource(filePath); mMediaPlayer.prepare(); mMediaPlayer.start(); } catch (Exception e) { } } /** * @param * @description 暫停播放 * @author ldm * @time 2016/6/25 11:31 */ public static void pause() { if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { //正在播放的時候 mMediaPlayer.pause(); isPause = true; } } /** * @param * @description 重新播放 * @author ldm * @time 2016/6/25 11:31 */ public static void resume() { if (mMediaPlayer != null && isPause) { mMediaPlayer.start(); isPause = false; } } /** * @param * @description 釋放操作 * @author ldm * @time 2016/6/25 11:32 */ public static void release() { if (mMediaPlayer != null) { mMediaPlayer.release(); mMediaPlayer = null; } }― 主站蜘蛛池模板: 冀州市| 临颍县| 柘城县| 高雄县| 江北区| 沈丘县| 永登县| 衡阳县| 浠水县| 横峰县| 太仆寺旗| 巴楚县| 新民市| 普兰县| 平定县| 集贤县| 微山县| 正阳县| 巴林左旗| 巴林右旗| 三亚市| 阜阳市| 高清| 沁阳市| 银川市| 恩施市| 遂平县| 洛宁县| 马关县| 诸城市| 开江县| 高阳县| 乐清市| 应城市| 东乡县| 扎赉特旗| 诸城市| 鄯善县| 霞浦县| 乌海市| 漳州市|