• Android中使用AudioManager实现按键录音并保存以及点击播放功能


    场景

    在Android中怎样实现类似发送语音消息功能前的按键录音并将其显示在RecyclerView上并且能点击录音文件进行播放。

    注:

    博客:
    https://blog.csdn.net/badao_liumang_qizhi
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

    实现页面布局

    新建一个项目,实现页面布局如下

    布局代码:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toTopOf="@+id/layout_bottom"
            app:layout_constraintTop_toTopOf="parent" />
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="101dp"
            android:id="@+id/layout_bottom"
            android:background="#F7F7F7"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent">
    
            <ImageView
                android:layout_width="66dp"
                android:layout_height="66dp"
                android:id="@+id/img_voice"
                android:background="@mipmap/badao"
                android:layout_centerInParent="true"
                />
    
        </RelativeLayout>
    
    </androidx.constraintlayout.widget.ConstraintLayout>

    并且在MainActivity中获取这些控件,并且设置下面ImageView的按下和松开的事件

    public class MainActivity extends AppCompatActivity {
    
        private ImageView audioImageView;
        private RecyclerView mRecyclerView;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            audioImageView = findViewById(R.id.img_voice);
            audioImageView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    if(motionEvent.getAction() == MotionEvent.ACTION_DOWN)
                    {
                        Toast.makeText(MainActivity.this,"录音开始",Toast.LENGTH_SHORT).show();
    
                        return true;
                    }else if(motionEvent.getAction() == MotionEvent.ACTION_UP)
                    {
                        Toast.makeText(MainActivity.this,"录音结束",Toast.LENGTH_SHORT).show();
    
                        return true;
                    }
                    return false;
                }
            });
    
        }

    赋予录音权限

    打开AndroidManifest.xml

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.RECORD_AUDIO"/>

    封装录音相关工具类

    在包下新建audioHelper包,包下新建如下几个接口和类

     

    AudioRecordManager

    package com.badao.audiodemo.audioHelper;
    
    import android.annotation.TargetApi;
    import android.content.Context;
    import android.content.res.Resources;
    import android.media.AudioManager;
    import android.media.MediaRecorder;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Handler;
    import android.os.Message;
    import android.os.SystemClock;
    import android.telephony.PhoneStateListener;
    import android.telephony.TelephonyManager;
    import android.text.TextUtils;
    import android.util.Log;
    
    import java.io.File;
    
    public class AudioRecordManager implements Handler.Callback {
        private static final String TAG = "LQR_AudioRecordManager";
        private int RECORD_INTERVAL;
        private String SAVE_PATH;
        private IAudioState mCurAudioState;
        private Context mContext;
        private Handler mHandler;
        private AudioManager mAudioManager;
        private MediaRecorder mMediaRecorder;
        private Uri mAudioPath;
        private long smStartRecTime;
        private AudioManager.OnAudioFocusChangeListener mAfChangeListener;
        IAudioState idleState;
        IAudioState recordState;
        IAudioState sendingState;
        IAudioState cancelState;
        IAudioState timerState;
        private IAudioRecordListener mAudioRecordListener;
        public static AudioRecordManager mInstance;
    
        public static AudioRecordManager getInstance(Context context) {
            if (mInstance == null) {
                Class var1 = AudioRecordManager.class;
                synchronized(AudioRecordManager.class) {
                    if (mInstance == null) {
                        mInstance = new AudioRecordManager(context);
                    }
                }
            }
    
            return mInstance;
        }
    
        @TargetApi(21)
        private AudioRecordManager(Context context) {
            this.mContext = context;
            this.mHandler = new Handler(this);
            this.RECORD_INTERVAL = 60;
            this.idleState = new AudioRecordManager.IdleState();
            this.recordState = new AudioRecordManager.RecordState();
            this.sendingState = new AudioRecordManager.SendingState();
            this.cancelState = new AudioRecordManager.CancelState();
            this.timerState = new AudioRecordManager.TimerState();
            if (Build.VERSION.SDK_INT < 21) {
                try {
                    TelephonyManager e = (TelephonyManager)this.mContext.getSystemService("phone");
                    e.listen(new PhoneStateListener() {
                        public void onCallStateChanged(int state, String incomingNumber) {
                            switch(state) {
                                case 1:
                                    AudioRecordManager.this.sendEmptyMessage(6);
                                case 0:
                                case 2:
                                default:
                                    super.onCallStateChanged(state, incomingNumber);
                            }
                        }
                    }, 32);
                } catch (SecurityException var3) {
                    var3.printStackTrace();
                }
            }
    
            this.mCurAudioState = this.idleState;
            this.idleState.enter();
        }
    
        public final boolean handleMessage(Message msg) {
            Log.i("LQR_AudioRecordManager", "handleMessage " + msg.what);
            AudioStateMessage m;
            switch(msg.what) {
                case 2:
                    this.sendEmptyMessage(2);
                    break;
                case 7:
                    m = AudioStateMessage.obtain();
                    m.what = msg.what;
                    m.obj = msg.obj;
                    this.sendMessage(m);
                    break;
                case 8:
                    m = AudioStateMessage.obtain();
                    m.what = 7;
                    m.obj = msg.obj;
                    this.sendMessage(m);
            }
    
            return false;
        }
    
        private void initView() {
            if (this.mAudioRecordListener != null) {
                this.mAudioRecordListener.initTipView();
            }
    
        }
    
        private void setTimeoutView(int counter) {
            if (this.mAudioRecordListener != null) {
                this.mAudioRecordListener.setTimeoutTipView(counter);
            }
    
        }
    
        private void setRecordingView() {
            if (this.mAudioRecordListener != null) {
                this.mAudioRecordListener.setRecordingTipView();
            }
    
        }
    
        private void setCancelView() {
            if (this.mAudioRecordListener != null) {
                this.mAudioRecordListener.setCancelTipView();
            }
    
        }
    
        private void destroyView() {
            Log.d("LQR_AudioRecordManager", "destroyTipView");
            this.mHandler.removeMessages(7);
            this.mHandler.removeMessages(8);
            this.mHandler.removeMessages(2);
            if (this.mAudioRecordListener != null) {
                this.mAudioRecordListener.destroyTipView();
            }
    
        }
    
        public void setMaxVoiceDuration(int maxVoiceDuration) {
            this.RECORD_INTERVAL = maxVoiceDuration;
        }
    
        public void setAudioSavePath(String path) {
            if (TextUtils.isEmpty(path)) {
                this.SAVE_PATH = this.mContext.getCacheDir().getAbsolutePath();
            } else {
                this.SAVE_PATH = path;
            }
    
        }
    
        public int getMaxVoiceDuration() {
            return this.RECORD_INTERVAL;
        }
    
        public void startRecord() {
            this.mAudioManager = (AudioManager)this.mContext.getSystemService("audio");
            if (this.mAfChangeListener != null) {
                this.mAudioManager.abandonAudioFocus(this.mAfChangeListener);
                this.mAfChangeListener = null;
            }
    
            this.mAfChangeListener = new AudioManager.OnAudioFocusChangeListener() {
                public void onAudioFocusChange(int focusChange) {
                    Log.d("LQR_AudioRecordManager", "OnAudioFocusChangeListener " + focusChange);
                    if (focusChange == -1) {
                        AudioRecordManager.this.mAudioManager.abandonAudioFocus(AudioRecordManager.this.mAfChangeListener);
                        AudioRecordManager.this.mAfChangeListener = null;
                        AudioRecordManager.this.sendEmptyMessage(6);
                    }
    
                }
            };
            this.sendEmptyMessage(1);
            if (this.mAudioRecordListener != null) {
                this.mAudioRecordListener.onStartRecord();
            }
    
        }
    
        public void willCancelRecord() {
            this.sendEmptyMessage(3);
        }
    
        public void continueRecord() {
            this.sendEmptyMessage(4);
        }
    
        public void stopRecord() {
            this.sendEmptyMessage(5);
        }
    
        public void destroyRecord() {
            AudioStateMessage msg = new AudioStateMessage();
            msg.obj = true;
            msg.what = 5;
            this.sendMessage(msg);
        }
    
        void sendMessage(AudioStateMessage message) {
            this.mCurAudioState.handleMessage(message);
        }
    
        void sendEmptyMessage(int event) {
            AudioStateMessage message = AudioStateMessage.obtain();
            message.what = event;
            this.mCurAudioState.handleMessage(message);
        }
    
        private void startRec() {
            Log.d("LQR_AudioRecordManager", "startRec");
    
            try {
                this.muteAudioFocus(this.mAudioManager, true);
                this.mAudioManager.setMode(0);
                this.mMediaRecorder = new MediaRecorder();
    
                try {
                    int bps = 7950;
                    this.mMediaRecorder.setAudioSamplingRate(8000);
                    this.mMediaRecorder.setAudioEncodingBitRate(bps);
                } catch (Resources.NotFoundException var2) {
                    var2.printStackTrace();
                }
    
                this.mMediaRecorder.setAudioChannels(1);
                this.mMediaRecorder.setAudioSource(1);
                this.mMediaRecorder.setOutputFormat(3);
                this.mMediaRecorder.setAudioEncoder(1);
                this.mAudioPath = Uri.fromFile(new File(this.SAVE_PATH, System.currentTimeMillis() + "temp.voice"));
                this.mMediaRecorder.setOutputFile(this.mAudioPath.getPath());
                this.mMediaRecorder.prepare();
                this.mMediaRecorder.start();
                Message e1 = Message.obtain();
                e1.what = 7;
                e1.obj = 10;
                this.mHandler.sendMessageDelayed(e1, (long)(this.RECORD_INTERVAL * 1000 - 10000));
            } catch (Exception var3) {
                var3.printStackTrace();
            }
    
        }
    
        private boolean checkAudioTimeLength() {
            long delta = SystemClock.elapsedRealtime() - this.smStartRecTime;
            return delta < 1000L;
        }
    
        private void stopRec() {
            Log.d("LQR_AudioRecordManager", "stopRec");
    
            try {
                this.muteAudioFocus(this.mAudioManager, false);
                if (this.mMediaRecorder != null) {
                    this.mMediaRecorder.stop();
                    this.mMediaRecorder.release();
                    this.mMediaRecorder = null;
                }
            } catch (Exception var2) {
                var2.printStackTrace();
            }
    
        }
    
        private void deleteAudioFile() {
            Log.d("LQR_AudioRecordManager", "deleteAudioFile");
            if (this.mAudioPath != null) {
                File file = new File(this.mAudioPath.getPath());
                if (file.exists()) {
                    file.delete();
                }
            }
    
        }
    
        private void finishRecord() {
            Log.d("LQR_AudioRecordManager", "finishRecord path = " + this.mAudioPath);
            if (this.mAudioRecordListener != null) {
                int duration = (int)(SystemClock.elapsedRealtime() - this.smStartRecTime) / 1000;
                this.mAudioRecordListener.onFinish(this.mAudioPath, duration);
            }
    
        }
    
        private void audioDBChanged() {
            if (this.mMediaRecorder != null) {
                int db = this.mMediaRecorder.getMaxAmplitude() / 600;
                if (this.mAudioRecordListener != null) {
                    this.mAudioRecordListener.onAudioDBChanged(db);
                }
            }
    
        }
    
        private void muteAudioFocus(AudioManager audioManager, boolean bMute) {
            if (Build.VERSION.SDK_INT < 8) {
                Log.d("LQR_AudioRecordManager", "muteAudioFocus Android 2.1 and below can not stop music");
            } else if (bMute) {
                audioManager.requestAudioFocus(this.mAfChangeListener, 3, 2);
            } else {
                audioManager.abandonAudioFocus(this.mAfChangeListener);
                this.mAfChangeListener = null;
            }
    
        }
    
        public IAudioRecordListener getAudioRecordListener() {
            return this.mAudioRecordListener;
        }
    
        public void setAudioRecordListener(IAudioRecordListener audioRecordListener) {
            this.mAudioRecordListener = audioRecordListener;
        }
    
        class IdleState extends IAudioState {
            public IdleState() {
                Log.d("LQR_AudioRecordManager", "IdleState");
            }
    
            void enter() {
                super.enter();
                if (AudioRecordManager.this.mHandler != null) {
                    AudioRecordManager.this.mHandler.removeMessages(7);
                    AudioRecordManager.this.mHandler.removeMessages(8);
                    AudioRecordManager.this.mHandler.removeMessages(2);
                }
    
            }
    
            void handleMessage(AudioStateMessage msg) {
                Log.d("LQR_AudioRecordManager", "IdleState handleMessage : " + msg.what);
                switch(msg.what) {
                    case 1:
                        AudioRecordManager.this.initView();
                        AudioRecordManager.this.setRecordingView();
                        AudioRecordManager.this.startRec();
                        AudioRecordManager.this.smStartRecTime = SystemClock.elapsedRealtime();
                        AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.recordState;
                        AudioRecordManager.this.sendEmptyMessage(2);
                    default:
                }
            }
        }
    
        class RecordState extends IAudioState {
            RecordState() {
            }
    
            void handleMessage(AudioStateMessage msg) {
                Log.d("LQR_AudioRecordManager", this.getClass().getSimpleName() + " handleMessage : " + msg.what);
                switch(msg.what) {
                    case 2:
                        AudioRecordManager.this.audioDBChanged();
                        AudioRecordManager.this.mHandler.sendEmptyMessageDelayed(2, 150L);
                        break;
                    case 3:
                        AudioRecordManager.this.setCancelView();
                        AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.cancelState;
                    case 4:
                    default:
                        break;
                    case 5:
                        final boolean checked = AudioRecordManager.this.checkAudioTimeLength();
                        boolean activityFinished = false;
                        if (msg.obj != null) {
                            activityFinished = (Boolean)msg.obj;
                        }
    
                        if (checked && !activityFinished) {
                            if (AudioRecordManager.this.mAudioRecordListener != null) {
                                AudioRecordManager.this.mAudioRecordListener.setAudioShortTipView();
                            }
    
                            AudioRecordManager.this.mHandler.removeMessages(2);
                        }
    
                        if (!activityFinished && AudioRecordManager.this.mHandler != null) {
                            AudioRecordManager.this.mHandler.postDelayed(new Runnable() {
                                public void run() {
                                    AudioStateMessage message = AudioStateMessage.obtain();
                                    message.what = 9;
                                    message.obj = !checked;
                                    AudioRecordManager.this.sendMessage(message);
                                }
                            }, 500L);
                            AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.sendingState;
                        } else {
                            AudioRecordManager.this.stopRec();
                            if (!checked && activityFinished) {
                                AudioRecordManager.this.finishRecord();
                            }
    
                            AudioRecordManager.this.destroyView();
                            AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.idleState;
                        }
                        break;
                    case 6:
                        AudioRecordManager.this.stopRec();
                        AudioRecordManager.this.destroyView();
                        AudioRecordManager.this.deleteAudioFile();
                        AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.idleState;
                        AudioRecordManager.this.idleState.enter();
                        break;
                    case 7:
                        int counter = (Integer)msg.obj;
                        AudioRecordManager.this.setTimeoutView(counter);
                        AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.timerState;
                        if (counter > 0) {
                            Message message = Message.obtain();
                            message.what = 8;
                            message.obj = counter - 1;
                            AudioRecordManager.this.mHandler.sendMessageDelayed(message, 1000L);
                        } else {
                            AudioRecordManager.this.mHandler.postDelayed(new Runnable() {
                                public void run() {
                                    AudioRecordManager.this.stopRec();
                                    AudioRecordManager.this.finishRecord();
                                    AudioRecordManager.this.destroyView();
                                }
                            }, 500L);
                            AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.idleState;
                        }
                }
    
            }
        }
    
        class SendingState extends IAudioState {
            SendingState() {
            }
    
            void handleMessage(AudioStateMessage message) {
                Log.d("LQR_AudioRecordManager", "SendingState handleMessage " + message.what);
                switch(message.what) {
                    case 9:
                        AudioRecordManager.this.stopRec();
                        if ((Boolean)message.obj) {
                            AudioRecordManager.this.finishRecord();
                        }
    
                        AudioRecordManager.this.destroyView();
                        AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.idleState;
                    default:
                }
            }
        }
    
        class CancelState extends IAudioState {
            CancelState() {
            }
    
            void handleMessage(AudioStateMessage msg) {
                Log.d("LQR_AudioRecordManager", this.getClass().getSimpleName() + " handleMessage : " + msg.what);
                switch(msg.what) {
                    case 1:
                    case 2:
                    case 3:
                    default:
                        break;
                    case 4:
                        AudioRecordManager.this.setRecordingView();
                        AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.recordState;
                        AudioRecordManager.this.sendEmptyMessage(2);
                        break;
                    case 5:
                    case 6:
                        AudioRecordManager.this.stopRec();
                        AudioRecordManager.this.destroyView();
                        AudioRecordManager.this.deleteAudioFile();
                        AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.idleState;
                        AudioRecordManager.this.idleState.enter();
                        break;
                    case 7:
                        int counter = (Integer)msg.obj;
                        if (counter > 0) {
                            Message message = Message.obtain();
                            message.what = 8;
                            message.obj = counter - 1;
                            AudioRecordManager.this.mHandler.sendMessageDelayed(message, 1000L);
                        } else {
                            AudioRecordManager.this.mHandler.postDelayed(new Runnable() {
                                public void run() {
                                    AudioRecordManager.this.stopRec();
                                    AudioRecordManager.this.finishRecord();
                                    AudioRecordManager.this.destroyView();
                                }
                            }, 500L);
                            AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.idleState;
                            AudioRecordManager.this.idleState.enter();
                        }
                }
    
            }
        }
    
        class TimerState extends IAudioState {
            TimerState() {
            }
    
            void handleMessage(AudioStateMessage msg) {
                Log.d("LQR_AudioRecordManager", this.getClass().getSimpleName() + " handleMessage : " + msg.what);
                switch(msg.what) {
                    case 3:
                        AudioRecordManager.this.setCancelView();
                        AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.cancelState;
                    case 4:
                    default:
                        break;
                    case 5:
                        AudioRecordManager.this.mHandler.postDelayed(new Runnable() {
                            public void run() {
                                AudioRecordManager.this.stopRec();
                                AudioRecordManager.this.finishRecord();
                                AudioRecordManager.this.destroyView();
                            }
                        }, 500L);
                        AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.idleState;
                        AudioRecordManager.this.idleState.enter();
                        break;
                    case 6:
                        AudioRecordManager.this.stopRec();
                        AudioRecordManager.this.destroyView();
                        AudioRecordManager.this.deleteAudioFile();
                        AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.idleState;
                        AudioRecordManager.this.idleState.enter();
                        break;
                    case 7:
                        int counter = (Integer)msg.obj;
                        if (counter > 0) {
                            Message message = Message.obtain();
                            message.what = 8;
                            message.obj = counter - 1;
                            AudioRecordManager.this.mHandler.sendMessageDelayed(message, 1000L);
                            AudioRecordManager.this.setTimeoutView(counter);
                        } else {
                            AudioRecordManager.this.mHandler.postDelayed(new Runnable() {
                                public void run() {
                                    AudioRecordManager.this.stopRec();
                                    AudioRecordManager.this.finishRecord();
                                    AudioRecordManager.this.destroyView();
                                }
                            }, 500L);
                            AudioRecordManager.this.mCurAudioState = AudioRecordManager.this.idleState;
                        }
                }
    
            }
        }
    }

    AudioPlayManager

    package com.badao.audiodemo.audioHelper;
    
    import android.annotation.TargetApi;
    import android.content.Context;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.media.AudioManager;
    import android.media.MediaPlayer;
    import android.media.AudioManager.OnAudioFocusChangeListener;
    import android.media.MediaPlayer.OnCompletionListener;
    import android.media.MediaPlayer.OnErrorListener;
    import android.media.MediaPlayer.OnPreparedListener;
    import android.media.MediaPlayer.OnSeekCompleteListener;
    import android.net.Uri;
    import android.os.PowerManager;
    import android.os.Build.VERSION;
    import android.os.PowerManager.WakeLock;
    import android.util.Log;
    import java.io.IOException;
    
    public class AudioPlayManager implements SensorEventListener {
        private static final String TAG = "LQR_AudioPlayManager";
        private MediaPlayer _mediaPlayer;
        private IAudioPlayListener _playListener;
        private Uri _playingUri;
        private Sensor _sensor;
        private SensorManager _sensorManager;
        private AudioManager _audioManager;
        private PowerManager _powerManager;
        private WakeLock _wakeLock;
        private OnAudioFocusChangeListener afChangeListener;
        private Context context;
    
        public AudioPlayManager() {
        }
    
        public static AudioPlayManager getInstance() {
            return AudioPlayManager.SingletonHolder.sInstance;
        }
    
        @TargetApi(11)
        public void onSensorChanged(SensorEvent event) {
            float range = event.values[0];
            if (this._sensor != null && this._mediaPlayer != null) {
                if (this._mediaPlayer.isPlaying()) {
                    if ((double)range > 0.0D) {
                        if (this._audioManager.getMode() == 0) {
                            return;
                        }
    
                        this._audioManager.setMode(0);
                        this._audioManager.setSpeakerphoneOn(true);
                        final int positions = this._mediaPlayer.getCurrentPosition();
    
                        try {
                            this._mediaPlayer.reset();
                            this._mediaPlayer.setAudioStreamType(3);
                            this._mediaPlayer.setVolume(1.0F, 1.0F);
                            this._mediaPlayer.setDataSource(this.context, this._playingUri);
                            this._mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
                                public void onPrepared(MediaPlayer mp) {
                                    mp.seekTo(positions);
                                }
                            });
                            this._mediaPlayer.setOnSeekCompleteListener(new OnSeekCompleteListener() {
                                public void onSeekComplete(MediaPlayer mp) {
                                    mp.start();
                                }
                            });
                            this._mediaPlayer.prepareAsync();
                        } catch (IOException var5) {
                            var5.printStackTrace();
                        }
    
                        this.setScreenOn();
                    } else {
                        this.setScreenOff();
                        if (VERSION.SDK_INT >= 11) {
                            if (this._audioManager.getMode() == 3) {
                                return;
                            }
    
                            this._audioManager.setMode(3);
                        } else {
                            if (this._audioManager.getMode() == 2) {
                                return;
                            }
    
                            this._audioManager.setMode(2);
                        }
    
                        this._audioManager.setSpeakerphoneOn(false);
                        this.replay();
                    }
                } else if ((double)range > 0.0D) {
                    if (this._audioManager.getMode() == 0) {
                        return;
                    }
    
                    this._audioManager.setMode(0);
                    this._audioManager.setSpeakerphoneOn(true);
                    this.setScreenOn();
                }
            }
    
        }
    
        @TargetApi(21)
        private void setScreenOff() {
            if (this._wakeLock == null) {
                if (VERSION.SDK_INT >= 21) {
                    this._wakeLock = this._powerManager.newWakeLock(32, "AudioPlayManager");
                } else {
                    Log.e("LQR_AudioPlayManager", "Does not support on level " + VERSION.SDK_INT);
                }
            }
    
            if (this._wakeLock != null) {
                this._wakeLock.acquire();
            }
    
        }
    
        private void setScreenOn() {
            if (this._wakeLock != null) {
                this._wakeLock.setReferenceCounted(false);
                this._wakeLock.release();
                this._wakeLock = null;
            }
    
        }
    
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    
        private void replay() {
            try {
                this._mediaPlayer.reset();
                this._mediaPlayer.setAudioStreamType(0);
                this._mediaPlayer.setVolume(1.0F, 1.0F);
                this._mediaPlayer.setDataSource(this.context, this._playingUri);
                this._mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
                    public void onPrepared(MediaPlayer mp) {
                        mp.start();
                    }
                });
                this._mediaPlayer.prepareAsync();
            } catch (IOException var2) {
                var2.printStackTrace();
            }
    
        }
    
        public void startPlay(Context context, Uri audioUri, IAudioPlayListener playListener) {
            if (context != null && audioUri != null) {
                this.context = context;
                if (this._playListener != null && this._playingUri != null) {
                    this._playListener.onStop(this._playingUri);
                }
    
                this.resetMediaPlayer();
                this.afChangeListener = new OnAudioFocusChangeListener() {
                    public void onAudioFocusChange(int focusChange) {
                        Log.d("LQR_AudioPlayManager", "OnAudioFocusChangeListener " + focusChange);
                        if (AudioPlayManager.this._audioManager != null && focusChange == -1) {
                            AudioPlayManager.this._audioManager.abandonAudioFocus(AudioPlayManager.this.afChangeListener);
                            AudioPlayManager.this.afChangeListener = null;
                            AudioPlayManager.this.resetMediaPlayer();
                        }
    
                    }
                };
    
                try {
                    this._powerManager = (PowerManager)context.getSystemService("power");
                    this._audioManager = (AudioManager)context.getSystemService("audio");
                    if (!this._audioManager.isWiredHeadsetOn()) {
                        this._sensorManager = (SensorManager)context.getSystemService("sensor");
                        this._sensor = this._sensorManager.getDefaultSensor(8);
                        this._sensorManager.registerListener(this, this._sensor, 3);
                    }
    
                    this.muteAudioFocus(this._audioManager, true);
                    this._playListener = playListener;
                    this._playingUri = audioUri;
                    this._mediaPlayer = new MediaPlayer();
                    this._mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
                        public void onCompletion(MediaPlayer mp) {
                            if (AudioPlayManager.this._playListener != null) {
                                AudioPlayManager.this._playListener.onComplete(AudioPlayManager.this._playingUri);
                                AudioPlayManager.this._playListener = null;
                                AudioPlayManager.this.context = null;
                            }
    
                            AudioPlayManager.this.reset();
                        }
                    });
                    this._mediaPlayer.setOnErrorListener(new OnErrorListener() {
                        public boolean onError(MediaPlayer mp, int what, int extra) {
                            AudioPlayManager.this.reset();
                            return true;
                        }
                    });
                    this._mediaPlayer.setDataSource(context, audioUri);
                    this._mediaPlayer.setAudioStreamType(3);
                    this._mediaPlayer.prepare();
                    this._mediaPlayer.start();
                    if (this._playListener != null) {
                        this._playListener.onStart(this._playingUri);
                    }
                } catch (Exception var5) {
                    var5.printStackTrace();
                    if (this._playListener != null) {
                        this._playListener.onStop(audioUri);
                        this._playListener = null;
                    }
    
                    this.reset();
                }
            } else {
                Log.e("LQR_AudioPlayManager", "startPlay context or audioUri is null.");
            }
    
        }
    
        public void setPlayListener(IAudioPlayListener listener) {
            this._playListener = listener;
        }
    
        public void stopPlay() {
            if (this._playListener != null && this._playingUri != null) {
                this._playListener.onStop(this._playingUri);
            }
    
            this.reset();
        }
    
        private void reset() {
            this.resetMediaPlayer();
            this.resetAudioPlayManager();
        }
    
        private void resetAudioPlayManager() {
            if (this._audioManager != null) {
                this.muteAudioFocus(this._audioManager, false);
            }
    
            if (this._sensorManager != null) {
                this._sensorManager.unregisterListener(this);
            }
    
            this._sensorManager = null;
            this._sensor = null;
            this._powerManager = null;
            this._audioManager = null;
            this._wakeLock = null;
            this._playListener = null;
            this._playingUri = null;
        }
    
        private void resetMediaPlayer() {
            if (this._mediaPlayer != null) {
                try {
                    this._mediaPlayer.stop();
                    this._mediaPlayer.reset();
                    this._mediaPlayer.release();
                    this._mediaPlayer = null;
                } catch (IllegalStateException var2) {
                }
            }
    
        }
    
        public Uri getPlayingUri() {
            return this._playingUri;
        }
    
        @TargetApi(8)
        private void muteAudioFocus(AudioManager audioManager, boolean bMute) {
            if (VERSION.SDK_INT < 8) {
                Log.d("LQR_AudioPlayManager", "muteAudioFocus Android 2.1 and below can not stop music");
            } else if (bMute) {
                audioManager.requestAudioFocus(this.afChangeListener, 3, 2);
            } else {
                audioManager.abandonAudioFocus(this.afChangeListener);
                this.afChangeListener = null;
            }
    
        }
    
        static class SingletonHolder {
            static AudioPlayManager sInstance = new AudioPlayManager();
    
            SingletonHolder() {
            }
        }
    }

    AudioStateMessage

    package com.badao.audiodemo.audioHelper;
    
    public class AudioStateMessage {
        public int what;
        public Object obj;
    
        public AudioStateMessage() {
        }
    
        public static AudioStateMessage obtain() {
            return new AudioStateMessage();
        }
    }

    IAudioPlayListener

    package com.badao.audiodemo.audioHelper;
    
    import android.net.Uri;
    
    public interface IAudioPlayListener {
        void onStart(Uri var1);
    
        void onStop(Uri var1);
    
        void onComplete(Uri var1);
    }

    IAudioRecordListener

    package com.badao.audiodemo.audioHelper;
    
    import android.net.Uri;
    
    public interface IAudioRecordListener {
        void initTipView();
    
        void setTimeoutTipView(int var1);
    
        void setRecordingTipView();
    
        void setAudioShortTipView();
    
        void setCancelTipView();
    
        void destroyTipView();
    
        void onStartRecord();
    
        void onFinish(Uri var1, int var2);
    
        void onAudioDBChanged(int var1);
    }

    IAudioState

    package com.badao.audiodemo.audioHelper;
    
    public abstract class IAudioState {
        public IAudioState() {
        }
    
        void enter() {
        }
    
        abstract void handleMessage(AudioStateMessage var1);
    }

    录音功能实现

    打开MainActivity,声明audioRecordManager

    private AudioRecordManager audioRecordManager;

    然后在onCreate中对其进行初始化

        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            audioRecordManager = AudioRecordManager.getInstance(MainActivity.this);
            File file = new File(MainActivity.this.getExternalFilesDir("voice").getAbsolutePath());
            if (!file.exists()) {
                file.mkdirs();
            }
            //设置录音文件保存路径
            audioRecordManager.setAudioSavePath(file.getAbsolutePath());
            //设置监听器
            audioRecordManager.setAudioRecordListener(recordListener);

    初始化之后设置其录音文件的的保存路径和监听器

    所以需要先声明并初始化一个监听器

        private final IAudioRecordListener recordListener = new IAudioRecordListener() {
    
            @Override
            public void initTipView() {
    
            }
    
            @Override
            public void setTimeoutTipView(int i) {
    
            }
    
            @Override
            public void setRecordingTipView() {
    
            }
    
            @Override
            public void setAudioShortTipView() {
    
            }
    
            @Override
            public void setCancelTipView() {
    
            }
    
            @Override
            public void destroyTipView() {
    
            }
    
            @Override
            public void onStartRecord() {
    
            }
    
            @Override
            public void onFinish(Uri uri, int i) {
                File file = new File(uri.getPath());
                //获取文件时长
                int voiceDuration = 0;
                try {
                    meidaPlayer.setDataSource(uri.getPath());
                    meidaPlayer.prepare();
                    int time = meidaPlayer.getDuration();//获得了时长(以毫秒为单位)
                    voiceDuration = time / 1000;
                    if (voiceDuration < 1) {
                        voiceDuration = 1;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    meidaPlayer.reset();
                }
                ChatBean.ChatItem chatItem = new ChatBean.ChatItem();
    
                chatItem.setId((int) System.currentTimeMillis());
                chatItem.setSendTime(new Date().toString());
                chatItem.setContent(file.getAbsolutePath());
                //存储语音文件时长
                chatItem.setVoiceDuration(voiceDuration);
    
                chatItemList.add(chatItem);
                chatAdapter.setmEntityList(chatItemList);
    
            }
    
            @Override
            public void onAudioDBChanged(int i) {
    
            }
        };

    在监听器中重写的onFinish方法就是录音结束后的回调方法,Uri就是录音文件的路径

    在此方法中获取录音的时长以及设置一些其他参数,然后将其通过Adapter给RecyclerView进行赋值。

    关于Android中使用Adapter(适配器)给RecycleView设置数据源:

    参考如下:

    https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/110926089

    然后在MainActivity中的imageView的Touch事件中

            audioImageView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    if(motionEvent.getAction() == MotionEvent.ACTION_DOWN)
                    {
                        Toast.makeText(MainActivity.this,"录音开始",Toast.LENGTH_SHORT).show();
                        audioRecordManager.startRecord();
                        return true;
                    }else if(motionEvent.getAction() == MotionEvent.ACTION_UP)
                    {
                        Toast.makeText(MainActivity.this,"录音结束",Toast.LENGTH_SHORT).show();
                        audioRecordManager.stopRecord();
                        return true;
                    }
                    return false;
                }
            });

    实现开始录音与结束录音。

    录音播放功能

    参照上面录音结束后使用adapter给recyclerView设置数据源的方式,在ChatAdapter中重写的

    onBindViewHolder中

       @Override
        public void onBindViewHolder(@NonNull ChatViewHolder holder, int position) {
            holder.mText.setText(mEntityList.get(position).getContent().toString());
            //设置每一项的点击事件
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    File file = new File(mEntityList.get(position).getContent());
                    //播放音频文件
                    audioPlayManager.startPlay(App.context, Uri.fromFile(file), new IAudioPlayListener() {
                        @Override
                        public void onStart(Uri uri1) {
    
                        }
    
                        @Override
                        public void onStop(Uri uri1) {
    
                        }
    
                        @Override
                        public void onComplete(Uri uri1) {
    
                        }
                    });
                }
            });
        }

    设置每一项的点击事件并播放音频文件

    在播放的方法startPlay中第一个参数为context,为了获取Context,参照如下

    Android中怎样在工具类中获取Context对象:

    https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/110817765

    示例代码下载

    https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/13609812

  • 相关阅读:
    模块化项目
    mysql mybatis-generator plugin 有page实体类的分页
    mysql mybatis-generator plugin 分页
    eclipse中mybatis generator插件的安装与使用,实现自动生成代码
    linux下安装mysql5.7.17及简单配置
    mybatis-mysql操作存储过程
    解决JSP路径问题的方法(jsp文件开头path, basePath作用)
    windows下开启mysql远程访问
    Java中hashCode的作用
    垃圾收集器与内存分配策略 (深入理解JVM二)
  • 原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/14109526.html
Copyright © 2020-2023  润新知