使用SoundPool播放音频文件,使用简单

背景

在项目实际开发中,可能会遇到播放一段音频文件的需求,比如播放一段话,比如连续播放来电铃声等等,下面介绍使用SoundPool播放音频文件,工具类已封装好,复制粘贴即可使用

实现目标

1、播放音频文件,播放完即停止
2、播放音频文件,循环播放

说明

播放音频文件有很多种方式,MediaPlayer播放音频,AudioTrack播放音频,Ringtone播放音频,SoundPool播放音频,此文章为SoundPool封装实例,复杂实现逻辑可以舍弃了,一句话即可实现播放音频


下边介绍下使用说明

1.播放指定音频文件,选择哪个播放哪个

AVChatSoundPlayer.instance().play(AVChatSoundPlayer.RingerTypeEnum.LY_CONNECT);

2.循环播放音频文件

public synchronized void play(RingerTypeEnum type) 
        this.ringerTypeEnum = type;
        int ringId = 0;
        switch (type) {
            case LY_CONNECT:
                ringId = R.raw.avchat_ly_connect;
                loop = false;//是否重复播放铃声
                break;
            case LY_CLOSE:
                ringId = R.raw.avchat_ly_close;
                loop = true;
                break;
        }
    }

将loop改成true,即循环播放
3.停止播放音频文件

AVChatSoundPlayer.instance().stop();

所需文件

1.新建raw目录,将所需要播放的音频文件放入,建议音频文件不要超过1M,因为在不同的系统下 SoundPool 表现可能存在不一致


raw.jpg

2.复制工具类AVChatSoundPlayer

/**
 * SoundPool 铃声尽量不要超过1M
 * 在不同的系统下 SoundPool 表现可能存在不一致
 */
public class AVChatSoundPlayer {

    private static final String TAG = "Lp_Player";

    public enum RingerTypeEnum {
        LY_CONNECT,
        LY_CLOSE,
        MEN_KAI,
        MEN_CLOSE,
        RING
        ;
    }
    private Context context;

    private SoundPool soundPool;
    private AudioManager audioManager;
    private int streamId;
    private int soundId;
    private boolean loop;
    private RingerTypeEnum ringerTypeEnum;
    private boolean isRingModeRegister = false;
    private int ringMode = -1;

    private static AVChatSoundPlayer instance = null;
    private RingModeChangeReceiver ringModeChangeReceiver;

    public static AVChatSoundPlayer instance() {
        if(instance == null) {
            synchronized (AVChatSoundPlayer.class) {
                if(instance == null) {
                    instance = new AVChatSoundPlayer();
                }
            }
        }
        return instance;
    }

    public AVChatSoundPlayer() {
        this.context = AppUMS.mContent;//全局上下文对象,getApplicationContext();
}

    public synchronized void play(RingerTypeEnum type) {
        L.e(TAG, "play type->" + type.name());
        this.ringerTypeEnum = type;
        int ringId = 0;
        switch (type) {
            case LY_CONNECT:
                ringId = R.raw.avchat_ly_connect;
                loop = false;//是否重复播放铃声
                break;
            case LY_CLOSE:
                ringId = R.raw.avchat_ly_close;
                loop = false;
                break;
            case MEN_KAI:
                ringId = R.raw.avchat_men_kai;
                loop = false;
                break;
            case MEN_CLOSE:
                ringId = R.raw.avchat_men_close;
                loop = false;
                break;
            case RING:
                ringId = R.raw.avchat_ring;
                loop = true;
                break;
        }

        if(ringId != 0) {
            play(ringId);
        }
    }

    public void stop() {
        L.e(TAG, "stop");
        if (soundPool != null) {
            if (streamId != 0) {
                soundPool.stop(streamId);
                streamId = 0;
            }
            if (soundId != 0) {
                soundPool.unload(soundId);
                soundId = 0;
            }
        }
        if (isRingModeRegister) {
            registerVolumeReceiver(false);
        }
    }

    private void play(int ringId) {
        initSoundPool();
        if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
            soundId = soundPool.load(context, ringId, 1);
        }
    }

    private void initSoundPool() {
        stop();
        if (soundPool == null) {
            soundPool = new SoundPool(1, AudioManager.STREAM_RING, 0);
            soundPool.setOnLoadCompleteListener(onLoadCompleteListener);

            audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            ringMode = audioManager.getRingerMode();
        }
        registerVolumeReceiver(true);
    }

    SoundPool.OnLoadCompleteListener onLoadCompleteListener = new SoundPool.OnLoadCompleteListener() {
        @Override
        public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
            if (soundId != 0 && status == 0) {
                if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
                    int curVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
                    streamId = soundPool.play(soundId, curVolume, curVolume, 1, loop ? -1 : 0, 1f);
                }
            }
        }
    };

    private void registerVolumeReceiver(boolean register){
        if (ringModeChangeReceiver == null) {
            ringModeChangeReceiver = new RingModeChangeReceiver() ;
        }

        if (register) {
            isRingModeRegister = true;
            IntentFilter filter = new IntentFilter() ;
            filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION) ;
            context.registerReceiver(ringModeChangeReceiver, filter) ;
        } else {
            context.unregisterReceiver(ringModeChangeReceiver);
            isRingModeRegister = false;
        }
    }

    private class RingModeChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (ringMode != -1 && ringMode != audioManager.getRingerMode()
                    && intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
                ringMode = audioManager.getRingerMode();
                play(ringerTypeEnum);
            }
        }
    }
}

最后,祝大家开发顺利!

你可能感兴趣的:(使用SoundPool播放音频文件,使用简单)