2017-06-12 250 views
1

我想每一個視圖被點擊時播放聲音:的Soundpool播放聲音只在第一次

我創建了一個簡單的效應播放:

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); 
} 

} 

我打電話EffectManager.initonCreate事件的我活動。然後我添加這個聽衆我的意見:

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

我可以聽到聲音時,我只點擊第一個視圖。我嘗試了點擊視圖的不同順序,聲音僅用於第一次點擊。除了此警告外,控制檯上沒有任何消息錯誤。 :

W/AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by server 

此警告僅在第一次單擊時出現。

回答

0

我有同樣的問題,我認爲在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); 

我希望這可以幫助您。