Androidマルチメディア開発音楽再生(進捗バー、時間表示付き)およびSoundPoolによる音響再生


音楽再生
MediaPlayer mediaPlayer = new MediaPlayer();
if(mediaPlayer.isPlaying(){mediaPlayer.reset();//初期状態にリセット}mediaPlayer.setDataSource("/mnt/sdcard/god.mp3"); mediaPlayer.prepare(); mediaPlayer.start();//再生を開始または再開する.pause();//MediaPlayerの再生を一時停止します.start();//再生を再開するstop();//メディアプレーヤーの再生を停止します.release();//リソースを解放するsetOnCompletionListener(new MediaPlayer.OnCompletionListener(){//放送完了イベント@Override public void onCompletion(MediaPlayer arg 0){mediaPlayer.release();        } }); mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener(){//エラー処理イベント@Override public boolean onError(MediaPlayer,int arg 1,int arg 2){mediaPlayer.release();return false;         }
});
音楽再生コードの例:
DemoActivity.java:
package cn.itcast.mp3;

import java.io.File;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.Chronometer.OnChronometerTickListener;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;

public class DemoActivity extends Activity implements OnClickListener,
		OnChronometerTickListener, OnSeekBarChangeListener {
	private EditText et_path;
	private Chronometer et_time;
	private SeekBar sb;
	private Button bt_play, bt_pause, bt_replay, bt_stop;
	private MediaPlayer mediaPlayer;
	private TelephonyManager manager;
	/**
	 * subtime:  “  ”          beginTime:        bash  falgTime:  “  ”   
	 * pauseTime:“  ”   
	 */
	private long subtime = 0, beginTime = 0, falgTime = 0, pauseTime = 0;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		manager = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE);
		manager.listen(new MyListener(), PhoneStateListener.LISTEN_CALL_STATE);
		sb = (SeekBar) this.findViewById(R.id.sb);
		et_path = (EditText) this.findViewById(R.id.et_path);
		et_time = (Chronometer) this.findViewById(R.id.et_time);
		bt_play = (Button) this.findViewById(R.id.play);
		bt_pause = (Button) this.findViewById(R.id.pause);
		bt_replay = (Button) this.findViewById(R.id.replay);
		bt_stop = (Button) this.findViewById(R.id.stop);
		sb.setEnabled(false);
		sb.setOnSeekBarChangeListener(this);
		bt_play.setOnClickListener(this);
		bt_pause.setOnClickListener(this);
		bt_replay.setOnClickListener(this);
		bt_stop.setOnClickListener(this);
		et_time.setOnChronometerTickListener(this);

	}

	Handler handler = new Handler();
	Runnable updateThread = new Runnable() {
		public void run() {
			//                      
			if (mediaPlayer != null) {
				sb.setProgress(mediaPlayer.getCurrentPosition());
				//     100       
				handler.postDelayed(updateThread, 100);
			}
		}
	};

	public void onClick(View v) {
		String path;
		try {
			switch (v.getId()) {
			case R.id.play:
				falgTime = SystemClock.elapsedRealtime();
				path = et_path.getText().toString().trim();
				play(path);
				pauseTime = 0;
				et_time.setBase(falgTime);
				et_time.start();
				break;
			case R.id.pause:
				pause();
				break;
			case R.id.replay:
				if (mediaPlayer != null && mediaPlayer.isPlaying()) {
					mediaPlayer.seekTo(0);
					et_time.setBase(SystemClock.elapsedRealtime());
					et_time.start();
				} else {
					path = et_path.getText().toString().trim();
					play(path);
					et_time.setBase(SystemClock.elapsedRealtime());
					et_time.start();

				}
				if ("  ".equals(bt_pause.getText().toString().trim())) {
					bt_pause.setText("  ");

				}
				falgTime = SystemClock.elapsedRealtime();
				subtime = 0;
				break;
			case R.id.stop:
				if (mediaPlayer != null && mediaPlayer.isPlaying()) {
					mediaPlayer.stop();
					mediaPlayer = null;
					et_time.setBase(SystemClock.elapsedRealtime());
					et_time.start();
					et_time.stop();
					bt_play.setEnabled(true);
					bt_play.setClickable(true);
					sb.setProgress(0);
					sb.setEnabled(false);
					falgTime = 0;
					subtime = 0;
				}
				break;

			}
		} catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(getApplicationContext(), "        ", 0).show();
		}

	}

	private void pause() {
		//          
		if (mediaPlayer != null && mediaPlayer.isPlaying()) {
			//        
			mediaPlayer.pause();
			bt_pause.setText("  ");
			sb.setEnabled(false);
			et_time.stop();

			pauseTime = SystemClock.elapsedRealtime();
			// System.out.println("1 pauseTime" + pauseTime);
		} else if (mediaPlayer != null
				&& "  ".equals(bt_pause.getText().toString())) {
			subtime += SystemClock.elapsedRealtime() - pauseTime;
			// System.out.println("2 subtime:" + subtime);
			mediaPlayer.start();
			bt_pause.setText("  ");
			sb.setEnabled(true);
			beginTime = falgTime + subtime;
			// System.out.println("3 beginTime" + beginTime);
			et_time.setBase(beginTime);
			et_time.start();
		}
	}

	/**
	 *             .mp3 .wav .amr
	 * 
	 * @param path
	 */
	private void play(String path) throws Exception {
		if ("".equals(path)) {
			Toast.makeText(getApplicationContext(), "      ", 0).show();
			return;
		}
		File file = new File(path);
		if (file.exists()) {

			mediaPlayer = new MediaPlayer();
			mediaPlayer.setDataSource(path);
			// mediaPlayer.prepare(); // c/c++          
			//     
			//        
			mediaPlayer.prepareAsync();
			//       
			mediaPlayer.setOnPreparedListener(new OnPreparedListener() {

				public void onPrepared(MediaPlayer mp) {
					// TODO Auto-generated method stub
					mediaPlayer.start();
					bt_play.setEnabled(false);
					bt_play.setClickable(false);
					sb.setMax(mediaPlayer.getDuration());
					handler.post(updateThread);
					sb.setEnabled(true);
				}
			});

			//             
			mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

				public void onCompletion(MediaPlayer mp) {
					mediaPlayer.release();
					mediaPlayer = null;
					bt_play.setEnabled(true);
					bt_play.setClickable(true);
					et_time.setBase(SystemClock.elapsedRealtime());
					et_time.start();
					et_time.stop();
					sb.setProgress(0);
					sb.setEnabled(false);
				}
			});

		} else {
			Toast.makeText(getApplicationContext(), "     ", 0).show();
			return;
		}

	}

	private class MyListener extends PhoneStateListener {

		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			super.onCallStateChanged(state, incomingNumber);
			switch (state) {
			case TelephonyManager.CALL_STATE_RINGING:
				//        
				pause();
				break;
			case TelephonyManager.CALL_STATE_IDLE:
				//       
				pause();
				break;
			}
		}
	}

	public void onChronometerTick(Chronometer chronometer) {

	}

	public void onProgressChanged(SeekBar seekBar, int progress,
			boolean fromUser) {
		// TODO          
		if (fromUser == true && mediaPlayer != null) {
			mediaPlayer.seekTo(progress);
			falgTime = SystemClock.elapsedRealtime() - sb.getProgress();
			et_time.setBase(falgTime);
			subtime = 0;
			et_time.start();
		}
	}

	public void onStartTrackingTouch(SeekBar seekBar) {

	}

	public void onStopTrackingTouch(SeekBar seekBar) {
		// TODO          
	}
}

main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="        " />

    <Chronometer
        android:id="@+id/et_time"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/et_path"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="/sdcard/e.mp3" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="  " />

        <Button
            android:id="@+id/pause"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="  " />

        <Button
            android:id="@+id/replay"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="  " />

        <Button
            android:id="@+id/stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="  " />
    </LinearLayout>

</LinearLayout>

SoundPoolを使用してサウンドを再生するには、次の手順に従います.
Android開発ではMediaPlayerを使用してオーディオファイルを再生することが多いが、MediaPlayerにはリソースの使用量が高く、遅延時間が長く、複数のオーディオの同時再生がサポートされていないなどの不足がある.これらの欠点は、MediaPlayerの場合の使用状況が望ましくないことを決定し、例えば、時間精度に対する要求が比較的高いゲーム開発において.ゲーム開発では、短時間で密集し、遅延が少ないという共通の特徴を持つゲームの音響効果(例えば、弾丸爆発、物体衝突など)を再生する必要があります.このようなシーンでは、MediaPlayerの代わりにSoundPoolを使用してこれらの音響効果を再生することができます.SoundPool(android.media.SoundPool)は、その名の通り、音声プールという意味で、主に短い音声クリップを再生するために用いられ、プログラムのリソースやファイルシステムからのロードをサポートする.SoundPoolの利点は、MediaPlayerに比べてCPUリソースの使用量が低く、反応の遅延が小さいことである.また、SoundPoolは、音声の品質、音量、再生比率などのパラメータを自分で設定することをサポートし、複数のオーディオストリームをIDで管理する.現在知られている資料では、SoundPoolにはいくつかの設計上のBUGがあり、ファームウェアバージョン1.0からまだ修復されていないものもありますが、使用中は注意してください.将来Googleがこれらの問題を修復すると信じていますが、私たちはやはり列挙したほうがいいです.SoundPoolは最大1 Mのメモリスペースしか申請できません.これは、曲を再生したり、ゲームのバックミュージックをしたりするのではなく、短い音声クリップしか使用できないことを意味します.  2. SoundPoolはpauseとstopの方法を提供していますが、これらの方法は簡単に使用しないことをお勧めします.プログラムがわけのわからない終了になる可能性があるからです.この2つの方法を使用する場合は、できるだけ多くのテスト作業を行うことをお勧めします.また、すぐに音声の再生を中止するのではなく、バッファ内のデータを再生してから停止することをお勧めします.1秒以上再生するかもしれません.  3. SoundPoolの効率の問題.実はSoundPoolの効率はこれらの再生クラスの中では良いのですが、G 1で100 ms程度の遅延があるとテストしている友人もいて、ユーザー体験に影響を与える可能性があります.SoundPool自体には関係ないかもしれませんが、性能の良いDroidではこの遅延が受け入れられるからです.現段階ではSoundPoolにはこれらの欠陥がありますが、代替できない利点もあります.これらに基づいて、SoundPoolを多く使用することをお勧めします.
      1.アプリケーションでの音響効果(キープロンプト音、メッセージなど)2.ゲーム中の密集した短い音(複数の宇宙船が同時に爆発するなど)
開発手順:
1>プロジェクトのres/rawディレクトリにサウンドファイルを入れます.
2>SoundPoolオブジェクトを新規作成し、SoundPoolを呼び出します.load()サウンドをロードし、SoundPoolを呼び出します.Play()メソッド指定したサウンドファイルを再生します.
public class AudioActivity extends Activity {
private SoundPool pool;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//指定音プールの最大オーディオストリーム数は10、音品質は5
pool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
final int sourceid = pool.load(this, R.raw.pj, 0);//オーディオストリームをロードし、プール内のidを返します.
Button button = (Button)this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//オーディオを再生し、2番目のパラメータは左チャンネルの音量です.3番目のパラメータは右チャネルボリュームです.4番目のパラメータは優先度です.5番目のパラメータはサイクル回数であり、0はサイクルではなく、-1はサイクルである.6番目のパラメータは速度で、速度は最低0.5で最高2で、1は正常な速度を表します.
pool.play(sourceid, 1, 1, 0, -1, 1);
}
});
}
}
SoundPoolを使用してサウンドコードの例を再生します.
DemoActivity.java:
package cn.itcast.soundpool;

import android.app.Activity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.View;

public class DemoActivity extends Activity {
	int soundid;
	SoundPool pool;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		pool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
		//               
		soundid = pool.load(this, R.raw.ring, 1); //          
	}

	public void shoot(View view) {
		//                         
		pool.play(soundid, 1.0f, 1.0f, 0, 0, 1.0f);
		// taking tom
	}
}