2011-01-14 16 views
5

En Android 2.2+ hay algo llamado SoundPool.OnLoadCompleteListener que permite saber si un sonido se ha cargado correctamente o no.Saber si la carga de un sonido con SoundPool ha tenido éxito en Android 1.6/2.0/2.1

Estoy apuntando a una versión de API inferior (idealmente 1.6, pero podría ir para 2.1) y necesito saber si un sonido se ha cargado correctamente (como lo ha seleccionado el usuario). ¿Cuál es la forma correcta de hacerlo?

Espero no cargar el sonido una vez con MediaPlayer y si es correcto con SoundPool ?!

+0

Buena pregunta, que tenía el mismo problema (http://stackoverflow.com/questions/3253108/how- do-i-know-that-the-soundpool-is-ready-using-sdk-target-below-2-2) y realmente no encontró una solución. – RoflcoptrException

Respuesta

10

Implementé una clase compatible con OnLoadCompleteListener que funciona al menos para Android 2.1.

El constructor toma un objeto SoundPool, y los sonidos para los que se ha llamado al SoundPool.load(..) deben registrarse con OnLoadCompleteListener.addSound(soundId). Después de esto, el oyente periódicamente intenta reproducir los sonidos solicitados (a volumen cero). Si tiene éxito, llama a su implementación de onLoadComplete, como en la versión de Android 2.2+.

Aquí está un ejemplo de uso:

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. 

y aquí está la fuente:

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 carga el archivo de forma asincrónica. Antes del nivel API8 desafortunadamente no hay API para verificar si la carga ha sido completa.

Como dijiste en Android API8, es posible verificar si la carga se completa a través de OnLoadCompleteListener. Aquí hay un pequeño ejemplo para esto: Android sounds tutorial.

Cuestiones relacionadas