知育アプリをつくってみたい。 -STEP1-

2012.10.25

はじめて2、3歳くらいの小さなこどもが自然に iPhoneでスワイプしたり、ピンチイン・ピンチアウトしたり してるのを見た時は、これがデジタルネイティブかー。がーん!ってなりましたが 最近はそんな光景ももうなれっこになりました。 この間お友達のこどもがアプリで遊んでいるのをみていたら、 私も知育アプリをつくってみたくなりました。 アプリをつくった事がないし勉強にもなるしってことでやってみようと思います!

知育アプリ、どんなものがあるのかGoogle playで見てみました。 Google playの知育アプリ色々あります。 Android用じゃないけど、わたしが好きな知育アプリはToca Tea Partyです。たのしそう。 シリーズものなのかな、TOCA BOCAサイトに色々あります。

アプリ作成初心者がいきなり素敵なものをつくるのはむつかしいので、ちょっぴりずつ進んでいきます。 まずは、どうぶつの鳴き声と絵をあてていくアプリをつくってみたいと思います。

  • STEP1. ボタンをタップしたら、そのボタンにあったどうぶつの鳴き声が出るようにします。
  • STEP2. ボタンをタップしたら音も出て、そのボタンにあったどうぶつの絵が出るようにします。
  • STEP3. デザインをどうしたらよいかなと考えてみます。
  • STEP4. デザインしてみます。
  • STEP5. どうぶつの鳴き声をきいて、鳴き声にあうどうぶつの絵をあてるようなクイズにします。

今回はSTEP1をやってみます。見た目は、ボタンをただ並べているだけです。

■MainActivity.java

package com.example.intellectualtrainingapp_soundpool;


import android.app.Activity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {

	private SoundPool soundPool;

	private Button birdButton;
	private Button catButton;
	private Button sheepButton;
	private Button dogButton;
	private Button lionButton;
	private Button dinosaurButton;

	private int loadCnt;

	private int[] resources = {
			R.raw.bird,
			R.raw.cat,
			R.raw.sheep,
			R.raw.dog,
			R.raw.lion,
			R.raw.dinosaur
	};

	private int[] soundIdArray;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        birdButton = (Button)findViewById(R.id.bird);
        catButton = (Button)findViewById(R.id.cat);
        sheepButton = (Button)findViewById(R.id.sheep);
        dogButton = (Button)findViewById(R.id.dog);
        lionButton = (Button)findViewById(R.id.lion);
        dinosaurButton = (Button)findViewById(R.id.dinosaur);

        birdButton.setOnClickListener(this);
        catButton.setOnClickListener(this);
        sheepButton.setOnClickListener(this);
        dogButton.setOnClickListener(this);
        lionButton.setOnClickListener(this);
        dinosaurButton.setOnClickListener(this);

        changeButtonEnabled(false);

        soundIdArray = new int[resources.length];
        soundPool = new SoundPool(resources.length, AudioManager.STREAM_MUSIC, 0);
        soundPool.setOnLoadCompleteListener(loadCompleteListener);
    }

    @Override
    public void onResume() {
    	super.onResume();
        for(int i = 0; i < resources.length; i++) {
        	soundIdArray[i] = soundPool.load(this.getApplicationContext(), resources[i], 1);
        }
    }

    @Override
    public void onPause() {
    	super.onPause();
    	soundPool.release();
    }

    private OnLoadCompleteListener loadCompleteListener = new OnLoadCompleteListener() {
		@Override
		public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
			loadCnt++;
			if(loadCnt == resources.length) {
				changeButtonEnabled(true);
			}
		}
	};

	private void changeButtonEnabled(boolean b) {
        birdButton.setEnabled(b);
        catButton.setEnabled(b);
        sheepButton.setEnabled(b);
        dogButton.setEnabled(b);
        lionButton.setEnabled(b);
        dinosaurButton.setEnabled(b);
	}

	@Override
	public void onClick(View v) {
		if(v == birdButton) {
			soundPool.play(soundIdArray[0], 100, 100, 1, 0, 1);
		}else if(v == catButton) {
			soundPool.play(soundIdArray[1], 100, 100, 1, 0, 1);
		}else if(v == sheepButton) {
			soundPool.play(soundIdArray[2], 100, 100, 1, 0, 1);
		}else if(v == dogButton) {
			soundPool.play(soundIdArray[3], 100, 100, 1, 0, 1);
		}else if(v == lionButton) {
			soundPool.play(soundIdArray[4], 100, 100, 1, 0, 1);
		}else {
			soundPool.play(soundIdArray[5], 100, 100, 1, 0, 1);
		}
	}
}
[/java]

<h4>MediaPlayerとSoundPool</h4>
<p>
音を出すやり方は、MediaPlayerを使う方法とSoundPoolを使う方法があります。
MediaPlayerは、BGMとして音をながす時など
尺の長い音ファイルを扱うのに向いています。
SoundPoolは、最初にメモリにロードするので再生時に
遅延がほとんど生じません。なのでゲームの効果音の再生などに向いています。
他には、複数の音を重ねることもできます。
注意点としては、SoundPoolを使う場合mp3形式も読み込めるけれど、
wav形式、ogg形式がよいようです。今回は、ボタンをタップして音をならすので
SoundPoolを使います。
</p>

<h4>①準備</4>
<p>以下の図の様にresフォルダに、rawフォルダを作ります。そこにogg形式の音ファイルをおきます。</p>
<p><a href="https://dev.classmethod.jp/smartphone/android/cognitive-education-step1/attachment/oo_step1_02/" rel="attachment wp-att-33700"><img src="https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2012/10/oo_step1_02--303x506.jpg" alt="" title="oo_step1_02" width="303" height="506" class="alignnone size-thumbnail wp-image-33700" /></a></p>

<h4>②onCreate()</h4>
<p>59行目でSoundPoolのインスタンスを生成します。</p>

soundPool = new SoundPool(resources.length, AudioManager.STREAM_MUSIC, 0);

引数が3つあります。

  • 1つ目は、作成するSoundPoolオブジェクトの同時使用できる最大ストリーム数を指定します。
  • 2つ目は、オーディオストリームの種類。(今回はAudioManager.STREAM_MUSICを指定します。 他には、STREAM_ALARMアラーム音、STREAM_NOTIFICATION 通知音 等があります。)
  • 3つ目は、サンプリングレート(サンプリング周波数)の品質。デフォルトは0です。

③onResume()

67行目でロードします。 SoundPoolは、デコードに時間がかかる為、ロードしたオーディオファイルをすぐに再生できないのでonResume()のタイミングでロードします。

soundIdArray[i] = soundPool.load(this.getApplicationContext(), resources[i], 1);

④onClick()

ボタンをおしたら音を再生します。

soundPool.play(soundIdArray[0], 100, 100, 1, 0, 1);

引数が6つあります。

  • 1つ目は、load()で返されるIDです。ここで返されるIDを使って再生する音を指定します。
  • 2つ目は、左の再生音量です。
  • 3つ目は、右の再生音量です。
  • 4つ目は、ストリームの優先順位です。
  • 5つ目は、ループさせたい回数です。
  • 6つ目は、再生速度です。

⑤onPause()

74行目で開放します。

soundPool.release();

ボタンを押すと、にゃー!とかガオー!とか鳴るようになりました。

次回は、ボタンをタップしたら音も出て、そのボタンにあったどうぶつの絵が出るようにします。