2011年8月23日火曜日

非同期でMediaPlayerを使う

非同期で(asynchronously)MediaPlayerを使う

Mediaに書かれているとおりに書いたつもりのsourceを掲載しておきます。
音楽ファイルは次のサイトのを使いました。
MP3ダウンロード(童謡 唱歌 世界の民謡)

動作内容:SDカードにある、複数の音楽ファイル(mp3)を連続再生する。実験・学習目的なので、簡単にするため、serviceを使っていません。

留意点:指定された音楽ファイルが存在しない場合、setDataSourceメソッドでエラーを補足するのでは無く、prepare系でエラーを補足する、というのがMediaPlayerの仕様です。
では、setDataSourceメソッドのIOExceptionは何のために存在するのでしょうか。そんなことまでは、私は興味はありません。


public class SoundWAVActivity extends Activity
    implements
    MediaPlayer.OnCompletionListener,
    MediaPlayer.OnPreparedListener,
    MediaPlayer.OnErrorListener
    {
    
    MediaPlayer mp = null;;
    int iFileNumber = 1647;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        StartMusic();
    }
    
    //演奏が終了した場合、呼ばれる。
    @Override
    public void onCompletion(MediaPlayer arg0) {
        if(mp==arg0) StartMusic();
    }


    //演奏の準備が完了したら呼ばれる。
    @Override//Running asynchronously
    public void onPrepared(MediaPlayer ThisMP) {
        if(mp==ThisMP) mp.start();
    }


    //演奏の準備の段階でエラーが発生した時に呼ばれる。
    @Override//Handling asynchronous errors
    public boolean onError(MediaPlayer ThisMP, int what, int extra) {
        if(mp==ThisMP){
            if(what==MediaPlayer.MEDIA_ERROR_SERVER_DIED)
                Log.e("SoundWAV", "onError:MEDIA_ERROR_SERVER_DIED");
            else//ファイルが存在しない場合、ここに来る。
                Log.e("SoundWAV", "onError:MEDIA_ERROR_UNKNOWN");
            //エラーになっても何もしなければ、onCompletionメソッドが呼ばれる。
            finish();
            return true;//次のonCompletion()が呼ばれないようにする。
        }
        return false;
    }


    @Override
    protected void onDestroy() {
        if(mp!=null) mp.release();//Performing cleanup
        super.onDestroy();
    }
    
    private void StartMusic(){
        File f, fSD;
        String sFile;
        
        fSD = Environment.getExternalStorageDirectory();
        fSD = new File(fSD, "music");
        sFile = "m" + String.valueOf(iFileNumber) + ".mp3";
        f = new File(fSD, sFile);
        sFile = f.getPath();//ファイルの存在確認はMediaPlayerで行う。
        iFileNumber++;
        
        if(mp!=null) mp.release();
        mp = new MediaPlayer();
        if(mp==null){
            Log.e("SoundWAV", "mp == null");
            finish();
            return;
        }
        try{
            mp.setDataSource(sFile);
        }
        catch (IOException e) {//ファイルが存在しなくても。ここには来ない。
            Log.e("SoundWAV", "IOException");
            finish();
            return;
        }
        catch (IllegalStateException e) {
            //release()&Newを実行しない場合、ここに来る。
            Log.e("SoundWAV", "IllegalStateException");
            finish();
            return;
        }
        catch (IllegalArgumentException e) {
            Log.e("SoundWAV", "IllegalArgumentException");
            finish();
            return;
        }
        
        mp.setOnCompletionListener(this);
        mp.setOnPreparedListener(this);
        mp.setOnErrorListener(this);
        mp.prepareAsync ();
        Toast.makeText(this, "Start", Toast.LENGTH_SHORT).show();
    }
}

0 件のコメント:

コメントを投稿