天津市做网站的公司有哪些贵阳奇点未来网站建设
天津市做网站的公司有哪些,贵阳奇点未来网站建设,建设网站的 成本,荔枝app下载不收费用一、简述效果#xff1a;实现功能#xff1a;长按Button时改变Button显示文字#xff0c;弹出Dialog(动态更新音量)#xff0c;动态生成录音文件#xff0c;开始录音#xff1b;监听手指动作#xff0c;规定区域。录音状态下手指划出规定区域取消录音#xff0c;删除生…一、简述效果实现功能长按Button时改变Button显示文字弹出Dialog(动态更新音量)动态生成录音文件开始录音监听手指动作规定区域。录音状态下手指划出规定区域取消录音删除生成的录音文件监听手指动作。当手指抬起时判断是否开始录音录音时长是否过短符合条件则提示录音时长过短正常结束时通过回调返回该次录音的文件路径和时长。4.点击录音列表的item时播放动画播放对应的音频文件。主要用到4个核心类自定义录音按钮(AudioRecordButton)弹框管理类(DialogManager)录音管理类(AudioManager)。1.AudioRecordButton状态1.STATE_NORMAL:普通状态2.STATE_RECORDING:录音中3.STATE_CANCEL取消录音2.DialogManager状态:1.RECORDING录音中2.WANT_TO_CANCEL取消录音3.TOO_SHORT录音时间太短3.AudioManager1.prepare():准备状态2.cancel()取消录音3.release():正常结束录音4.getVoiceLevel()获取音量核心逻辑自定义Button重写onTouchEvent()方法。伪代码class AudioRecorderButton{onTouchEvent(){DOWN:changeButtonState(STATE_RECORDING);| DialogManager.showDialog(RECORDING)触发LongClick事件(AudioManager.prepare() -- end prepared -- | );| getVoiceLevel();//开启一个线程更新Dialog上的音量等级MOVE:if(wantCancel(x,y)){DialogManager.showDialog(WANT_TO_CANCEL);更新DialogchangeButtonState(STATE_WANT_TO_CANCEL);更新Button状态}else{DialogManager.showDialog(WANT_TO_CANCEL);changeButtonState(STATE_RECORDING);}UP:if(wantCancel curState){//当前状态是想取消状态AudioManager.cancel();}if(STATE_RECORDING curState){if(tooShort){//判断录制时长如果录制时间过短DialogManager.showDialog(TOO_SHORT);}AudioManager.release();callbackActivity(url,time);//(当前录音文件路径时长)}}}二、MediaManager封装简述使用MediaPlayer播放录制好的音频文件要注意MediaPlayer资源的释放。代码import android.media.*;import java.io.IOException;/*** 播放管理类*/public class MediaManager {private static MediaPlayer mMediaPlayer;private static boolean isPause;public static void playSound(String filePath, MediaPlayer.OnCompletionListener onCompletionListener) {if (mMediaPlayer null) {mMediaPlayer new MediaPlayer();mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {Overridepublic boolean onError(MediaPlayer mp, int what, int extra) {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 (IOException e) {e.printStackTrace();}}public static void pause(){if(mMediaPlayer ! null mMediaPlayer.isPlaying()){mMediaPlayer.pause();isPause true;}}public static void resume(){if(mMediaPlayer ! null isPause){mMediaPlayer.start();isPause false;}}public static void release(){if(mMediaPlayer ! null){mMediaPlayer.release();mMediaPlayer null;}}}三、DialogManager封装封装了6个方法1. showRecordingDialog()用来设置Diaog布局拿到控件的引用显示Dialog。2. recording()更改Dialog状态为录音中状态。3. wantToCancel()更改Dialog状态为想要取消状态。4. tooShort()更改Dialog状态为录音时长过短状态。5. dismissDialog()移除Dialog。6. updateVoiceLevel()用来更新音量图片。代码import android.app.Dialog;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.widget.ImageView;import android.widget.TextView;import com.tiddlerliu.wxrecorder.R;/*** Dialog管理类*/public class DialogManager {private Dialog mDialog;private ImageView mIcon;private ImageView mVoice;private TextView mLabel;private Context mContext;public DialogManager(Context context) {mContext context;}/*** 显示Dialog*/public void showRecordingDialog(){//将布局应用于DialogmDialog 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.recorder_dialog_icon);mVoice (ImageView) mDialog.findViewById(R.id.recorder_dialog_voice);mLabel (TextView) mDialog.findViewById(R.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.mipmap.recorder);mLabel.setText(手指上滑取消发送);}}public void wantToCancel(){if(mDialog ! null mDialog.isShowing()){mIcon.setVisibility(View.VISIBLE);mVoice.setVisibility(View.GONE);mLabel.setVisibility(View.VISIBLE);mIcon.setImageResource(R.mipmap.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.mipmap.voice_to_short);mLabel.setText(录音时间过短);}}public void dismissDialog(){if(mDialog ! null mDialog.isShowing()){mDialog.dismiss();mDialog null;}}/*** 通过level更新音量资源图片* param level*/public void updateVoiceLevel(int level){if(mDialog ! null mDialog.isShowing()){int resId mContext.getResources().getIdentifier(vlevel,mipmap,mContext.getPackageName());mVoice.setImageResource(resId);}}}四、AudioManager封装4.1 添加必要权限4.2 代码import android.media.MediaRecorder;import java.io.File;import java.io.IOException;import java.util.UUID;/*** 录音管理类*/public class AudioManager {private String mDir;//文件夹名称private MediaRecorder mMediaRecorder;private String mCurrentFilePath;//文件储存路径private static AudioManager mInstance;//表明MediaRecorder是否进入prepare状态(状态为true才能调用stop和release方法)private boolean isPrepared;public AudioManager(String dir) {mDir dir;}public String getCurrentFilePath() {return mCurrentFilePath;}/*** 准备完毕接口*/public interface AudioStateListener{void wellPrepared();}public AudioStateListener mListener;public void setOnAudioStateListener(AudioStateListener listener){mListener listener;}/*** 单例* return AudioManager*/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.AMR_NB);//设置音频格式mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置音频编码mMediaRecorder.prepare();mMediaRecorder.start();//准备结束isPrepared true;if (mListener ! null){mListener.wellPrepared();}} catch (IOException e) {e.printStackTrace();}}/*** 随机生成文件的名称* return*/private String generateFileName() {return UUID.randomUUID().toString().amr;}/*** 获取音量等级*/public int getVoiceLevel(int maxLevel) {if (isPrepared) {try {//mMediaRecorder.getMaxAmplitude() 范围:1-32767return maxLevel * mMediaRecorder.getMaxAmplitude() / 32768 1;//最大值 * [0,1) 1} catch (Exception e) {}}return 1;}/*** 重置*/public void release(){if(mMediaRecorder ! null){mMediaRecorder.stop();mMediaRecorder.release();mMediaRecorder null;}}/*** 取消*/public void cancel(){release();//删除产生的文件if(mCurrentFilePath ! null){File file new File(mCurrentFilePath);file.delete();mCurrentFilePath null;}}}五、AudioRecordButton封装import android.annotation.SuppressLint;import android.content.Context;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.Button;import com.tiddlerliu.wxrecorder.R;/*** 自定义Button*/SuppressLint(AppCompatCustomView)public class AudioRecordButton extends Button implements AudioManager.AudioStateListener{private static final int STATE_NORMAL 1;//默认状态private static final int STATE_RECORDING 2;//录音状态private static final int STATE_WANT_CANCEL 3;//想取消状态private static final int DISTANCE_Y_CANCEL 50;//定义上滑取消距离private int mCurState STATE_NORMAL;//记录当前状态private boolean isRecording false;//是否在录音状态private DialogManager mDialogManager;private AudioManager mAudioManager;private float mTime;//记录录音时长private boolean mReady;//是否触发OnLongClick事件private boolean isComplete true;//是否已经完成public AudioRecordButton(Context context) {this(context,null);}public AudioRecordButton(Context context, AttributeSet attrs) {super(context, attrs);mDialogManager new DialogManager(getContext());String dir Environment.getExternalStorageDirectory()/TiddlerLiu/recorder/audios;//最好判断SD卡是否存在可读mAudioManager AudioManager.getInstance(dir);mAudioManager.setOnAudioStateListener(this);setOnLongClickListener(new OnLongClickListener() {Overridepublic boolean onLongClick(View v) {mReady true;mAudioManager.prepareAudio();return false;}});}/*** 录音完成后的回调*/public interface AudioFinishRecorderListener {void onFinish(float seconds,String filePath);}private AudioFinishRecorderListener mAudioFinishRecorderListener;public void setAudioFinishRecorderListener(AudioFinishRecorderListener listener){mAudioFinishRecorderListener listener;}private static final int MSG_AUDIO_PREPARED 0x110;private static final int MSG_VOICE_CHANGED 0x111;private static final int MSG_DIALOG_DISMISS 0x112;private static final int MSG_AUDIO_COMPLETE 0x113;//达到最大时长自动完成/*** 获取音量大小*/private Runnable mGetVoiceLevelRunnable new Runnable() {Overridepublic void run() {while (isRecording){try {Thread.sleep(100);mTime 0.1f;if(mTime 60f){//60s自动触发完成录制mHandler.sendEmptyMessage(MSG_AUDIO_COMPLETE);}mHandler.sendEmptyMessage(MSG_VOICE_CHANGED);} catch (InterruptedException e) {e.printStackTrace();}}}};private Handler mHandler new Handler(){Overridepublic void handleMessage(Message msg) {switch (msg.what){case MSG_AUDIO_PREPARED://显示应该在audio end prepared以后mDialogManager.showRecordingDialog();isRecording true;isComplete false;new Thread(mGetVoiceLevelRunnable).start();break;case MSG_VOICE_CHANGED:mDialogManager.updateVoiceLevel(mAudioManager.getVoiceLevel(7));break;case MSG_DIALOG_DISMISS:mDialogManager.dismissDialog();break;case MSG_AUDIO_COMPLETE:complete();reset();break;default:break;}}};Overridepublic void wellPrepared() {mHandler.sendEmptyMessage(MSG_AUDIO_PREPARED);}Overridepublic 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){//根据(x,y)坐标判断是否想要取消if (wantToCancel(x,y)){changeState(STATE_WANT_CANCEL);}else{changeState(STATE_RECORDING);}}break;case MotionEvent.ACTION_UP:if(!isComplete){//没有执行超时自动完成逻辑if (!mReady) {//还未触发OnLongClick事件reset();return super.onTouchEvent(event);}if (!isRecording || mTime 0.6f) {//还未开始录音 或者 录制时长过短mDialogManager.tooShort();mAudioManager.cancel();mHandler.sendEmptyMessageDelayed(MSG_DIALOG_DISMISS, 1300);//1.3秒后关闭对话框} else if (mCurState STATE_RECORDING) {//正常录制结束complete();} else if (mCurState STATE_WANT_CANCEL) {//想要取消状态mDialogManager.dismissDialog();mAudioManager.cancel();}reset();}break;}return super.onTouchEvent(event);}/*** 正常录制结束*/private void complete() {mDialogManager.dismissDialog();mAudioManager.release();if(mAudioFinishRecorderListener ! null !isComplete){mAudioFinishRecorderListener.onFinish(mTime,mAudioManager.getCurrentFilePath());}}/*** 恢复状态和标志位*/private void reset() {isRecording false;mReady false;mTime 0;isComplete true;changeState(STATE_NORMAL);}/*** 根据(x,y)坐标判断是否想要取消* param x* param y* return*/private boolean wantToCancel(int x, int y) {if(x 0 || x getWidth()){//手指移出button范围return true;}if(y - DISTANCE_Y_CANCEL || y getHeight() DISTANCE_Y_CANCEL){//手指移出Y轴设定范围return true;}return false;}/*** 改变状态* param state*/private void changeState(int state) {if(mCurState ! state){mCurState 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_WANT_CANCEL:setBackgroundResource(R.drawable.btn_recorder_recording);setText(R.string.str_recorder_want_cancel);mDialogManager.wantToCancel();break;default:break;}}}}六、 主界面实现6.1 adapterimport android.content.Context;import android.support.annotation.NonNull;import android.support.annotation.Nullable;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.TextView;import com.tiddlerliu.wxrecorder.R;import com.tiddlerliu.wxrecorder.model.Recorder;import java.util.List;public class RecorderAdapter extends ArrayAdapter{private int mMinItemWidth;private int mMaxItemWidth;private LayoutInflater mInflater;public RecorderAdapter(NonNull Context context, List datas) {super(context, -1 ,datas);mInflater LayoutInflater.from(context);//获取屏幕参数WindowManager wm (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);//设置最小宽度和最大宽度mMinItemWidth (int) (outMetrics.widthPixels * 0.16f);mMaxItemWidth (int) (outMetrics.widthPixels * 0.64f);}NonNullOverridepublic View getView(int position, Nullable View convertView, NonNull ViewGroup parent) {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.item_recorder_time);holder.length convertView.findViewById(R.id.item_recorder_length);convertView.setTag(holder);}else {holder (ViewHolder) convertView.getTag();}//设置时长holder.seconds.setText(Math.round(getItem(position).getTime()) \);//根据时长按比例设置时长ViewGroup.LayoutParams lp holder.length.getLayoutParams();lp.width (int) (mMinItemWidth (mMaxItemWidth/60f * getItem(position).getTime()));return convertView;}private class ViewHolder{TextView seconds;View length;}}6.2 activityimport android.graphics.drawable.AnimationDrawable;import android.media.MediaPlayer;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.ListView;import com.tiddlerliu.wxrecorder.CustomView.AudioRecordButton;import com.tiddlerliu.wxrecorder.CustomView.MediaManager;import com.tiddlerliu.wxrecorder.adapter.RecorderAdapter;import com.tiddlerliu.wxrecorder.model.Recorder;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {private ListView mListView;private AudioRecordButton mAudioRecordButton;private ArrayAdapter mAdapter ;private List mDatas new ArrayList();private View mAnimView;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mListView (ListView) findViewById(R.id.recorder_list);mAudioRecordButton (AudioRecordButton) findViewById(R.id.recorder_button);mAudioRecordButton.setAudioFinishRecorderListener(new AudioRecordButton.AudioFinishRecorderListener() {Overridepublic void onFinish(float seconds, String filePath) {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 AdapterView.OnItemClickListener() {Overridepublic void onItemClick(AdapterView parent, View view, int position, long id) {if(mAnimView ! null){mAnimView.setBackgroundResource(R.mipmap.adj);mAnimView null;}//播放动画mAnimView view.findViewById(R.id.item_recorder_anim);mAnimView.setBackgroundResource(R.drawable.play_ainm);AnimationDrawable anim (AnimationDrawable) mAnimView.getBackground();anim.start();//播放音频MediaManager.playSound(mDatas.get(position).getFilePath(), new MediaPlayer.OnCompletionListener() {Overridepublic void onCompletion(MediaPlayer mp) {mAnimView.setBackgroundResource(R.mipmap.adj);}});}});}Overrideprotected void onPause() {super.onPause();MediaManager.pause();}Overrideprotected void onResume() {super.onResume();MediaManager.resume();}Overrideprotected void onDestroy() {super.onDestroy();MediaManager.release();}}总结以上所述是小编给大家介绍的Android仿微信语音消息的录制和播放功能希望对大家有所帮助如果大家有任何疑问请给我留言小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/88019.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!