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

原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/14109526.html