【问题标题】:SoundPool plays sound only the first timeSoundPool 仅在第一次播放声音
【发布时间】:2017-06-12 15:49:58
【问题描述】:

我想在每次点击视图时播放声音:

我创建了一个简单的效果播放器:

public class EffectManager {

private static SoundPool soundPool;
private static int puzzlePieceOK;
private static int puzzleOK;


public static void init(Context context) {
    if (soundPool == null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            soundPool = new SoundPool.Builder()
                    .setAudioAttributes(new AudioAttributes.Builder()
                            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                            .setUsage(AudioAttributes.USAGE_GAME)
                            .build()
                    )
                    .setMaxStreams(10)
                    .build();
        }
        else {
            soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
        }
        puzzlePieceOK = soundPool.load(context,R.raw.puzzle_piece_ok,1);
        puzzleOK = soundPool.load(context,R.raw.puzzle_ok,1);
    }
}

public static void playPuzzlePieceOK() {
    soundPool.play(puzzlePieceOK,10,10, 1,0,1);
}

public static void playPuzzleOK() {
    soundPool.play(puzzleOK,10,10, 1,1,1);
}

}

我在我的活动的onCreate 事件上致电EffectManager.init。然后我将此侦听器添加到我的视图中:

setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            EffectManager.playPuzzlePieceOK();
        }
    });   

当我只点击第一个视图时,我可以听到声音。我尝试了不同的单击视图顺序,声音仅在第一次单击时播放。除了这个警告,我在控制台上没有任何消息错误。 :

W/AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by server

此警告仅在第一次点击时出现。

【问题讨论】:

    标签: android soundpool


    【解决方案1】:

    我也有同样的问题,我认为使用 SDK >= LOLLIPOP 的 SoundPool 中存在问题。 我找不到一个完美的解决方案,但一个很好的解决方法。 我解决了,重新加载原始内容再播放。

    我正在使用我的类 SoundManager,它很有用。

    import java.util.HashMap;
    import java.util.Iterator;
    
    import android.content.Context;
    import android.media.AudioAttributes;
    import android.media.AudioManager;
    import android.media.SoundPool;
    import android.os.Build;
    
    import it.aldea.android.Log;
    import it.aldea.util.Utils;
    
    public class SoundManager {
    
        private SoundPool mSoundPool;
        private HashMap<Integer, Integer> mSoundPoolMap;
        private AudioManager mAudioManager;
        private Context mContext;
        private int streamId;
        private boolean initialized = false;
        protected Log log;
    
        public SoundManager() {
            mSoundPoolMap = new HashMap<Integer, Integer>();
        }
    
        public SoundManager(Log log) {
            this();
            this.log = log;
        }
    
        public void initSounds(Context theContext) {
            mContext = theContext;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mSoundPool = new SoundPool.Builder()
                        .setAudioAttributes(new AudioAttributes.Builder()
                                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                                .setUsage(AudioAttributes.USAGE_GAME)
                                .build()
                        )
                        .setMaxStreams(10)
                        .build();
            } else {
                mSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
            }
            mSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
    
                @Override
                public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                    initialized = true;
                }
            });
            mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        }
    
        public void reset() {
            //initSounds(mContext);
            reloadSound();
        }
    
        public void reloadSound() {
            Iterator iterator = mSoundPoolMap.keySet().iterator();
            while (iterator.hasNext()) {
                int soundID = (Integer) iterator.next();
                mSoundPoolMap.put(soundID, mSoundPool.load(mContext, soundID, 1));
            }
        }
    
        public void addSound(int soundID) {
            mSoundPoolMap.put(soundID, mSoundPool.load(mContext, soundID, 1));
        }
    
        public void clearSounds() {
            mSoundPoolMap.clear();
        }
    
    
        private void waitInit() {
    
            for (int i = 0; !isInitialized() && i < 10; i++) {
                    if (log != null && log.isDebugEnabled()) log.d("Wait SoundPool initialized n." + i);
                    Utils.sleep(100);
            }
            if (!isInitialized()) {
                if (log != null) {
                    log.e("SoundPool NOT initialized");
                } else {
                    System.err.println("SoundPool NOT initialized");
                }
            }
        }
    
        public void playSingleSound(int resourceId, boolean forever) {
            int repeat = forever ? -1 : 0;
            int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
            waitInit();
            for (int i = 0; i < 3; i++) {
                int poolId = mSoundPoolMap.get(resourceId);
                streamId = mSoundPool.play(poolId, streamVolume, streamVolume, 1, repeat, 1f);
                if (streamId > 0) {
                    break;
                } else {
                    Utils.sleep(300);
                }
            }
            if (streamId == 0) {
                if (log != null) {
                    log.e("playSound without streamId for index :" + resourceId);
                }
            }
        }
    
        public void playSound(int index) {
            playSingleSound(index, false);
        }
    
        public void playLoopedSound(int index) {
            if (log != null && log.isDebugEnabled()) {
                log.d("playLoopedSound soundId:" + index);
            }
            playSingleSound(index, true);
        }
    
        public void stopLastSound() {
            if (log != null && log.isDebugEnabled()) {
                log.d("stopLastSound");
            }
            if (streamId > 0) {
                mSoundPool.stop(streamId);
            }
            streamId = 0;
        }
    
        public boolean isInitialized() {
            return initialized;
        }
    
        public void setInitialized(boolean initialized) {
            this.initialized = initialized;
        }
    
        public void close() {
            mSoundPool.release();
        }
    }
    

    供使用:

    // Init
    mSoundManager = new SoundManager();
    mSoundManager.initSounds(getBaseContext());
    mSoundManager.addSound(R.raw.SOUND_BEEP2); 
    mSoundManager.addSound(R.raw.SOUND_BEEP);
    mSoundManager.addSound(R.raw.SOUND_ANNOYING_ALARM);
    
    
    // Use
    mSoundManager.reset();
    mSoundManager.playSound(R.raw.SOUND_BEEP2);
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多