2011-01-14 5 views
5

Android 2.2 이상에서는 SoundPool.OnLoadCompleteListener이라는 것이있어 사운드가 성공적으로로드되었는지 여부를 알 수 있습니다.Android 1.6/2.0/2.1에서 SoundPool로 사운드로드가 성공했는지 알 수 있습니다.

낮은 API 버전 (이상적으로는 1.6이지만 2.1에 해당 될 수 있음)을 타겟팅하고 있으며 사운드가 올바르게로드되었는지 (사용자가 선택 했음) 알 필요가 있습니다. 그것을하는 적당한 방법은 무엇인가?

SoundPool에서 MediaPlayer로 사운드를 한 번로드하지 않으시겠습니까?!

+0

좋은 질문, 나는 같은 문제 (http://stackoverflow.com/questions/3253108/how-했다 do-i-know-that-the-soundpool-is-ready-using-dd-target-below-2-2) 실제로 해결책을 찾지 못했습니다. – RoflcoptrException

답변

10

적어도 Android 2.1에서 작동하는 호환 가능한 종류의 OnLoadCompleteListener 클래스를 구현했습니다.

생성자는 SoundPool 개체를 사용하며 SoundPool.load(..)이 호출 된 사운드는 OnLoadCompleteListener.addSound(soundId)으로 등록되어야합니다. 이 후 청취자는 주기적으로 요청 된 사운드를 재생하려고 시도합니다 (0 볼륨에서). 성공적으로 실행되면 Android 2.2 이상 버전과 마찬가지로 onLoadComplete 구현을 호출합니다. 여기

이 사용 예제 :

SoundPool mySoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0); 
    OnLoadCompleteListener completionListener = new OnLoadCompleteListener(mySoundPool) { 
     @Override 
     public void onLoadComplete(SoundPool soundPool, int soundId, int status) { 
      Log.i("OnLoadCompleteListener","Sound "+soundId+" loaded."); 
     } 
    } 
    int soundId=mySoundPool.load(this, R.raw.funnyvoice,1); 
    completionListener.addSound(soundId); // tell the listener to test for this sound. 

그리고 여기 소스입니다 :

abstract class OnLoadCompleteListener {  
    final int testPeriodMs = 100; // period between tests in ms 

    /** 
    * OnLoadCompleteListener fallback implementation for Android versions before 2.2. 
    * After using: int soundId=SoundPool.load(..), call OnLoadCompleteListener.listenFor(soundId) 
    * to periodically test sound load completion. If a sound is playable, onLoadComplete is called. 
    * 
    * @param soundPool The SoundPool in which you loaded the sounds. 
    */ 
    public OnLoadCompleteListener(SoundPool soundPool) { 
     testSoundPool = soundPool; 
    } 

    /** 
    * Method called when determined that a soundpool sound has been loaded. 
    * 
    * @param soundPool The soundpool that was given to the constructor of this OnLoadCompleteListener 
    * @param soundId The soundId of the sound that loaded 
    * @param status  Status value for forward compatibility. Always 0. 
    */ 
    public abstract void onLoadComplete(SoundPool soundPool, int soundId, int status); // implement yourself 

    /** 
    * Method to add sounds for which a test is required. Assumes that SoundPool.load(soundId,...) has been called. 
    * 
    * @param soundPool The SoundPool in which you loaded the sounds. 
    */ 
    public void addSound(int soundId) { 
     boolean isFirstOne; 
     synchronized (this) { 
      mySoundIds.add(soundId); 
      isFirstOne = (mySoundIds.size()==1); 
     } 
     if (isFirstOne) { 
      // first sound, start timer 
      testTimer = new Timer(); 
      TimerTask task = new TimerTask() { // import java.util.TimerTask for this 
       @Override 
       public void run() { 
        testCompletions(); 
       } 
      }; 
      testTimer.scheduleAtFixedRate(task , 0, testPeriodMs); 
     } 
    } 

    private ArrayList<Integer> mySoundIds = new ArrayList<Integer>(); 
    private Timer testTimer; // import java.util.Timer for this 
    private SoundPool testSoundPool; 

    private synchronized void testCompletions() { 
     ArrayList<Integer> completedOnes = new ArrayList<Integer>(); 
     for (Integer soundId: mySoundIds) { 
      int streamId = testSoundPool.play(soundId, 0, 0, 0, 0, 1.0f); 
      if (streamId>0) {     // successful 
       testSoundPool.stop(streamId); 
       onLoadComplete(testSoundPool, soundId, 0); 
       completedOnes.add(soundId); 
      } 
     } 
     mySoundIds.removeAll(completedOnes); 
     if (mySoundIds.size()==0) { 
      testTimer.cancel(); 
      testTimer.purge(); 
     } 
    } 
} 
1

SoundPool은 파일을 비동기 적으로로드합니다. API8 수준 이전에는로드가 완전히 완료되었는지 확인하는 API가 없습니다.

Android API8의 경우 OnLoadCompleteListener를 통해로드가 완료되었는지 확인할 수 있습니다. 여기에 작은 예제가 있습니다 : Android sounds tutorial.

관련 문제