5

Android 2.2+ では、 SoundPool.OnLoadCompleteListenerと呼ばれるものがあり、サウンドが正常にロードされたかどうかを知ることができます。

下位の API バージョン (理想的には 1.6 ですが、2.1 を使用することもできます) をターゲットにしており、サウンドが (ユーザーによって選択されているため) 正しくロードされているかどうかを知る必要があります。それを行う適切な方法は何ですか?

MediaPlayer でサウンドを一度ロードしないことを望みます。SoundPool で正しければ?!

4

2 に答える 2

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();
        }
    }
}
于 2011-08-14T22:43:19.680 に答える
1

SoundPool はファイルを非同期的にロードします。残念ながら、API8 レベルより前では、ロードが完全に行われたかどうかを確認する API はありません。

あなたが言ったように、Android API8の時点で、OnLoadCompleteListenerを介してロードが完了したかどうかを確認できます。これに関する小さな例を次に示します: Android サウンド チュートリアル

于 2011-06-16T07:58:47.510 に答える