SoundPool 仅在第一次播放声音
Posted
技术标签:
【中文标题】SoundPool 仅在第一次播放声音【英文标题】:SoundPool plays sound only the first time 【发布时间】: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
此警告仅在第一次点击时出现。
【问题讨论】:
【参考方案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);
希望对您有所帮助。
【讨论】:
以上是关于SoundPool 仅在第一次播放声音的主要内容,如果未能解决你的问题,请参考以下文章