2010年7月26日月曜日

AndroidでBluetooth

AndroidでBluetoothを扱うAPIのテスト。
ということで、色々と周辺調査したので箇条書きにしてみる。


・Android用BluetoothAPIには公式のものと非公式のものがある
・公式のAPIはAndroidOSのバージョンが2.0以上で無いと使用不可
・OSのバージョンが1.0系の場合、非公式BluetoothAPIを使用する必要がある
・非公式APIにはいくつかあるが今回は"backport-android-bluetooth"を使用してみた


以下ざっくりしたbackport-android-bluetooth使用手順


1.このサイトよりbackport-android-bluetooth.jarをダウンロード
2.BluetoothAPIを使用するプロジェクトのライブラリにダウンロードしたjarファイルを追加(ココを参考に
3.マニフェストファイルにpermissionを変更する文言を追加(jarファイルをダウンロードしたサイトに載ってるヤツ
4.ソースコード内でimportする

これで使えるようになるはず。

2010年7月22日木曜日

マルチスレッドプログラミング

Androidでオーディオプログラミングの続きをしていた。

ネットでマルチスレッドを使って録音プログラム作っている人を発見[1]。
で、いじくってみようと思ったら、マルチスレッドプログラミングに関して余りにも無知なのでコードがよく理解できない…。

ということで、少し周辺知識について調べてみた。

・排他制御
複数のプログラムが一つのリソースにアクセスする際に、競合が発生しないように整合性を保つための仕組み[2]。


・同期
複数のエージェントの動作を時系列で制御すること[3]。
(エージェント:何らかの処理を行う仕組みのこと。プログラムとか)


・ハンドラ
割り込み時に実行されるプログラムのこと。
リスナーと同義[4][5]。


・セマフォ
同期機構の一種。
複数のスレッドが共有リソースにアクセスするような仕組みを作る際に、一度にアクセス出来るスレッドの数を制限したい時に使用する。
具体的にはセマフォ変数という共有変数を用いて実現される。
セマフォ変数の初期値は共有リソースに対して、一度にアクセス可能なスレッドの数である。
共有リソースにアクセスするスレッドはセマフォ変数をデクリメントする。
この時、セマフォ変数がゼロの場合、そのスレッドは共有リソースにアクセスすることは出来ない。
共有リソースへのアクセスが終了したスレッドはセマフォ変数をインクリメントする[6][7]。


・ミューテックス
同期機構の一種。
仕組みはセマフォと同じ。
セマフォ変数の初期値を1に設定したセマフォ。
複数のスレッドが共通のリソースにアクセスする際に、一つのスレッドのみにアクセス権を与えるようにして、スレッドを同期化する仕組み。
Mutexという語はMUTual EXclusion(相互排他)の略[8][9]。



・クリティカルセクション
マルチスレッドプログラミングにおいて、共有リソースを複数のスレッドが取り合うような部分のこと。クリティカルセクションを実行することが出来るスレッドの数は一つに限られる[10][11]。


参考URL
[1]http://d.hatena.ne.jp/yamanetoshi/20100202/1265116750
[2]http://ja.wikipedia.org/wiki/%E6%8E%92%E4%BB%96%E5%88%B6%E5%BE%A1
[3]http://ja.wikipedia.org/wiki/%E5%90%8C%E6%9C%9F_(%E6%83%85%E5%A0%B1%E5%B7%A5%E5%AD%A6)
[4]http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000546.html
[5]http://e-words.jp/w/E589B2E3828AE8BEBCE381BFE3838FE383B3E38389E383A9.html
[6]http://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%9E%E3%83%95%E3%82%A9
[7]
[8]http://ja.wikipedia.org/wiki/%E3%83%9F%E3%83%A5%E3%83%BC%E3%83%86%E3%83%83%E3%82%AF%E3%82%B9
[9]http://www-06.ibm.com/jp/domino04/pc/support/beginner.nsf/btechinfo/SYB0-014660D
[10]http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AA%E3%83%86%E3%82%A3%E3%82%AB%E3%83%AB%E3%82%BB%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3
[11]http://www.tokumaru.org/techterm/critical_section.html

昨日の続き

昨日のAudioRecord初期化エラーやっぱりpermissionが原因だった。
下記の記述をAndroidManifest.xmlのタグの前に追加したら問題なく動作した。

<uses-permission android:name="android.permission.RECORD_AUDIO">
</uses-permission>


参考URL
[1]http://groups.google.com/group/android-group-japan/browse_thread/thread/489149ff5e91eb73
[2]http://feedyomi.blog32.fc2.com/blog-entry-181.html


※あとブログ記事の中にタグを記述する方法について下記のサイトを参考にした。
http://www.wareteki.com/movabletype/archives/2005/07/html_3.html

2010年7月21日水曜日

Android AudioRecordクラス

Androidのマイク入力を扱うためにAudioRecordクラスのテスト。
色んなサイト見てコーディングしてみた。

…がうまくいかない。

ソースはこんなん(注:実行しても動きません→追記:permissionの設定すれば動きます。この記事参照)

package org.example.microphone;

import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.media.AudioRecord.OnRecordPositionUpdateListener;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class Microphone extends Activity {

private static final int AUDIO_SAMPLE_FREQ = 8000;
//Bufferサイズ(getMinBufferSize()で取得できる値の2倍)
private static final int AUDIO_BUFFER_SIZE = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_FREQ,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.CHANNEL_CONFIGURATION_MONO) * 2;

private static final String TAG = "debug";

AudioRecord record;
mNotification notificaiotn;
TextView textView;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

Log.d(TAG,String.valueOf(AUDIO_BUFFER_SIZE));

textView = (TextView)findViewById(R.id.textView);
setContentView(R.layout.main);

//recorderインスタンスのコンストラクタ設定
try{
record = new AudioRecord(MediaRecorder.AudioSource.MIC,
AUDIO_SAMPLE_FREQ,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
AUDIO_BUFFER_SIZE);
}
catch(IllegalArgumentException e){
e.printStackTrace();
}

Log.d(TAG,String.valueOf(record.getState()));

record.setNotificationMarkerPosition(50);
record.setPositionNotificationPeriod(100);
record.setRecordPositionUpdateListener(notificaiotn);


}

//オーディオ入力イベントリスナの実装
public class mNotification implements OnRecordPositionUpdateListener{

@Override
public void onMarkerReached(AudioRecord recorder) {
// TODO Auto-generated method stub

//read PCM buffer here
byte[] audioBuffer = new byte[AUDIO_SAMPLE_FREQ];
record.read(audioBuffer,0,AUDIO_SAMPLE_FREQ);

textView.setText(String.valueOf(audioBuffer));

}

@Override
public void onPeriodicNotification(AudioRecord recorder) {
// TODO Auto-generated method stub

//read PCM buffer here
byte[] audioBuffer = new byte[AUDIO_SAMPLE_FREQ];
record.read(audioBuffer,0,AUDIO_SAMPLE_FREQ);
}}

@Override
public void onPause(){
super.onPause();

}

}


どうもsetNotificationMarketPosition部分でAudioRecordのインスタンス初期化が出来ていないみたい。エラーログはこんな感じ。

07-21 21:54:24.749: ERROR/AudioFlinger(35): Request requires android.permission.RECORD_AUDIO

permissionの設定が問題なのかしら?
明日はそこら辺のいじくり方について調べるか。

----------
※参考URL
[1]http://www.mail-archive.com/android-developers@googlegroups.com/msg35441.html
[2]http://www.mailinglistarchive.com/html/android-group-japan@googlegroups.com/2009-10/msg00035.html
[3]http://d.hatena.ne.jp/yamanetoshi/20100202/1265036548
[4]http://www.mailinglistarchive.com/html/android-group-japan@googlegroups.com/2010-06/msg00617.html
[5]http://groups.google.co.jp/group/android-developers/browse_thread/thread/38cabdc4a48358a9?fwc=1
[6]http://developer.android.com/reference/android/media/AudioRecord.html

寝坊根絶

今日は寝坊してバイトをサボってしまった…。

本来起きなければいけない時間をブッちぎること4h。

昨日まで3日連続で研究室の大掃除をしていて疲れていた、なんてのは言い訳にならないわけで(じゃあ言うなよ)。
ダメじゃん、俺(関係者のみなさん、ご迷惑をお掛けしました)。


こんなダメな自分には優秀な秘書が必要だ。
キチンと時間通りに起こしてくれる秘書が(どちらかと言うと母親の役割だな、コレは)。
でも秘書を雇うカネは無い。
自分でスケジュール管理するしかない。
何とかせねば。


そんなことをボンヤリ考えているうちに、スケジュール帳から目覚ましを設定できればいいのにと思った。



自分はスケジュール管理を全部iPhone君におまかせしている。
デフォルトのカレンダーアプリとGoogleカレンダーをSynkして使っている。
このGoogleカレンダーの設定に「アラーム」みたいな設定項目を設けて、アプリ連携で設定した時間にアラーム鳴らす、みたいな感じで出来たらなと。


しかしiPhoneアプリを作るためには色々揃えなければいけないものがある。
MacPC、iPhoneアプリのDev登録…。
まぁつまりは金が必要だということだ。
普通に揃えたら10万円近くかかるであろう金が。
しかし、極貧学生の自分にそんな額の持ち合わせがある筈もない。


ということでタダで開発できるAndroidで(しかも今実機も手元にある)出来ないものかと思って、これを実現するために考え得る最大の障害、アプリ連携についてちょっと調べてみた。
ザッと箇条書きにしてみる。

・Androidでアプリ連携は可能
・アプリ間連携に用いられる「インテント」というモノがあるらしい
・インテントはアプリ間でやりとりするメッセージ
・あるアプリがインテントを発行すると、その内容を処理可能なアプリが勝手に起動して処理してくれる
・例えばTwitterクライアントでURLをクリックするとURLを含んだインテントが発行されて、Webブラウザが処理してくれる、メモ帳アプリからメール送信のインテントを発行するとメーラーが起動とか


こんな感じらしい。
インテントの存在はアプリ開発を非常にラクにしてくれそうだ。
iPhoneだと全部自分で実装しなきゃ、だから。

それに色々使い道考えるとワクワクする。

iPhoneアプリ使いながらさっきの案以外にもちょっと考えてみよう。


で、ヒマがあったらカレンダー&アラーム連携試してみよう。

参考URL http://www.atmarkit.co.jp/news/analysis/200906/29/android.html