2011-01-14 16 views
5

W systemie Android 2.2+ jest coś, co nazywa się SoundPool.OnLoadCompleteListener, co pozwala sprawdzić, czy dźwięk został załadowany poprawnie.Wiedząc, czy ładowanie dźwięku za pomocą SoundPool odniosło sukces w systemie Android 1.6/2.0/2.1

Mam na myśli niższą wersję interfejsu API (najlepiej 1.6, ale może przejść do wersji 2.1) i muszę wiedzieć, czy dźwięk został załadowany poprawnie (jak jest wybrany przez użytkownika). Jaki jest właściwy sposób na zrobienie tego?

Mam nadzieję, że nie załaduję dźwięku raz z MediaPlayer i czy jest to prawidłowe z SoundPool ?!

+0

Dobre pytanie, miałem ten sam problem (http://stackoverflow.com/questions/3253108/how- do-i-know-that-the-soundpool-is-ready-using-sdk-target-below-below-2-2) i tak naprawdę nie znalazł rozwiązania. – RoflcoptrException

Odpowiedz

10

Zaimplementowałem rodzaj zgodny z klasą OnLoadCompleteListener, która działa przynajmniej na Androida 2.1.

Konstruktor pobiera obiekt SoundPool, a dźwięki, dla których wywołano SoundPool.load(..), muszą być zarejestrowane pod numerem OnLoadCompleteListener.addSound(soundId). Następnie słuchacz okresowo próbuje odtworzyć żądane dźwięki (przy zerowej głośności). Jeśli się powiedzie, wywoła twoją implementację onLoadComplete, tak jak w wersji Androida 2.2+.

Oto przykład użycia:

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. 

A oto źródło:

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 wczytuje plik asynchronicznie. Przed poziomem API8 niestety nie ma interfejsu API do sprawdzenia, czy ładowanie zostało całkowicie zakończone.

Jak już powiedziałeś na Androidzie API8, można sprawdzić, czy ładowanie zostało zakończone za pośrednictwem OnLoadCompleteListener. Oto mały przykład: Android sounds tutorial.

Powiązane problemy