Зная, была ли загрузка звука с SoundPool была успешной на Android 1.6 / 2.0 / 2.1 - PullRequest
5 голосов
/ 14 января 2011

В Android 2.2+ есть нечто, называемое SoundPool.OnLoadCompleteListener , позволяющее узнать, успешно ли был загружен звук.

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

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

Ответы [ 2 ]

10 голосов
/ 15 августа 2011

Я реализовал своего рода совместимый класс 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 голос
/ 16 июня 2011

SoundPool загружает файл асинхронно.До уровня API8, к сожалению, нет API для проверки того, была ли загрузка полностью завершена.

Как вы сказали, начиная с Android API8, можно проверить, завершена ли загрузка через OnLoadCompleteListener.Вот небольшой пример для этого: Учебник по звукам Android .

...