質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

2回答

2397閲覧

【Android】他のスレッド、アクティビティの処理は実行したまま、指定した時間待たせる【Java】

Puhu

総合スコア31

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2015/08/26 21:49

今、Android【Java】で音楽を再生する処理を作成しています。
ユーザからの入力なしに、自動で音楽を再生していきたいと思っています。
使用しているのはSoundPoolです。

音楽を再生させるときに、

for (int i = 0; i < 8; i++) {
codePlay.play(soundID[i], 1, 1, 0, 1, 0);//soundIDの中にはloadしたIDが格納されている。
}

とすると、うまく順々に再生させることができません。

そのために、指定した秒数流れたのが確認できたら、一度停止して、また再生を始めさせようと思うのですが
どのように実装したらいいのかがわからず困っています。

他の部分に干渉せずに処理を待つ、というやりかたか、そもそもSoundPoolではこんなことが出来るよ、等がありましたら、ぜひ教えて頂きたいです。

以下、再生部分のソース

public class MainActivity extends Activity {
static int loadEndFlag = 0;
static int[] soundID = {0,0,0,0,0,0,0};
static int[] codicide = {2, 0, 0, 0, 0, 0, 0, 2};
static int[] melody={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static int[] harmony={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static SoundPool codePlay//インスタンスの生成
//(ロードするファイルの数、AudioManager.STREAM_(種類)、サンプリングレートノクォリティ(default 0))
= new SoundPool(7, AudioManager.STREAM_MUSIC,0);
//0 = Am 1 = B 2 =C 3 = Dm 4 = Em 5= F 6 = G
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

SoundPool codePlay;//インスタンスの生成 //(ロードするファイルの数、AudioManager.STREAM_(種類)、サンプリングレートノクォリティ(default 0)) codePlay = new SoundPool(7, AudioManager.STREAM_MUSIC,0); soundID[0] = codePlay.load(this,R.raw.am4,1); soundID[1] = codePlay.load(this,R.raw.b4,1); soundID[2] = codePlay.load(this,R.raw.c4,1); soundID[3] = codePlay.load(this,R.raw.dm4,1); soundID[4] = codePlay.load(this,R.raw.em4,1); soundID[5] = codePlay.load(this,R.raw.f4,1); soundID[6] = codePlay.load(this,R.raw.g4,1); for(int i=0;i<soundID.length;i++) { Log.d("Checked", "soundID" + soundID[i]); } } @Override protected void onResume(){ super.onResume(); codePlay.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { @Override public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { if (0 == status) { //読み込みに成功するとステータスが0で帰って来る loadEndFlag = 1; } } }); if(loadEndFlag == 1) { Toast.makeText(this, "NOW - onResume", Toast.LENGTH_LONG).show(); codicide = SoundRandom(codicide); melody = melodySelect(codicide);(ここで、codicideという配列に、整数値を格納) for (int i = 0; i < 8; i++) { codePlay.play(codicide[i] - 1, 1, 1, 0, 1, 0);//codicide[i]と同じsoundIDに格納されている音を順番に再生。(させたい) } } } @Override protected void onDestroy() { super.onPause(); //インスタンス解放 for(int i=0;i<soundID.length;i++) { codePlay.unload(soundID[i]); codePlay.release(); } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

メインスレッドで重い処理をさせるのは推奨されていなかった(実行時警告が出る)と思いますので、ループ構文を使わずにActivityのライフサイクルを利用して回す事もできるかと思います。

投稿2015/08/27 02:03

T_Hashimoto

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Puhu

2015/08/27 10:06

ありがとうございます。確かに警告が出されて、うまく実行させることができませんでした。 今はonCreateでファイルをloadし、onResume()で再生とさせているのですが、うまくいきません。onResume()だけでは上手くサイクルできないのでしょうか。
T_Hashimoto

2015/08/27 10:33 編集

onResumeで完結する事は出来ると思います。 SoundPoolを使った事はありませんが、似たようなループ処理をダイヤル機能で実装した事があります。 その時も単純なループでは動作しなかったので、下記の様な実装となりました。 MainActivityのメインスレッドからRunnableでThread生成。 ↓ 新しいスレッドからStartActivity(Intent)でダイヤル。 Thread.Sleepでタイマーカウント。 タイムアウトで同期用のlockオブジェクト解放。 ↓ メインスレッドで電話を切る。 以上で動作するところまで持ってこれました。 activityとthreadの連携を工夫すれば応用できるかな?と思った次第です。
Puhu

2015/08/27 11:31

ありがとうございます! まだまだ初心者でわからないことだらけですがちょっとやってみようと思います!
guest

0

ベストアンサー

Java

1 for (int i = 0; i < 8; i++) { 2 codePlay.play(codicide[i] - 1, 1, 1, 0, 1, 0);//codicide[i]と同じsoundIDに格納されている音を順番に再生。(させたい) 3 }

ここでcodePlay.playの第一引数にcodicide[i] - 1を渡していますが、soundID[i]の間違いではないでしょうか。

投稿2015/08/26 23:44

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Puhu

2015/08/27 00:05

ご回答ありがとうございます! すみません、もともとソースを載せるつもりでなく、変数名で分かりやすく説明しようと思い、上のfor文のところではsoundID[i]と記述しました。 本来であれば、計算結果から求められた0~6の値がcodicide[i]に格納されます。、soundPool#loadの返り値が1~なため、soundPool#play()ではcodicide[i]+1とさせて頂いています。 わかりづらい記述、大変失礼いたしました。
yona

2015/08/27 00:29 編集

定期実行するなら下記でできると思いますが、本質的な解決はしていないと思います。 new Thread(new Runnable() { @Override public void run() { for(int i = 0 ; i < 7 ; i++){ try { codePlay.play(codicide[i] - 1, 1, 1, 0, 1, 0); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start();
Puhu

2015/08/27 00:50

ありがとうございます! 参考にさせて頂きます! 今、いろいろと検証していたところ、どうやらいつまでたってもSoundPoolのloadが終わらないことが原因ではないか、という判断になりました。 yona様はSoundPoolに精通していらっしゃいますでしょうか? もしそうであれば、何故ロードが終わらないかのヒントだけでも頂けましたら幸いです。  そうではない場合は、勿論お答えいただかなくて結構です、失礼いたしました。 一つ前のコメントで頂いた指定した秒数を待つ、というやり方は今後使わせていただきたいと思います! yona様の迅速かつ親身になって受け答えしていただけるところ、大変助けになっています。  本当にありがとうございます。
yona

2015/08/27 01:23

ロードが終わらないとはSoundPool#loadの戻り値が0ということでしょうか。 SoundPool#loadは非同期処理で行われています。そのため、loadの完了後にSoundPool#playをしないといけません。完了通知を受け取るためにSoundPool#setOnLoadCompleteListenerを使用する必要があります。
Puhu

2015/08/27 01:43

setOnLoadCompleteListenerを実装しているのですが、何故かそこに入ってくれません。 setOnLoadCompleteListenerを使わない方法として、再生に失敗した場合(読み込めてない等の理由でSoundPool#play()の戻り値が0だったときは new Thread(new Runnable() { @Override public void run() { for(int i = 0 ; i < 8 ; i++){ try { do { codeplayed[i] = codePlay.play(codicide[i] + 1, 0, 0, 0, 1, 0); }while(codeplayed[i] == 0); codeplayed[i] = codePlay.play(codicide[i] + 1, 1, 1, 0, 1, 0); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); としてみたのですが、いつまでたっても無限ループをしており、一向に抜ける気配がありません。
yona

2015/08/27 03:41

コードが更新されているのに気づきませんでした。 上のコードではロードの完了を待つことにはなりません。 OnLoadCompleteListener#onLoadCompleteはロード完了後に呼ばれるメソッドです。 コードのif(loadEndFlag){//再生処理}をOnLoadCompleteListener#onLoadCompleteの中に入れてください。
Puhu

2015/08/27 10:05

ありがとうございます! 解決したかはわかりませんが、一歩進んだ気がします! 
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問