2011-01-14 2 views
5

На Android 2.2+ есть что-то под названием SoundPool.OnLoadCompleteListener, позволяющее узнать, был ли звук загружен успешно или нет.Знание того, что загрузка звука с помощью SoundPool прошла успешно на Android 1.6/2.0/2.1

Я ориентируюсь на более низкую версию API (в идеале 1,6, но может пойти на 2,1), и мне нужно знать, правильно ли загружен звук (поскольку он выбран пользователем). Каков правильный способ сделать это?

Надеюсь, что один раз не загрузите звук с помощью MediaPlayer, и если это будет правильно с SoundPool ?!

+0

Хороший вопрос, я была такая же проблема (http://stackoverflow.com/questions/3253108/how- do-i-know-that-the-soundpool-is-ready-using-sdk-target-below-2-2) и на самом деле не нашел решения. – RoflcoptrException

ответ

10

Я реализовал класс совместимого класса OnLoadCompleteListener, который работает хотя бы для Android 2.1.

Конструктор принимает объект SoundPool, и звуки, для которых был вызван SoundPool.load(..), должны быть зарегистрированы с OnLoadCompleteListener.addSound(soundId). После этого слушатель периодически пытается воспроизвести запрошенные звуки (при нулевой громкости). В случае успеха он вызывает вашу реализацию onLoadComplete, как в Android 2.2+.

Вот пример использования:

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.