音感センサーを利用したサンプルアプリ

タグ: , ,

今回のサンプルアプリは音感センサーを利用したアプリを作っていきます。

手順の説明

準備
  • 手順1:新しいAndroidプロジェクトを作成する
  • 手順2:レイアウトを決定する
  • 手順3:必要なActivity/Javaクラスを用意する
  • 手順4:各ファイルに処理を書く
  • 手順5:エミュレター/実機で実行

準備

今回のサンプルアプリ構築の為の環境を確認していきます。

  • 実機を利用して実行テストを行いますので、実機テスト環境を確認してください。

手順1:新しいAndroidプロジェクトを作成する

「ファイル」→「新規」→「プロジェクト」ウィザードが開く。
「Android Project」を選択して「次へ」。New Android Projectが開く。

  • プロジェクト名:Sound_app
  • アプリケーション名:音感センサー
  • パッケージ名を入力:isa.android
  • ターゲット名:Android2.1 7
  • Create Activity:MainActivity
  • Min SDK Version:7

手順2:レイアウトを決定する

以下の様な構成でレイアウトにしたいと思います。

ファイル構成
  • main.xml
  • LightView.java
  • MainActivity.java
  • SoundSwitch.java
レイアウト構成
Androidアプリ レイアウト Androidアプリ レイアウト Androidアプリ レイアウト

手順3:必要なActivity/Javaクラスを用意する

今回のサンプルアプリではxmlファイルが1枚、Javaファイルが3枚必要となります。

JavaClassの生成

まず、SoundSwitch.javaのJavaクラスファイルを用意してみます。

  1. プロジェクト/src/isa.androidにフォーカスをあてて右クリック。
  2. 「新規」→「クラス」を選択します。
  3. 名前に「SoundSwitch」を入力して完了。
  4. インターフェース「追加」をクリック→「実装されたインターフェース」が立ち上がる
  5. インターフェースの選択に「Runnable」を入力→「OK」をクリック

LightView.javaのJavaクラスファイルを皆さんで用意してみましょう。各項目への設定は次の通りです。

  • クラス名:LightView
  • スーパークラス:android.view.View
AndroidManifest.xmlへパーミッションを追加

今回のサンプルは音感センサーを利用しますので、音を拾う必要があります。 音を拾う機能としてマイク機能を利用して音を拾います。 次はAndroidManifest.xmlへマイク機能を利用する為のパーミッションの追加をしてあげます。 具体的ソースコードは次の通りです。

<!-- マイク機能を利用する為にパーミッションを追加 マイク利用の許可-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />

パーミッションを追加する場所は「manifest」の直下になります。

MainActivity.javaの処理を書く
importクラスの準備

今回もimportクラスの準備を進めていきます。 importクラスは次の通りです。みなさんで追加してみましょう。

  • android.os.Bundle
  • android.os.Handler
  • android.view.WindowManager
おさらい

importファイルの追加は前回にも行ったとおりです。

import クラス名;


変数の宣言

次はMainActivityクラスで使用する変数を宣言します。変数の宣言は前回と同じです。各設定は次の通りです。皆さんで追加してみましょう。

SoundSwitchの宣言
  • アクセス修飾子:private
  • 型名:SoundSwitch
  • 変数名:mSoundSwitch
LightViewの宣言
  • アクセス修飾子:private
  • 型名:LightView
  • 変数名:mLightView
Handlerの宣言
  • アクセス修飾子:private
  • 型名:Handler
  • 変数名:mHandler

※Handlerクラスはインスタンス化しておきましょう。

MainActivity.javaに必要なメソッド

MainActivity.javaに必要なメソッドを用意していきます。必要なメソッドは次の通りです。 皆さんでメソッドを準備してみましょう。

  • onResume
  • onPause
各メソッド内の処理を書いていきます。
onCreateメソッド
mLightView = new LightView(this);//LightViewの呼び出し
setContentView(mLightView);//画面に表示するviewを指定
// 暗くならないようにする
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
onResumeメソッド
mSoundSwitch = new SoundSwitch();
// リスナーを登録して音を感知できるように
mSoundSwitch.setOnVolumeReachedListener(
new SoundSwitch.OnReachedVolumeListener() {
// 音を感知したら呼び出される
public void onReachedVolume(short volume) {
// 別スレッドからUIスレッドに要求/Handler.postでエラー回避
mHandler.post(new Runnable() {
//Runnableに入った要求を順番にLoopでrunを呼び出し処理
public void run() {
//LightViewクラスのrandomDrawで描画を依頼
mLightView.randomDraw();
}
});
}
});
// 別スレッドとしてSoundSwitchを開始(録音を開始)
new Thread(mSoundSwitch).start();
onPauseメソッド
// 録音を停止
mSoundSwitch.stop();

以上でMainActivity.javaの処理が書き終わりました。

LightView.javaの処理を書く
importクラスの準備

LightView.javaの処理です。まずは、importクラスを用意します。 importクラスは次の通りです。みなさんで追加してみましょう。

  • java.util.Random
  • android.content.Context
  • android.view.View
  • android.graphics.Canvas
  • android.graphics.Color
  • android.view.animation.AlphaAnimation

変数の宣言

次はLightViewクラスで使用する変数を宣言します。変数の宣言は前回と同じです。各設定は次の通りです。皆さんで追加してみましょう。

AlphaAnimationの宣言
  • アクセス修飾子:private
  • 型名:AlphaAnimation
  • 変数名:mAnimation
Randomの宣言
  • アクセス修飾子:private
  • 型名:Random
  • 変数名:random

※Randomクラスはついでにインスタンス化しておきましょう。

最後に「描画する色」の変数を宣言しておきます。具体的なソースコードは次の通りです。

// 描画する色
private int mColor = Color.BLACK;
private int[] mColors = new int[] {
Color.rgb(237,  26,  61), // 赤
// 橙
// 黄
// 緑
// 青
// 藍
// 紫
};

以上で赤色(描画する色)が配列にプッシュされました。その他の色は皆さんで呼び出してみましょう。

以上の手順でredのカラーintができました。 上記の手順を参考に残りのカラーintを皆さんで作ってみましょう。設定は次の通りです。

  • 255, 183, 76
  • 255, 212, 0
  • 0, 128, 0
  • 0, 154, 214
  • 35, 71, 148
  • 167, 87, 168

LightView.javaに必要なメソッド

LightView.javaに必要なメソッドを用意していきます。具体的なソースコードは次の通りです。

//LightViewのコンストラクタ
public LightView(Context context) {
super(context);
}
//ランダム関数の処理
public void randomDraw() {
}
//画面の描画
@Override
protected void onDraw(Canvas canvas) {
}

各メソッド内の処理を書いていきます。
LightViewのコンストラクタ
// だんだん透明になるAlphaAnimationを生成
mAnimation = new AlphaAnimation(1, 0);
// 3秒で動くように
mAnimation.setDuration(3000);
// 終了後、元に戻らないように
mAnimation.setFillAfter(true);
ランダム関数の処理
// アニメーション中に次のアニメーションが動いて
// 欲しいのでキャンセルする
clearAnimation();
// 色をランダムに選んで
mColor = mColors[random.nextInt(mColors.length)];
// アニメーション開始
startAnimation(mAnimation);
画面の描画
// 画面を指定された色で塗りつぶす
canvas.drawColor(mColor);

以上でLightView.javaに必要なソースコードができあがりました。

SoundSwitch.javaの処理を書く
importクラスの準備

SoundSwitch.javaの処理です。まずは、importクラスを用意します。 importクラスは次の通りです。みなさんで追加してみましょう。

  • android.media.AudioFormat
  • android.media.AudioRecord
  • android.media.MediaRecorder

変数を宣言していきます。具体的ソースコードは次の通りです。

// ボリューム感知リスナー
private OnReachedVolumeListener mListener;
// 録音中フラグ
private boolean isRecoding = true;
// サンプリングレート
private static final int SAMPLE_RATE = 8000;//80.0KHz
// ボーダー音量
private short mBorderVolume = 10000;
SoundSwitch.javaに必要なメソッド

SoundSwitch.javaに必要なメソッドを用意していきます。具体的なソースコードは次の通りです。

// ボーダー音量をセット
public void setBorderVolume(short volume) {
}
// ボーダー音量を取得
public short getBorderVolume() {
}
// 録音を停止
public void stop() {
}
// OnReachedVolumeListenerをセット
public void setOnVolumeReachedListener(OnReachedVolumeListener listener) {
}
// ボーダー音量を検知した時のためのリスナー
public interface OnReachedVolumeListener {
}
// スレッド開始(録音を開始)
public void run() {
}
各メソッド内の処理を書いていきます。

ここは難しく考えず、今回はとりあえず、コピーしていきましょう。

setBorderVolumeメソッドの処理
mBorderVolume = volume;
getBorderVolumeメソッドの処理
return mBorderVolume;
stopメソッドの処理
isRecoding = false;
setOnVolumeReachedListenerメソッドの処理
mListener = listener;
OnReachedVolumeListenerメソッドの処理
// ボーダー音量を超える音量を検知した時に
// 呼び出されるメソッドです。
void onReachedVolume(short volume);
runメソッドの処理
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
int bufferSize = AudioRecord.getMinBufferSize(
SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC,
SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize);
short[] buffer = new short[bufferSize];
audioRecord.startRecording();
while(isRecoding) {
audioRecord.read(buffer, 0, bufferSize);
short max = 0;
for (int i=0; i<bufferSize; i++) {
// 最大音量を計算
max = (short)Math.max(max, buffer[i]);
// 最大音量がボーダーを超えていたら
if (max > mBorderVolume) {
if (mListener != null) {
// リスナーを実行
mListener.onReachedVolume(max);
break;
}
}
}
}
audioRecord.stop();
audioRecord.release();
}

以上で、SoundAwitch.javaが書けました。実機に転送して実行してみましょう。ちゃんと動いていれば成功です。

スプラッシュ画像を表示する

アプリを立ち上げた時に画像を表示します。一定時間経過の後、消えます。

設定する画像をDLする→利用するファイル。

表示用のxmlを用意

先程ダウンロードした画像をxmlに設定します。

ファイル名:splash.xml

<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerInside"
android:src="@drawable/goowa"
/>
スプラッシュ画像を表示するActivityを用意

スプラッシュ画像を表示してMainActivityに遷移させます。

ファイル名:SplashActivity.java

public class SplashActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.splash);
Handler hdl = new Handler();
hdl.postDelayed(new splashHandler(), 3000);
}
class splashHandler implements Runnable {
public void run() {
Intent i = new Intent(getApplication(), MainActivity.class);
startActivity(i);
SplashActivity.this.finish();
}
}
}
AndroidManifest.xmlを修正

初めにSplashActivityが表示されるよう変更する。

画面タップで.
OnClickListenerインターフェースの追加

//MainActivityにOnClickListenerインターフェースを実装。

ViewにListenerを設定

//光らせているViewにOnClickListenerをセットする。

onClickメソッドの実装する

//onClick(View v){}

完成予定のソースコード

MainActivity.java

package isa.android;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.WindowManager;
public class MainActivity extends Activity {
private SoundSwitch mSoundSwitch;
private LightView mLightView;
private Handler mHandler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLightView = new LightView(this);//LightViewの呼び出し
setContentView(mLightView);//画面に表示するviewを指定
// 暗くならないようにする
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@Override
public void onResume() {
super.onResume();
mSoundSwitch = new SoundSwitch();
// リスナーを登録して音を感知できるように
mSoundSwitch.setOnVolumeReachedListener(
new SoundSwitch.OnReachedVolumeListener() {
// 音を感知したら呼び出される
public void onReachedVolume(short volume) {
// 別スレッドからUIスレッドに要求するのでHandler.postでエラー回避
mHandler.post(new Runnable() {//Runnableに入った要求を順番にLoopでrunを呼び出し処理
public void run() {
mLightView.randomDraw();//LightViewクラスのrandomDrawを呼び出して描画を依頼
}
});
}
});
// 別スレッドとしてSoundSwitchを開始(録音を開始)
new Thread(mSoundSwitch).start();
}
@Override
public void onPause() {//Activityの状態がonPauseの時の処理
super.onPause();//superクラスのonPauseを呼び出す
mSoundSwitch.stop();// 録音を停止
}
}

Lightview.java

package isa.android;
import java.util.Random;
import android.content.Context;
import android.view.View;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.animation.AlphaAnimation;
public class LightView extends View {
private AlphaAnimation mAnimation;
private Random random = new Random();
// 描画する色
private int mColor = R.color.BLACK;
private int[] mColors = new int[] {
    Color.rgb(237,  26,  61), // 赤
Color.rgb(255, 183,  76), // 橙
Color.rgb(255, 212,   0), // 黄
Color.rgb(  0, 128,   0), // 緑
Color.rgb(  0, 154, 214), // 青
Color.rgb( 35,  71, 148), // 藍
Color.rgb(167,  87, 168)  // 紫
};
public LightView(Context context) {
super(context);
// だんだん透明になるAlphaAnimationを生成
mAnimation = new AlphaAnimation(1, 0);
// 3秒で動くように
mAnimation.setDuration(3000);
// 終了後、元に戻らないように
mAnimation.setFillAfter(true);
}
public void randomDraw() {
// アニメーション中に次のアニメーションが動いて
// 欲しいのでキャンセルする
clearAnimation();
// 色をランダムに選んで
mColor = mColors[random.nextInt(mColors.length)];
// アニメーション開始
startAnimation(mAnimation);
}
@Override
protected void onDraw(Canvas canvas) {
// 画面を指定された色で塗りつぶす
canvas.drawColor(mColor);
}
}

SoundSwitch.java

package isa.android;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
public class SoundSwitch implements Runnable {
// ボリューム感知リスナー
private OnReachedVolumeListener mListener;
// 録音中フラグ
private boolean isRecoding = true;
// サンプリングレート
private static final int SAMPLE_RATE = 8000;//80.0KHz
// ボーダー音量
private short mBorderVolume = 10000;
// ボーダー音量をセット
public void setBorderVolume(short volume) {
mBorderVolume = volume;
}
// ボーダー音量を取得
public short getBorderVolume() {
return mBorderVolume;
}
// 録音を停止
public void stop() {
isRecoding = false;
}
// OnReachedVolumeListenerをセット
public void setOnVolumeReachedListener(
OnReachedVolumeListener listener) {
mListener = listener;
}
// ボーダー音量を検知した時のためのリスナー
public interface OnReachedVolumeListener {
// ボーダー音量を超える音量を検知した時に
// 呼び出されるメソッドです。
void onReachedVolume(short volume);
}
// スレッド開始(録音を開始)
public void run() {
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
int bufferSize = AudioRecord.getMinBufferSize(
SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC,
SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize);
short[] buffer = new short[bufferSize];
audioRecord.startRecording();
while(isRecoding) {
audioRecord.read(buffer, 0, bufferSize);
short max = 0;
for (int i=0; i<bufferSize; i++) {
// 最大音量を計算
max = (short)Math.max(max, buffer[i]);
// 最大音量がボーダーを超えていたら
if (max > mBorderVolume) {
if (mListener != null) {
// リスナーを実行
mListener.onReachedVolume(max);
break;
}
}
}
}
audioRecord.stop();
audioRecord.release();
}
}

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainActivity!</string>
<string name="app_name">音感センサー</string>
</resources>

日付: Monday November 29th, 2010 | カテゴリ: goowalog > システム・アプリ - 制作メモ

記事カテゴリ
カテゴリ内アーカイブ
  • メニュー/トップページへ
  • メニュー/会社概要へ
  • メニュー/事業内容へ
  • メニュー/スタッフ紹介へ
  • メニュー/採用情報へ
  • メニュー/制作実績へ
  • メニュー/goowaログへ
  • メニュー/お問い合わせへ
  • メニュー/アクセス案内へ
最新の問い合わせ事案
  • 2019/08/09:
    (日本語) 建築パース制作
  • 2019/07/20:
    (日本語) パンフレット制作
  • 2019/07/15:
    (日本語) 建築パース制作
  • 2019/06/20:
    (日本語) WEBサイトリニューアル
  • 2019/05/01:
    (日本語) WEBサイトコンサルティング
  • 2019/01/07:
    (日本語) LINE Bot製作
  • 2018/11/28:
    (日本語) 災害時安否確認システム
  • 2018/10/21:
    (日本語) webシステム構築
  • 2018/10/05:
    (日本語) iOS/Androidアプリ製作
  • 2018/09/13:
    (日本語) オーダリングシステム開発