MediaPlayerを使ってみる
Android端末で音を鳴らす方法はいくつかありますが、今回はMediaPlayerクラスを使用して
音を鳴らす方法を勉強していきます。
MediaPlayerの特徴として
再生時間が長い音(BGMなど)にはMediaPlayerを使うのがいい
連打して音を鳴らすのが苦手
呼び出しから再生までの時間がSoundPoolに比べて遅いなどがあります。
用は、バックミュージックで流すことは得意だよ!でも画面タッチした際などに音を鳴らすのは苦手だよ!って感じです。
勉強ソフトとして、再生状況の表示
再生ボタン、一時停止ボタン、繰り返しボタン、停止ボタンが画面に並んでいる単純なソフトを作成していきます。
bgmで使用するサウンドファイルですが、oggやmp3などが使えます。もちろん自作で作成したものを使っても構いませんが、ネット上には、すばらしいフリー素材サイトがたくさんあります。今回は、「ユウラボ8bitサウンド工房」様からいただきました。
プロジェクトの作成
プロジェクト名:MediaPlayerTest、アクテビティ名:MainActivity、レイアウト名:main、でプロジェクトを作成します。文字列定義
アプリで使用する文字列を定義します。(定義方法はStrings.xmlについての勉強を参照)
++strings.xml++
<resources>
<string name="app_name">MediaPlayerTest</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="text_bgm_title">タイトル</string>
<string name="button_play">再生</string>
<string name="button_pause">一時停止</string>
<string name="button_loop">繰り返し</string>
<string name="button_stop">停止</string>
<string name="button_project_end">終了</string>
</resources>
メニュー画面レイアウト作成
次にメニュー画面(main.xml)のレイアウトを作成します。main.xmlソース
++main.xml++
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<TextView
android:id="@+id/bgm_title_text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textSize="30sp"
android:text="@string/text_bgm_title"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<Button
android:id="@+id/play_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_play"
/>
<Button
android:id="@+id/pause_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_pause"
/>
<Button
android:id="@+id/stop_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_stop"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical" >
<Button
android:id="@+id/loop_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_loop"
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="bottom"
android:orientation="vertical" >
<Button
android:id="@+id/projec_end_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/button_project_end"
/>
</LinearLayout>
</LinearLayout>
サウンドファイルの配置
今回は、サウンドファイルをリソースファイルから読み込んで再生するためプロジェクトフォルダ内の『res』内に『raw』フォルダを作成します。
rawフォルダ内にサウンドファイルを格納します。
これにより、下記のようにサウンドファイルにアクセスできるようになります。
R.raw.sht_a01
なぜrawフォルダ内に入れるかは、公式でここに配置するのが妥当となっているようです。
各コントロール操作準備(MainActivity.java)
各ボタンを操作するための準備をします。
public class MainActivity extends Activity implements OnClickListener {
private Button playButton = null;
private Button pauseButton = null;
private Button stopButton = null;
private Button loopButton = null;
private Button projectEndButton = null;
private TextView bgmTitleText = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
playButton = (Button)findViewById(R.id.play_button);
pauseButton = (Button)findViewById(R.id.pause_button);
stopButton = (Button)findViewById(R.id.stop_button);
loopButton = (Button)findViewById(R.id.loop_button);
projectEndButton = (Button)findViewById(R.id.projec_end_button);
bgmTitleText = (TextView)findViewById(R.id.bgm_title_text);
playButton.setOnClickListener(this);
pauseButton.setOnClickListener(this);
stopButton.setOnClickListener(this);
loopButton.setOnClickListener(this);
projectEndButton.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View v) {
// TODO 自動生成されたメソッド・スタブ
switch(v.getId()) {
case R.id.play_button :
break;
case R.id.pause_button :
break;
case R.id.stop_button :
break;
case R.id.loop_button :
break;
case R.id.projec_end_button :
break;
default:
}
}
/*
* タイトルセット
*/
private void setBGMTitle(String title){
this.bgmTitleText.setText(title);
}
}
MediaPlayerクラスについて
では、本題のMediaPlayerクラスの使用方法を見ていきます。●インスタンスの生成
MediaPlayer mp;
mp = MediaPlayer.create(context,R.raw.sht_a01);
createメソッドの第一引数に Context クラス、第二引数にリソースを指定します。
●再生方法
mp.start();
再生は start メソッドを使用します。引数は有りません。
●停止方法
mp.stop();
try {
mp.prepare();
} catch (IOException e){}
停止は stop メソッドを使用します。引数は有りません。
prepare()はおまじないみたいです、trychachで必ずかこってください。
●一時停止方法
mp.pause();
一時停止は pause メソッドを使用します。引数は有りません。
●現在再生中かの確認
mp.isPlaying();
再生中かどうかをboolean型で返します。
●リソースの解放
mp.release();
アプリの停止するタイミングでreleaseメソッドを使わないとメモリに残り続けてしまうので注意です。
●シーク完了(指定の位置に再生ポイントを移動すること)
mp.setOnSeekCompleteListener(new OnSeekCompleteListener(){
public void onSeekComplete(MediaPlayer mp){
}
});
シークが完了した場合にコールされるコールバックメソッド
●再生が完了
mp.setOnCompletionListener(new OnCompletionListener(){
public void onCompletion(MediaPlayer mp){
}
});
再生が終了した場合にコールされるコールバックメソッド。Stop()を実行時に呼ばれる
MediaPlayer実装
上記の内容をふまえてMainActivity.javaを修正
+++MainActivity.java+++
public class MainActivity extends Activity implements OnClickListener {
private Button playButton = null;
private Button pauseButton = null;
private Button stopButton = null;
private Button loopButton = null;
private Button projectEndButton = null;
private TextView bgmTitleText = null;
private MediaPlayer mediaPlayer = null;
private Handler guiControlHandler = null;
private int count = 0;
private boolean isLoop = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
playButton = (Button)findViewById(R.id.play_button);
pauseButton = (Button)findViewById(R.id.pause_button);
stopButton = (Button)findViewById(R.id.stop_button);
loopButton = (Button)findViewById(R.id.loop_button);
projectEndButton = (Button)findViewById(R.id.projec_end_button);
bgmTitleText = (TextView)findViewById(R.id.bgm_title_text);
playButton.setOnClickListener(this);
pauseButton.setOnClickListener(this);
stopButton.setOnClickListener(this);
loopButton.setOnClickListener(this);
projectEndButton.setOnClickListener(this);
mediaPlayer = MediaPlayer.create(this,R.raw.sht_a01);
guiControlHandler = new Handler();
// シーク完了イベント
mediaPlayer.setOnSeekCompleteListener(new OnSeekCompleteListener(){
public void onSeekComplete(MediaPlayer mp){
count += 1;
setBGMTitle(String.valueOf(count));
}
});
// 再生終了イベント
mediaPlayer.setOnCompletionListener(new OnCompletionListener(){
public void onCompletion(MediaPlayer mp)
{
setBGMTitle("再生終了");
count = 0;
}
});
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onRestart() {
super.onRestart();
}
@Override
protected void onPause() {
super.onPause();
mediaPlayer.pause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View v) {
// TODO 自動生成されたメソッド・スタブ
switch(v.getId()) {
case R.id.play_button :
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
setBGMTitle("再生中");
}
break;
case R.id.pause_button :
if(mediaPlayer.isPlaying()){
mediaPlayer.pause();
setBGMTitle("一時停止中");
}
break;
case R.id.stop_button :
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
} catch (IOException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
setBGMTitle("停止中");
}
break;
case R.id.loop_button :
if(isLoop){
;isLoop = false;
mediaPlayer.setLooping(isLoop);
this.loopButton.setText("繰り返しOFF");
}
else {
;isLoop = true;
mediaPlayer.setLooping(isLoop);
this.loopButton.setText("繰り返しON");
}
break;
case R.id.projec_end_button :
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
} catch (IOException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
setBGMTitle("停止中");
}
this.finish();
break;
default:
}
}
/*
* タイトルセット
*/
public void setBGMTitle(final String text){
guiControlHandler.post(new Runnable(){
@Override
public void run() {
bgmTitleText.setText(text);
}
});
}
}
カテゴリーへ
SoundPoolを使ってみる
今回はSoundPoolクラスを使って音を鳴らす方法を勉強していきます。
SoundPoolの特徴として
1つのインスタンスで複数の音声を再生するのが得意。
ファイルをロード時にデコードしておくので、遅延が少ない。
再生時間が短い効果音などが得意、逆に再生時間が長い音は途中で切れる可能性がある。
ファイルフォーマットmp3は不安定、oggが無難。
再生時間10秒までっぽい。
用は、バックミュージックで流す長い音楽は無理だよ!
でも画面タッチした際などに短い音を鳴らすのは得意だよ!って感じです。
勉強ソフトとして、MediaPlayerクラスについてで作成したプロジェクトを使用します。
MediaPlayer操作コントロールの下に、
再生状況の表示、再生ボタン、一時停止ボタン、繰り返しボタン、停止ボタンが画面に並んでいる単純なソフトを作成していきます。
使用するサウンドファイルですが、oggを使用します。もちろん自作で作成したものを使っても構いませんが、ネット上には、すばらしいフリー素材サイトがたくさんあります。今回は、「魔王魂」様からいただきました。
メニュー画面レイアウト作成
まずは、メニュー画面(main.xml)のレイアウトを編集します。main.xmlソースは省略します。
サウンドファイルの配置
MediaPlayerを使ってみるで説明した通り、rawフォルダ内にサウンドファイルを格納します。これにより、下記のようにサウンドファイルにアクセスできるようになります。
R.raw.se_maoudamashii_onepoint33
各コントロール操作準備(MainActivity.java)
各ボタンを操作するための準備をします。 ここも、MediaPlayerをつかってみるで説明した内容とほぼ同じなので省略します。SoundPoolクラスについて
では、本題のSoundPoolクラスの使用方法を見ていきます。●インスタンスの生成
SoundPool sp;
sp = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
第一引数:ロードするファイルの数
第二引数:ストリームのタイプ
ストリームタイプ一覧
AudioManager.STREAM_ALARM アラーム音
AudioManager.STREAM_MUSIC 音楽音
AudioManager.STREAM_NOTIFICATION 通知音
AudioManager.STREAM_RING 着信音
AudioManager.STREAM_SYSTEM システム音
AudioManager.STREAM_VOICE_CALL 通話音
第三引数:サンプリングレートのクオリティを指定します。(デフォルトは0)
●ファイルロード方法
int soundId01 = sp.load(context,R.raw.se_maoudamashii_onepoint33,1);
第一引数:コンテキスト
第二引数にリソースID
第三引数は公式でデフォルト1を指定するように記述されています。
戻り値intは再生時に必要になるため保持しておくこと。
ファイルロードは少し時間がかかるため、非同期で動作します。
ロードが終わったかどうか分からないのですぐload()直後にplay()(再生)を呼ぶと、再生されない時があります。
OnLoadCompleteListenerでリスナー登録することによりload()が終了したイベントを受け取ることができます
●再生方法
soundId01 = sp.play(soundID,leftVolume,rightVolume,priority,loop,rate); 第一引数:ロードしたときのID
第二引数:左側音量
第三引数:右側音量
第四引数:プライオリティ(デフォルト0)
第五引数:ループ設定(-1で無限ループ,0で1回再生)
第六引数:再生速度(1.0で普通)
●停止方法
sp.stop(soundId01);
第一引数:ロードしたときのID
停止は stop メソッドを使用します。
●一時停止方法
sp.pause(soundId01);
第一引数:ロードしたときのID
一時停止は pause メソッドを使用します。
●リソースの解放
sp.release();
アプリの停止するタイミングでreleaseメソッドを使わないとメモリに残り続けてしまうので注意です。
onResumeでインスタンスの生成&loadして、onPauseでreleaseするといいようです。
上記の内容をふまえてMainActivity.javaを修正(soundPoolクラスに関係している場所だけを抜粋してます)
+++MainActivity.java+++
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
oggPlayButton = (Button)findViewById(R.id.ogg_play_button);
oggPlayButton.setEnabled(false);
oggPauseButton = (Button)findViewById(R.id.ogg_pause_button);
oggPauseButton.setEnabled(false);
oggStopButton = (Button)findViewById(R.id.ogg_stop_button);
oggStopButton.setEnabled(false);
oggLoopButton = (Button)findViewById(R.id.ogg_loop_button);
oggLoopButton.setEnabled(false);
oggTitleText = (TextView)findViewById(R.id.ogg_title_text);
oggPlayButton.setOnClickListener(this);
oggPauseButton.setOnClickListener(this);
oggStopButton.setOnClickListener(this);
oggLoopButton.setOnClickListener(this);
}
@Override
protected void onResume() {
super.onResume();
//インスタンス生成
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
//ファイルロード
soundID01 = soundPool.load(this,R.raw.se_maoudamashii_onepoint33,1);
//ロード終了イベント登録
soundPool.setOnLoadCompleteListener(this);
}
@Override
protected void onPause() {
super.onPause();
//インスタンス解放
soundPool.unload(soundID01);
soundPool.release();
}
@Override
public void onClick(View v) {
case R.id.ogg_play_button :
//再生
soundPool.play(soundID01,1,1,0,soundLoopFlg,0);
oggTitleText.setText("再生中");
break;
case R.id.ogg_pause_button :
//一時停止
soundPool.pause(soundID01);
oggTitleText.setText("一時停止");
break;
case R.id.ogg_stop_button:
//停止
soundPool.stop(soundID01);
oggTitleText.setText("停止");
break;
case R.id.ogg_loop_button:
//停止
if(soundLoopFlg == 0){
oggLoopButton.setText("繰り返し ON");
soundLoopFlg = -1;
}
else{
oggLoopButton.setText("繰り返し OFF");
soundLoopFlg = 0;
}
break;
}
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
// TODO 自動生成されたメソッド・スタブ
oggPlayButton.setEnabled(true);
oggPauseButton.setEnabled(true);
oggStopButton.setEnabled(true);
oggLoopButton.setEnabled(true);
}
カテゴリーへ
SoundPoolで複数音を鳴らしてみる
今回はSoundPoolに複数の音をLoadさせて、音を鳴らした時の動作を確認していきます。
使用するサウンドファイルですが、oggを使用します。
もちろん自作で作成したものを使っても構いませんが
ネット上には、すばらしいフリー素材サイトがたくさんあります。
今回も、「魔王魂」様
からいただきました。
ダウンロードした音楽ファイルはプロジェクトフォルダ内の『res』内に『raw』フォルダを作成して
rawフォルダ内にサウンドファイルを格納します。
ざっくりした仕様は
○10~20個ほどサウンドファイルをリソースファイルから読み込んで
それぞれのサウンドごとにボタンを設けてボタン押下で音が鳴るようにする。
○連続で音を鳴らすようにループ回数も設定できるようにする。
○途中で止めるために停止ボタンをもうける。
○現状のメモリ使用量などがわかるように画面に表示する。
画面はこんな感じ(画像は下のボタンが切れてますが、実機で実行すると自動調整してくれます)
全体のソース
package com.example.soundepooltest;
import java.util.ArrayList;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener,OnLoadCompleteListener{
private SoundPool soundPool;
private int[] soundIDList = new int[20];
private int currentSoundID = 0;
private int loopCount = 0;
private Button soundButton01 = null;
private Button soundButton02 = null;
private Button soundButton03 = null;
private Button soundButton04 = null;
private Button soundButton05 = null;
private Button soundButton06 = null;
private Button soundButton07 = null;
private Button soundButton08 = null;
private Button soundButton09 = null;
private Button soundButton10 = null;
private Button soundButton11 = null;
private Button soundButton12 = null;
private Button soundButton13 = null;
private Button soundButton14 = null;
private Button soundButton15 = null;
private Button soundButton16 = null;
private TextView totalMemoryText = null;
private TextView freeMemoryText = null;
private TextView useMemoryText = null;
private TextView dalvikMemoryText = null;
private EditText loopCountEdit = null;
private Button loopCountButton = null;
private Button soundStopButton = null;
private ArrayList<Button> soundButtonList = null;
private boolean isSoundLoadEnd = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.soundButtonList = new ArrayList<Button>();
//各ボタン設定
this.initButtonView(this.soundButton01, R.id.sound01_button);
this.initButtonView(this.soundButton02, R.id.sound02_button);
this.initButtonView(this.soundButton03, R.id.sound03_button);
this.initButtonView(this.soundButton04, R.id.sound04_button);
this.initButtonView(this.soundButton05, R.id.sound05_button);
this.initButtonView(this.soundButton06, R.id.sound06_button);
this.initButtonView(this.soundButton07, R.id.sound07_button);
this.initButtonView(this.soundButton08, R.id.sound08_button);
this.initButtonView(this.soundButton09, R.id.sound09_button);
this.initButtonView(this.soundButton10, R.id.sound10_button);
this.initButtonView(this.soundButton11, R.id.sound11_button);
this.initButtonView(this.soundButton12, R.id.sound12_button);
this.initButtonView(this.soundButton13, R.id.sound13_button);
this.initButtonView(this.soundButton14, R.id.sound14_button);
this.initButtonView(this.soundButton15, R.id.sound15_button);
this.initButtonView(this.soundButton16, R.id.sound16_button);
this.totalMemoryText = (TextView)findViewById(R.id.total_memory_text);
this.freeMemoryText = (TextView)findViewById(R.id.free_memory_text);
this.useMemoryText = (TextView)findViewById(R.id.use_memory_text);
this.dalvikMemoryText = (TextView)findViewById(R.id.dalvik_memory_text);
this.loopCountEdit = (EditText)findViewById(R.id.loopCount_Edit);
this.loopCountButton = (Button)findViewById(R.id.loopCount_button);
this.loopCountButton.setOnClickListener(this);
this.soundStopButton = (Button)findViewById(R.id.sound_stop_button);
this.soundStopButton.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
protected void onResume() {
super.onResume();
//インスタンス生成
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
//ファイルロード
//ボタンのタグに読込んだIDを設定する。
this.soundButtonList.get(0).setTag(soundPool.load(this,R.raw.battle01,1));
this.soundButtonList.get(1).setTag(soundPool.load(this,R.raw.battle02,1));
this.soundButtonList.get(2).setTag(soundPool.load(this,R.raw.battle03,1));
this.soundButtonList.get(3).setTag(soundPool.load(this,R.raw.battle04,1));
this.soundButtonList.get(4).setTag(soundPool.load(this,R.raw.battle05,1));
this.soundButtonList.get(5).setTag(soundPool.load(this,R.raw.battle06,1));
this.soundButtonList.get(6).setTag(soundPool.load(this,R.raw.battle07,1));
this.soundButtonList.get(7).setTag(soundPool.load(this,R.raw.battle08,1));
this.soundButtonList.get(8).setTag(soundPool.load(this,R.raw.battle09,1));
this.soundButtonList.get(9).setTag(soundPool.load(this,R.raw.battle10,1));
this.soundButtonList.get(10).setTag(soundPool.load(this,R.raw.se_tori01,1));
this.soundButtonList.get(11).setTag(soundPool.load(this,R.raw.se_tori02,1));
this.soundButtonList.get(12).setTag(soundPool.load(this,R.raw.se_pi01,1));
this.soundButtonList.get(13).setTag(soundPool.load(this,R.raw.se_pi02,1));
this.soundButtonList.get(14).setTag(soundPool.load(this,R.raw.se_pi03,1));
this.soundButtonList.get(15).setTag(soundPool.load(this,R.raw.se_neko01,1));
//ロード終了イベント登録
soundPool.setOnLoadCompleteListener(this);
}
@Override
protected void onPause() {
super.onPause();
//インスタンス解放
soundPool.unload(soundIDList[0]);
soundPool.unload(soundIDList[1]);
soundPool.unload(soundIDList[2]);
soundPool.unload(soundIDList[3]);
soundPool.unload(soundIDList[4]);
soundPool.unload(soundIDList[5]);
soundPool.unload(soundIDList[6]);
soundPool.unload(soundIDList[7]);
soundPool.unload(soundIDList[8]);
soundPool.unload(soundIDList[9]);
soundPool.release();
}
@Override
public void onClick(View v) {
// TODO 自動生成されたメソッド・スタブ
for(int i = 0; i < this.soundButtonList.size(); i++) {
if(this.soundButtonList.get(i).getId() == v.getId()) {
int soundId;
soundId = Integer.valueOf(this.soundButtonList.get(i).getTag().toString());
currentSoundID = soundPool.play(soundId,1,1,0,this.loopCount,0);
break;
}
}
if(v.getId() == this.loopCountButton.getId()) {
String s = this.loopCountEdit.getText().toString();
if(check(s) == true) {
this.loopCount = Integer.valueOf(s);
}
}
if(v.getId() == this.soundStopButton.getId()) {
soundPool.stop(this.currentSoundID);
}
// アプリのメモリ情報を取得
Runtime runtime = Runtime.getRuntime();
// トータルメモリ
this.totalMemoryText.setText("totalMemory[KB] = " + String.valueOf((runtime.totalMemory()/1024)));
// 空きメモリ
this.freeMemoryText.setText("freeMemory[KB] = " + String.valueOf(runtime.freeMemory()/1024));
// 現在使用しているメモリ
this.useMemoryText.setText("usedMemory[KB] = " + String.valueOf((runtime.totalMemory() - runtime.freeMemory())/1024));
// Dalvikで使用できる最大メモリ
this.dalvikMemoryText.setText("maxMemory[KB] = " + String.valueOf(runtime.maxMemory()/1024));
}
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
// TODO 自動生成されたメソッド・スタブ
if(status == 0) {
this.isSoundLoadEnd = true;
for(int i = 0; i < this.soundButtonList.size(); i++) {
this.soundButtonList.get(i).setEnabled(true);
}
}
}
/**
* ボタン初期化処理
* @param button
* @param id
*/
private void initButtonView(Button button, int id) {
button = (Button)findViewById(id);
button.setOnClickListener(this);
button.setEnabled(false);
this.soundButtonList.add(button);
}
/**
* 数値チェック
* double に変換でききない文字列が渡された場合は false を返します。
* @param str チェック文字列
* @return 引数の文字列が数値である場合 true を返す。
*/
public boolean check(String str) {
try {
Double.parseDouble(str);
return true;
} catch(NumberFormatException e) {
return false;
}
}
}
では、簡単な説明
サウンドファイルを読み込む場所はonResumeです。
ボタンリストを作成して、各ボタンのTagにサウンドファイル読込時のIDを格納しています。
//インスタンス生成
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
//ファイルロード
//ボタンのタグに読込んだIDを設定する。
this.soundButtonList.get(0).setTag(soundPool.load(this,R.raw.battle01,1));
this.soundButtonList.get(1).setTag(soundPool.load(this,R.raw.battle02,1));
16個ほど、サイズ合計で242KBほどLoadしてみましたが動作としては一瞬でおわりました。(ちなみに各サウンドファイルサイズは一番大きいサイズで30KBです)
サウンドファイルの解放はonPause内に記述します。
@Override
protected void onPause() {
super.onPause();
//インスタンス解放
soundPool.unload(soundIDList[0]);
soundPool.unload(soundIDList[1]);
各ボタン押下で画面で指定したループ回数を設定して再生ボタンのTagに登録したIDを使ってsoundPool.playで再生します。
その際停止処理ように現在再生中のサウンドIDをcurrentSoundIDに保持
@Override
public void onClick(View v) {
// TODO 自動生成されたメソッド・スタブ
for(int i = 0; i < this.soundButtonList.size(); i++) {
if(this.soundButtonList.get(i).getId() == v.getId()) {
currentSoundID = Integer.valueOf(this.soundButtonList.get(i).getTag().toString());
soundPool.play(currentSoundID,1,1,0,this.loopCount,0);
break;
}
}
停止ボタン押下処理でcurrentSoundIDをつかって停止処理を実行
if(v.getId() == this.soundStopButton.getId()) {
soundPool.stop(this.currentSoundID);
}
結構簡単にできた!とおもいきや、実際動かすと、再生もできるし、ループ回数の設定もうまくいくが途中で音を止めるのがなか効かない!!
ちゃんと調べた結果。。。完全に勘違いしてました(ノД`)
ストップのときはsoundPool.playの戻り値IDを使用すること。
load時のsoundIDではないことに注意。
修正版のソース(上の全体ソースは修正済みです)
@Override
public void onClick(View v) {
// TODO 自動生成されたメソッド・スタブ
for(int i = 0; i < this.soundButtonList.size(); i++) {
if(this.soundButtonList.get(i).getId() == v.getId()) {
int soundId;
soundId = Integer.valueOf(this.soundButtonList.get(i).getTag().toString());
currentSoundID = soundPool.play(soundId,1,1,0,this.loopCount,0);
break;
}
}
カテゴリーへ