スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

音を鳴らそう

Androidアプリで音を鳴らすときの注意。

音源を扱うクラスを作って、
インスタンスがたくさんできる意味はないと思ったからシングルトンにして、
メモリリークを避けるためにApplicationContextを取ってきて渡してインスタンスを生成した。


すると、Activityを切り替わると音が出なくなる現象が発生。

たとえば、Activity 1のボタンを押したときに音を出して、Activity 2に切り替えるとする。
そうすると、Activity 2ではボタンの音が出ない。
Activity 1で押し続ける分にはいくらでも音が出るのにだ。


このとき、MediaPlayer.seekTo(int mSec)でIllegalStateExceptionが発生している。

>Attempt to perform seekTo in wrong state: mPlayer=インスタンスID, mCurrentState=ステート番号


リファレンスによると、seekToはPrepared、Started、Paused、Playback Completedのいずれかでないと使えない。

Activityが切り替わると、SoundManagerで用意したMediaPlayerが初期化されない状態に戻ってしまい、
seekToは使えません。startもstopも使えません。
と怒られてしまう。


おそらく、音はActivityに関連付けられていて、Activityが変わればまた作らなきゃいけないんだと思う。


続きには、うまく動かないソースコードと、うまく動くソースコード。
うまく動かない

package jp.moriko;

import jp.moriko.R;
import android.content.Context;
import android.media.MediaPlayer;

public class SoundEffect {
public static final int EFFECT_BTN_OK = 0;
public static final int EFFECT_BTN_CANCEL = 1;

private MediaPlayer ok;
private MediaPlayer cancel;

// シングルトン
private static SoundManager instance;
public static SoundManager get(Context appContext){
if(instance == null){
instance = new SoundEffect();
instance.ok = MediaPlayer.create(appContext, R.raw.ok);
instance.cancel = MediaPlayer.create(appContext, R.raw.cancel);
}
return instance;
}

private SoundManager() {
}


/**
* 指定されたボタン効果音を鳴らす
*
* @param soundId
*/
public void btnSound(int soundId) {
btnSound(soundId, false);
}

public void btnSound(int soundId, boolean looping){
if (SettingItem.getButtonSound()) {
MediaPlayer mp = null;

switch (soundId) {
case EFFECT_BTN_OK:
mp = ok;
break;
case EFFECT_BTN_CANCEL:
mp = cancel;
break;
default:
break;
}
if (mp != null) {
mp.seekTo(0);
mp.setLooping(looping);
mp.start();
}
}
}
}





うまく動く


package jp.moriko;

import jp.moriko.R;
import android.content.Context;
import android.media.MediaPlayer;

public class SoundManager {
public static final int EFFECT_BTN_OK = 0;
public static final int EFFECT_BTN_CANCEL = 1;

private MediaPlayer ok;
private MediaPlayer cancel;

// シングルトンをやめた
public SoundManager(Context context) {
ok = MediaPlayer.create(context, R.raw.ok);
cancel = MediaPlayer.create(context, R.raw.cancel);
}


/**
* 指定されたボタン効果音を鳴らす
*
* @param soundId
*/
public void btnSound(int soundId) {
btnSound(soundId, false);
}
public void btnSound(int soundId, boolean looping){
if (SettingItem.getButtonSound()) {
MediaPlayer mp = null;

switch (soundId) {
case EFFECT_BTN_OK:
mp = ok;
break;
case EFFECT_BTN_CANCEL:
mp = cancel;
break;
default:
break;
}
if (mp != null) {
mp.seekTo(0);
mp.setLooping(looping);
mp.start();
}
}
}

}

テーマ : android
ジャンル : コンピュータ

コメントの投稿

管理者にだけ表示を許可する

プロフィール

森嶋晃介

Author:森嶋晃介
社会人2年目。
独学する勉強のために、いろいろ手を出して、それについて書いていく予定です。
今年こそ、たくさん書くぞ

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。