创新实训——第六周1

这次首先实现了播放音频的功能,日后用于语音聊天,通过自定义一个AudioPlayManager类来实现这个功能。

/**
     * 播放音频文件
     *
     * @param path     音频文件路径
     * @param listener 播放监听器
     */
    public static void playAudio(Context context, final String path, final OnPlayAudioListener listener) {

        if (sAudioManager == null) {
            sAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        }

        assert sAudioManager != null;
        sAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);

        if (sMediaPlayer == null) {
            sMediaPlayer = new MediaPlayer();
        } else {
            if (sMediaPlayer.isPlaying()) {
                sMediaPlayer.stop();
            }
            sMediaPlayer.reset();
        }

        sMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mp.start();
                if (listener != null) {
                    listener.onPlay();
                }
            }
        });

        sMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                if (listener != null) {
                    listener.onError("播放出错,错误码:" + what);
                }
                return false;
            }
        });

        sMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                if (listener != null) {
                    listener.onComplete();
                }
            }
        });

        try {
            int focus = sAudioManager.requestAudioFocus(null,
                    AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
            if (focus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                sMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                sMediaPlayer.setDataSource(path);
                sMediaPlayer.prepare();
            } else if (focus == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
                if (listener != null) {
                    listener.onError("播放出错:" + "AUDIOFOCUS_REQUEST_FAILED");
                }
            }
        } catch (Exception e) {
            if (listener != null) {
                listener.onError("播放出错:" + e.getMessage());
            }
            release();
        }

    }

其中的listener监听器的接口

public interface OnPlayAudioListener {
        void onPlay();

        void onComplete();

        void onError(String message);
    }

接口的实现

AudioPlayManager.playAudio(this, audioAttachment.getPath(),
                new AudioPlayManager.OnPlayAudioListener() {
                    @Override
                    public void onPlay() {
                        // 启动播放动画
                        isAudioPlay = true;
                        mPlayId = message.getUuid();
                        mAudioPlayHandler.startAudioAnim(imageView, isLeft);
                    }

                    @Override
                    public void onComplete() {
                        isAudioPlay = false;
                        mPlayId = "";
                        mAudioPlayHandler.stopAnimTimer();
                    }

                    @Override
                    public void onError(String message) {
                        isAudioPlay = false;
                        mPlayId = "";
                        mAudioPlayHandler.stopAnimTimer();
                        ToastUtils.showMessage(P2PChatActivity.this, message);
                    }
                });

暂停播放,在contex生命周期onPause中调用

public static void pause() {
        if (sMediaPlayer != null && sMediaPlayer.isPlaying()) { //正在播放的时候
            sMediaPlayer.pause();
            isPause = true;
        }

        if (sAudioManager != null) {
            sAudioManager.abandonAudioFocus(null);
        }
    }

恢复播放,在contex生命周期onResume中调用

public static void resume() {
        if (sMediaPlayer != null && isPause) {
            if (sAudioManager != null) {
                int focus = sAudioManager.requestAudioFocus(null,
                        AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
                if (focus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                    sMediaPlayer.start();
                    isPause = false;
                }
            }

        }
    }

释放资源,在context生命周期onDestroy中调用

public static void release() {
        if (sMediaPlayer != null) {
            sMediaPlayer.release();
            sMediaPlayer = null;
        }

        if (sAudioManager != null) {
            sAudioManager.abandonAudioFocus(null);
            sAudioManager = null;
        }
    }

然后自定义了一个Handler用来播放音频文件,并通过更新界面实现动画效果。

    //语音动画控制器
    private Timer mTimer = null;
    //语音动画控制任务
    private TimerTask mTimerTask = null;
    //记录语音动画图片索引
    private int index = 0;
    //根据 index 更换动画
    private AudioAnimHandler mAudioAnimHandler = null;

类的构造方法继承自Handler:

private static class AudioAnimHandler extends Handler {

        private final ImageView mIvAudio;
        private final boolean isLeft;

        private int[] mLeftIndex = {
                R.mipmap.sound_left_1,R.mipmap.sound_left_2,R.mipmap.sound_left_3};

        private int[] mRightIndex = {
                R.mipmap.sound_right_1, R.mipmap.sound_right_2,R.mipmap.sound_right_3};

        AudioAnimHandler(ImageView imageView,boolean isLeft){
            this.mIvAudio = imageView;
            this.isLeft = isLeft;
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                    mIvAudio.setImageResource(isLeft? mLeftIndex[0]:mRightIndex[0]);
                    break;
                case 1:
                    mIvAudio.setImageResource(isLeft? mLeftIndex[1]:mRightIndex[1]);
                    break;
                case 2:
                    mIvAudio.setImageResource(isLeft? mLeftIndex[2]:mRightIndex[2]);
                    break;
                default:
                    mIvAudio.setImageResource(isLeft? R.mipmap.sound_left_0:R.mipmap.sound_right_0);
                    removeCallbacks(null);
                    break;
            }
        }
    }

播放音频动画的方法:

 public void startAudioAnim(ImageView imageView,boolean isLeft){

        stopAnimTimer();

        // 语音播放动画效果
        mAudioAnimHandler = new AudioAnimHandler(imageView,isLeft);

        mTimerTask = new TimerTask() {
            @Override
            public void run() {
                mAudioAnimHandler.obtainMessage(index).sendToTarget();
                index = (index+1)%3;
            }
        };
        mTimer = new Timer();
        // 每半秒更新一次界面
        mTimer.schedule(mTimerTask,0,500);
    }

停止播放音频动画的方法:

public  void stopAnimTimer(){

        if (mTimer != null) {
            mTimer.cancel();
            mTimer = null;
        }

        if (mTimerTask != null) {
            mTimerTask.cancel();
            mTimerTask = null;
        }

        // 将上一个语音消息界面复位
        if (mAudioAnimHandler != null){
            mAudioAnimHandler.obtainMessage(3).sendToTarget();
        }
    }
在日后的编程中在需要播放音频的Java文件中调用这些类和方法。




展开阅读全文

没有更多推荐了,返回首页