Android自定义UI实现微信语音_Android

本文实例为大家分享了java获取不同路径的方法,供大家参考,具体内容如下

思路:
自定义Button
获取DialogManager、AudioManager setOnLongClickListener长按事件--做好AudioManager的录音准备工作
AudioManager.setOnAudioStateListener(this)实现录音准备完毕的接口回调方法,方法中去发送MSG_AUDIO_PREPARE消息代表录音准备工作完毕
在mHandler中接收消息,开始开启线程录音,并且计时,计时的过程中,去发送MSG_VOICE_CHANGED消息,去updateVoiceLeve更新音量图标,另外在MotionEvent.ACTION_UP事件中,去定义audioFinishRecorderListener.onFinish接口方法,方法是录音完毕的回调方法,在MainActivity中,mAudioRecorderButton.setAudioFinishRecorderListener实现录音完毕回调方法去更新listViewUi界面

点击listViewItem条目播放动画, MediaManager.playSound并且播放音频

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context="com.example.imooc_recorder.MainActivity" > 

 <ListView
 android:id="@+id/id_listview"
 android:layout_width="fill_parent"
 android:layout_height="0dp"
 android:layout_weight="1"
 android:background="#ebebeb"
 android:divider="@null"
 android:dividerHeight="10dp" >
 </ListView> 

 <FrameLayout
 android:layout_width="fill_parent"
 android:layout_height="wrap_content" >
 <View
  android:background="#ccc"
  android:layout_width="fill_parent"
  android:layout_height="1dp" /> 

 <com.example.recorder_view.AudioRecorderButton
  android:id="@+id/id_recorder_button"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_marginBottom="7dp"
  android:layout_marginLeft="50dp"
  android:layout_marginRight="50dp"
  android:layout_marginTop="6dp"
  android:background="@drawable/button_recorder_normal"
  android:gravity="center"
  android:minHeight="0dp"
  android:padding="5dp"
  android:text="@string/str_recorder_nomal"
  android:textColor="#727272" >
 </com.example.recorder_view.AudioRecorderButton> 

 </FrameLayout> 

</LinearLayout>

dialog_recorder.xml---dialog布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@drawable/dialog_loading_bg"
 android:gravity="center"
 android:orientation="vertical"
 android:padding="20dp" > 

 <LinearLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:orientation="horizontal" > 

 <ImageView
  android:id="@+id/id_recorder_dialog_icon"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:src="@drawable/recorder"
  android:visibility="visible" /> 

 <ImageView
  android:id="@+id/id_recorder_dialog_voice"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:src="@drawable/v1"
  android:visibility="visible" />
 </LinearLayout> 

 <TextView
 android:id="@+id/id_recorder_dialog_label"
 android:layout_marginTop="5dp"
 android:text="手指上滑,取消发送"
 android:textColor="#ffffff"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"/> 

</LinearLayout>

item_recorder.xml--listview中的每个item

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:background="#eeeeee"
 android:layout_height="60dp"
 android:layout_marginTop="5dp" > 

 <ImageView
 android:id="@+id/id_icon"
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:layout_alignParentRight="true"
 android:layout_centerVertical="true"
 android:layout_marginRight="5dp"
 android:src="@drawable/icon" /> 

 <FrameLayout
 android:id="@+id/id_recorder_length"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_centerVertical="true"
 android:layout_toLeftOf="@id/id_icon"
 android:background="@drawable/chatto_bg_focused" > 

 <View
  android:id="@+id/id_recorder_anim"
  android:layout_width="25dp"
  android:layout_height="25dp"
  android:layout_gravity="center_vertical|right"
  android:background="@drawable/adj" />
 </FrameLayout> 

 <TextView
 android:id="@+id/id_recorder_time"
 android:layout_centerVertical="true"
 android:layout_toLeftOf="@id/id_recorder_length"
 android:layout_marginRight="3dp"
 android:textColor="#ff777777"
 android:text=""
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" /> 

</RelativeLayout>

styles.xml

<style name="Theme_AudioDialog" parent="@android:Theme.Dialog">
 <item name="android:windowBackground">@android:color/transparent</item>
 <item name="android:windowFrame">@null</item>
 <item name="android:windowIsFloating">true</item>
  <item name="android:windowIsTranslucent">true</item>
  <item name="android:backgroundDimEnabled">false</item> 

 </style>

button_recorder_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="rectangle" > 

 <solid android:color="#ffffff"/>
 <stroke android:width="1px" android:color="#9b9b9b"/>
 <corners android:radius="3dp"/>
</shape> 

button_recorder_recording.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="rectangle" > 

 <solid android:color="#ffffff"/>
 <stroke android:width="1px" android:color="#eeeeee"/>
 <corners android:radius="3dp"/>
</shape>

play_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" > 

 <item
 android:drawable="@drawable/v_anim1"
 android:duration="300">
 </item>
 <item
 android:drawable="@drawable/v_anim2"
 android:duration="300">
 </item> 

 <item
 android:drawable="@drawable/v_anim3"
 android:duration="300">
 </item> 

</animation-list>

MainActivity

package com.example.imooc_recorder; 

import java.util.ArrayList;
import java.util.List; 

import com.example.recorder_view.AudioRecorderButton;
import com.example.recorder_view.AudioRecorderButton.AudioFinishRecorderListener;
import com.example.recorder_view.MediaManager; 

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView; 

public class MainActivity extends Activity { 

 private ListView mListView;
 private ArrayAdapter<Recorder> mAdapter;
 private List<Recorder> mDatas = new ArrayList<MainActivity.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.setAudioFinishRecorderListener(new AudioFinishRecorderListener() { 

  @Override
  public void onFinish(float seconds, String filePath) {
  // TODO Auto-generated method stub
  Recorder recorder = new Recorder(seconds, filePath);
  mDatas.add(recorder);
  mAdapter.notifyDataSetChanged();
  mListView.setSelection(mDatas.size()-1);
  }
 });
 mAdapter = new RecorderAdapter(this, mDatas);
 mListView.setAdapter(mAdapter); 

 mListView.setOnItemClickListener(new OnItemClickListener() {
  @Override
  public void onItemClick(AdapterView<?> parent, View view,
   int position, long id) {
  if (animView !=null) {
   animView.setBackgroundResource(R.drawable.adj);
   animView = null; 

  }
  //播放动画
  animView = view.findViewById(R.id.id_recorder_anim);
  animView.setBackgroundResource(R.drawable.play_anim);
  AnimationDrawable anim = (AnimationDrawable) animView.getBackground();
  anim.start();
  //播放音频
  MediaManager.playSound(mDatas.get(position).filePath,new MediaPlayer.OnCompletionListener() { 

   @Override
   public void onCompletion(MediaPlayer mp) {
   // TODO Auto-generated method stub
   animView.setBackgroundResource(R.drawable.adj);
   }
  });
  }
 });
 } 

 @Override
 protected void onPause() {
 // TODO Auto-generated method stub
 super.onPause();
 MediaManager.pause();
 }
 @Override
 protected void onResume() {
 // TODO Auto-generated method stub
 super.onResume();
 MediaManager.resume();
 }
 @Override
 protected void onDestroy() {
 // TODO Auto-generated method stub
 super.onDestroy();
 MediaManager.release();
 }
 /**内部类*/
 class Recorder{
 float time;
 String filePath;
 public Recorder(float time, String filePath) {
  super();
  this.time = time;
  this.filePath = filePath;
 }
 public float getTime() {
  return time;
 }
 public void setTime(float time) {
  this.time = time;
 }
 public String getFilePath() {
  return filePath;
 }
 public void setFilePath(String filePath) {
  this.filePath = filePath;
 } 

 }
}

RecorderAdapter

package com.example.imooc_recorder; 

import java.util.List; 

import com.example.imooc_recorder.MainActivity.Recorder; 

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView; 

public class RecorderAdapter extends ArrayAdapter<Recorder> { 

// private List<Recorder> mDatas;
// private Context mContext;
 private int mMinItemWidth;
 private int mMaxItemWidth;
 private LayoutInflater mInflater; 

 public RecorderAdapter(Context context, List<Recorder> datas) {
 super(context, -1, datas);
// mContext = context;
// mDatas = datas;
 WindowManager wm = (WindowManager) context
  .getSystemService(Context.WINDOW_SERVICE);
 DisplayMetrics outMetrics = new DisplayMetrics();
 wm.getDefaultDisplay().getMetrics(outMetrics); 

 mMaxItemWidth = (int) (outMetrics.widthPixels * 0.7f);
 mMinItemWidth = (int) (outMetrics.widthPixels * 0.15f);
 mInflater = LayoutInflater.from(context);
 } 

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
 // TODO Auto-generated method stub
 ViewHolder holder = null;
 if (convertView == null) {
  convertView = mInflater.inflate(R.layout.item_recorder, parent,
   false);
  holder = new ViewHolder();
  holder.seconds = (TextView) convertView.findViewById(R.id.id_recorder_time);
  holder.length = convertView.findViewById(R.id.id_recorder_length); 

  convertView.setTag(holder);
 }else {
  holder = (ViewHolder) convertView.getTag();
 }
 holder.seconds.setText(Math.round(getItem(position).time)+"\"");
 ViewGroup.LayoutParams lp = holder.length.getLayoutParams();
 lp.width = (int) (mMinItemWidth +(mMaxItemWidth/60f*getItem(position).time));
 return convertView;
 } 

 private class ViewHolder {
 private TextView seconds;
 private View length;
 }
}

AudioRecorderButton

package com.example.recorder_view; 

import com.example.imooc_recorder.R;
import com.example.recorder_view.AudioManager.AudioStateListener; 

import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.telephony.SignalStrength;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button; 

public class AudioRecorderButton extends Button implements AudioStateListener {
 private static final int DISTANCE_Y_CANCEL = 50; 

 /** 提示框管理工具类 */
 private DialogManager mDialogManager;
 /** 正常、松开手指取消发送、手指上滑取消发送 */
 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 AudioManager mAudioManager; 

 /** 录音总时间 */
 private float mTime; 

 /** 是否触发button */
 private boolean mReady; 

 /** *****************自定义Button************************************* */
 public AudioRecorderButton(Context context) {
 super(context);
 } 

 public AudioRecorderButton(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 } 

 public AudioRecorderButton(Context context, AttributeSet attrs) {
 super(context, attrs);
 mDialogManager = new DialogManager(getContext());
 String dir = Environment.getExternalStorageDirectory()
  + "/imooc_recorder_audios";
 mAudioManager = AudioManager.getInstance(dir);
 mAudioManager.setOnAudioStateListener(this);
 /** 监听回调 */
 setOnLongClickListener(new OnLongClickListener() { 

  @Override
  public boolean onLongClick(View v) {
  mReady = true;
  // 录音准备--准备好后,有实现接口方法
  mAudioManager.prepareAndio();
  return false;
  }
 });
 } 

 /******************************************************
 * 完成录音准备的回调函数
 */
 @Override
 public void wellPrepared() {
 // 准备完毕,发送消息
 mHandler.sendEmptyMessage(MSG_AUDIO_PREPARE);
 } 

 private Handler mHandler = new Handler() {
 public void handleMessage(android.os.Message msg) {
  switch (msg.what) {
  case MSG_AUDIO_PREPARE:
  mDialogManager.showRecordingDailog();
  isRecording = true; 

  new Thread(new Runnable() { 

   @Override
   public void run() { 

   // TODO Auto-generated method stub
   while (isRecording) {
    try {
    Thread.sleep(100);
    // 录音计时
    mTime += 0.1f;
    mHandler.sendEmptyMessage(MSG_VOICE_CHANGED);
    } catch (InterruptedException e) {
    e.printStackTrace();
    } 

   } 

   }
  }).start();
  break;
  case MSG_VOICE_CHANGED: 

  mDialogManager.updateVoiceLeve(mAudioManager.getVoiceLevel(7)); 

  break;
  case MSG_DIALOG_DIMISS: 

  mDialogManager.dimissDailog();
  break; 

  default:
  break;
  }
  super.handleMessage(msg);
 };
 }; 

 private static final int MSG_AUDIO_PREPARE = 0x110;
 private static final int MSG_VOICE_CHANGED = 0x111;
 private static final int MSG_DIALOG_DIMISS = 0x112; 

 @Override
 public boolean onTouchEvent(MotionEvent event) {
 // TODO Auto-generated method stub
 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) {
  // 根据xy坐标。判断是否想要取消
  if (wantToCancel(x, y)) {
   changeState(STATE_WANT_TO_CANCEL);
  } else {
   changeState(STATE_RECORDING);
  } 

  }
  break;
 case MotionEvent.ACTION_UP:
  if (!mReady) {
  // 没有触发onclick
  reset();
  return super.onTouchEvent(event); 

  }
  if (!isRecording || mTime < 0.6f) {
  // prapred没有完成已经up了
  mDialogManager.tooShort();
  mAudioManager.cancel();
  mHandler.sendEmptyMessageDelayed(MSG_DIALOG_DIMISS, 1300); 

  } else if (mCurState == STATE_RECORDING) { 

  mDialogManager.dimissDailog();
  mAudioManager.release();
  if (audioFinishRecorderListener != null) {
   audioFinishRecorderListener.onFinish(mTime,
    mAudioManager.getCurrentFilePath());
  }
  } else if (mCurState == STATE_WANT_TO_CANCEL) {
  mDialogManager.dimissDailog();
  mAudioManager.cancel();
  }
  // 恢复标志位
  reset();
  break; 

 default:
  break;
 }
 return super.onTouchEvent(event);
 } 

 private void reset() {
 // TODO Auto-generated method stub
 mReady = false;
 mTime = 0;
 isRecording = false;
 changeState(STATE_NORMAL);
 } 

 private boolean wantToCancel(int x, int y) {
 // x<0代表来到按钮的范围以外
 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.button_recorder_normal);
  setText(R.string.str_recorder_nomal);
  break; 

  case STATE_RECORDING:
  setBackgroundResource(R.drawable.button_recorder_recording);
  setText(R.string.str_recorder_recording);
  if (isRecording) {
   // to do
   mDialogManager.recording();
  }
  break; 

  case STATE_WANT_TO_CANCEL:
  setBackgroundResource(R.drawable.button_recorder_recording);
  setText(R.string.str_recorder_want_cancel);
  mDialogManager.wantToCancle();
  break;
  default:
  break;
  }
 }
 } 

 /** 完成录音回调 */
 public interface AudioFinishRecorderListener {
 void onFinish(float seconds, String filePath);
 } 

 private AudioFinishRecorderListener audioFinishRecorderListener; 

 public void setAudioFinishRecorderListener(
  AudioFinishRecorderListener audioFinishRecorderListener) {
 this.audioFinishRecorderListener = audioFinishRecorderListener;
 }
}

DialogManager

package com.example.recorder_view; 

import com.example.imooc_recorder.R; 

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 mLabel;
 private Context mContext; 

 public DialogManager(Context context) {
 this.mContext = context;
 } 

 public void showRecordingDailog() {
 mDialog = new Dialog(mContext, R.style.Theme_AudioDialog);
 LayoutInflater inflater = LayoutInflater.from(mContext);
 View view = inflater.inflate(R.layout.dialog_recorder, null);
 mDialog.setContentView(view); 

 mIcon = (ImageView) mDialog.findViewById(R.id.id_recorder_dialog_icon);
 mVoice = (ImageView) mDialog
  .findViewById(R.id.id_recorder_dialog_voice);
 mLabel = (TextView) mDialog.findViewById(R.id.id_recorder_dialog_label); 

 mDialog.show();
 } 

 public void recording() {
 if (mDialog != null && mDialog.isShowing()) {
  mIcon.setVisibility(View.VISIBLE);
  mVoice.setVisibility(View.VISIBLE);
  mLabel.setVisibility(View.VISIBLE); 

  mIcon.setImageResource(R.drawable.recorder);
  mLabel.setText("手指上滑,取消发送"); 

 }
 } 

 public void wantToCancle() {
 if (mDialog != null && mDialog.isShowing()) {
  mIcon.setVisibility(View.VISIBLE);
  mVoice.setVisibility(View.GONE);
  mLabel.setVisibility(View.VISIBLE); 

  mIcon.setImageResource(R.drawable.cancel);
  mLabel.setText("松开手指,取消发送"); 

 }
 } 

 public void tooShort() {
 if (mDialog != null && mDialog.isShowing()) {
  mIcon.setVisibility(View.VISIBLE);
  mVoice.setVisibility(View.GONE);
  mLabel.setVisibility(View.VISIBLE); 

  mIcon.setImageResource(R.drawable.voice_to_short);
  mLabel.setText("录音时间过短"); 

 } 

 } 

 public void dimissDailog() {
 if (mDialog != null && mDialog.isShowing()) {
  mDialog.dismiss();
  mDialog = null;
 }
 } 

 public void updateVoiceLeve(int level) {
 if (mDialog != null && mDialog.isShowing()) {
//  mIcon.setVisibility(View.VISIBLE);
//  mVoice.setVisibility(View.VISIBLE);
//  mLabel.setVisibility(View.VISIBLE); 

  // 通过方法名字,找到资源
  int resId = mContext.getResources().getIdentifier("v" + level,
   "drawable", mContext.getPackageName());
  mVoice.setImageResource(resId);
 }
 } 

}

AudioManager

package com.example.recorder_view; 

import java.io.File;
import java.io.IOException;
import java.util.UUID; 

import javax.security.auth.PrivateCredentialPermission; 

import android.R.integer;
import android.media.MediaRecorder; 

public class AudioManager { 

 private MediaRecorder mMediaRecorder;
 private String mDir;
 private String mCurrentFilepath;
 private static AudioManager mInstance; 

 private boolean isPrepare; 

 /** 接口回调 */
 public interface AudioStateListener {
 void wellPrepared();
 } 

 public AudioStateListener mAudioStateListener; 

 public void setOnAudioStateListener(AudioStateListener audioStateListener) {
 mAudioStateListener = audioStateListener; 

 } 

 private AudioManager(String dir) {
 this.mDir = dir;
 } 

 public static AudioManager getInstance(String dir) {
 if (mInstance == null) {
  synchronized (AudioManager.class) {
  if (mInstance == null) {
   mInstance = new AudioManager(dir); 

  } 

  }
 }
 return mInstance;
 } 

 public void prepareAndio() {
 isPrepare = false;
 File dir = new File(mDir);
 if (!dir.exists()) {
  dir.mkdirs();
 }
 String fileName = geneFileName(); 

 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);
 try {
  mMediaRecorder.prepare();
  mMediaRecorder.start();
  isPrepare = true;
  if (mAudioStateListener != null) {
  mAudioStateListener.wellPrepared(); 

  }
 } catch (Exception e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 } 

 private String geneFileName() {
 return UUID.randomUUID().toString() + ".amr";
 } 

 public int getVoiceLevel(int maxLevel) {
 if (isPrepare) {
  try {
  // mMediaRecorder.getMaxAmplitude() 1~32767
  // return maxlevel*mMediaRecorder.getMaxAmplitude()/32768+1;
  return maxLevel * new MediaRecorder().getMaxAmplitude() / 32768
   + 1;
  } catch (Exception e) {
  } 

 }
 return 1;
 } 

 public void release() {
 mMediaRecorder.release();
 mMediaRecorder = null;
 } 

 public void cancel() {
 release();
 if (mCurrentFilepath != null) {
  File file = new File(mCurrentFilepath);
  file.delete();
  mCurrentFilepath = null; 

 }
 } 

 public String getCurrentFilePath() {
 // TODO Auto-generated method stub
 return mCurrentFilepath;
 } 

}

MediaManager

package com.example.recorder_view; 

import java.io.IOException; 

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener; 

public class MediaManager { 

 private static MediaPlayer mediaPlayer;
 private static boolean isPause;
 public static void playSound(String filePath,
  OnCompletionListener onCompletionListener) {
 if (mediaPlayer == null) {
  mediaPlayer = new MediaPlayer();
  mediaPlayer.setOnErrorListener(new OnErrorListener() { 

  @Override
  public boolean onError(MediaPlayer mp, int what, int extra) {
   mediaPlayer.reset();
   return false;
  }
  });
 }else {
  mediaPlayer.reset();
 }
 try {
  mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
  mediaPlayer.setOnCompletionListener(onCompletionListener);
  mediaPlayer.setDataSource(filePath);
  mediaPlayer.prepare();
 } catch (Exception e) {
  e.printStackTrace();
 }
 mediaPlayer.start();
 } 

 public static void pause(){
 if (mediaPlayer!=null && mediaPlayer.isPlaying()) {
  mediaPlayer.pause();
  isPause = true;
 }
 }
 public static void resume(){
 if (mediaPlayer!=null && isPause) {
  mediaPlayer.start();
  isPause = false;
 }
 }
 public static void release(){
 if (mediaPlayer!=null) {
  mediaPlayer.release();
  mediaPlayer = null; 

 }
 }
}

本文已被整理到了《Android微信开发教程汇总》,欢迎大家学习阅读。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
, ui
, 微信
语音
android 自定义相机ui、android 自定义ui控件、android自定义ui、android 语音聊天实现、android 语音对讲实现,以便于您获取更多的相关知识。

时间: 2024-09-20 00:00:12

Android自定义UI实现微信语音_Android的相关文章

Android自定义UI手势密码改进版_Android

接着第一个Android UI手势密码设计的基础上继续改进,效果图如下 activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layo

Android自定义UI手势密码改进版源码下载_Android

在之前文章的铺垫下,再为大家分享一篇:Android手势密码,附源码下载,不要错过. 源码下载:http://xiazai.jb51.net/201610/yuanma/androidLock(jb51.net).rar 先看第一张图片的布局文件 activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://sc

Android自定义UI手势密码终结版_Android

之前写过3篇手势密码的demo,不过没有集成到真实的企业项目中,这几天正好领到一个手势密码项目,昨天刚好弄完,今天抽空整理下,目前还没有完善,有一些地方需要更改,不过基本的流程都可以跑通了. 源码下载地址:http://xiazai.jb51.net/201610/yuanma/AndroidGestureLock(jb51.net).rar 先看主界面的入口把.里面有2个button(一个是设置手势密码.一个是校验手势密码) activity_main.xml <RelativeLayout

Android自定义UI手势密码简单版_Android

先看看效果图: ImageLockActivity package com.example.imagelock; import com.example.view.NinePointLineView; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; public class ImageLockActivity extends Acti

Android自定义UI手势密码改进版源码下载

在之前文章的铺垫下,再为大家分享一篇:Android手势密码,附源码下载,不要错过. 源码下载:http://xiazai.jb51.net/201610/yuanma/androidLock(jb51.net).rar 先看第一张图片的布局文件 activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://sc

Android自定义View制作仪表盘界面_Android

前言 最近我跟自定义View杠上了,甚至说有点上瘾到走火入魔了.身为菜鸟的我自然要查阅大量的资料,学习大神们的代码,这不,前两天正好在郭神在微信公众号里推送一片自定义控件的文章--一步步实现精美的钟表界面.正适合我这种菜鸟来学习,闲着没事,我就差不多依葫芦画瓢也写了一个自定义表盘View,现在纯粹最为笔记记录下来.先展示下效果图: 下面进入正题 自定义表盘属性 老规矩,先在attrs文件里添加表盘自定义属性 <declare-styleable name="WatchView"&

Android 自定义手势--输入法手势技术_Android

进行软件开发时,通常我们都喜欢使用较新版本的工具,但这里我为什么使用低版本的SDK来开发Android游戏呢?这里介绍下原因:        1.Android SDK 属于向下兼容!那么低版本可以运行的,高版本基本上更是没问题!(当然每次SDK的更新也会带来新功能,或者修改了一些原来的BUG等等,那么其实对于游戏开发来说,如果你的游戏中不需要更高的SDK版本的支持情况下,完全不必去追求最新的SDK!)        2.使用低版本进行游戏开发这样能兼顾更多的机型,获取更多的用户!       

Android自定义TitleView标题开发实例_Android

Android开发过程中,经常遇到一个项目需要重复的定义相同样式的标题栏,Android相继推出了actionBar, toolBar, 相信有用到的朋友也会遇到一些不如意的时候,比如标题栏居中时,需要自定义xml文件给toolBar等,不了解actionBar,toolBar的可以去找相应的文章了解,这里介绍自定义titleBar满足国内主题风格样式的情况. 为了提前看到效果,先上效果图: 前期准备 1.为标题栏titleView预定义id,在values下的ids.xml中 <?xml ve

Android自定义圆形倒计时进度条_Android

效果预览 源代码传送门:https://github.com/yanzhenjie/CircleTextProgressbar 实现与原理 这个文字圆形的进度条我们在很多APP中看到过,比如APP欢迎页倒计时,下载文件倒计时等. 分析下原理,可能有的同学一看到这个自定义View就慌了,这个是不是要继承View啊,是不是要绘制啊之类的,答案是:是的.但是我们也不要担心,实现这个效果实在是so easy.下面就跟我一起来看看核心分析和代码吧. 原理分析 首先我们观察上图,需要几个部分组成: 1. 外