FC2ブログ

なんかいろいろこんぴゅーたかんけいのなぐりがき

なんか勉強しているこんぴゅーた関係のことのメモやそれ以外のことを書こうかなあ...

logs

Android Bluetoothプログラミング

AndroidのBluetoothプログラミングは資料が少なくて大変だが、とりあえず簡単なコードをかいてみた。
このプログラムではBluetoothの電源がOFFであればONにし、ONであったなら、既にピアリングしているデバイスの情報をログに出力する。

パッケージ名はプロジェクトで指定したものに変更し、マニフェストファイルで
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
を記述してパーミッションを得ないといけない。
さらにOSは2.0.1だっけか、それくらい以上でなければならないようである。
以下プログラム



package foo.bar.searchBT;

import java.util.Set;
import java.util.Vector;

import android.app.Activity;
import android.content.Intent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class SerachBluetoothDevices extends Activity {
private static final int REQUEST_ENABLE_BT = 1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onStart()
{
super.onStart();
BluetoothAdapter bluetooth_adapter = BluetoothAdapter.getDefaultAdapter();
//端末がBluetoothに対応していない場合終了する
if(bluetooth_adapter == null)
{
Toast.makeText(this, "この端末はBluetoothを利用できません。終了します。", Toast.LENGTH_LONG);
finish();
}
//もしBluetoothがOFFになっていたらONにするようにする
if(!bluetooth_adapter.isEnabled())
{
Intent enable_bt = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enable_bt,REQUEST_ENABLE_BT);
}
//もしBluetoothがONに最初からなっていたら
else
{
Vector<BluetoothDevice> devices = new Vector<BluetoothDevice>();
//getBoundedDevicesによってピアリングが既になされているデバイスを取得する
Set<BluetoothDevice> paired_devices = bluetooth_adapter.getBondedDevices();
//BluetoothDeviceのインスタンスをdevicesインスタンスに追加していく
for(BluetoothDevice device : paired_devices)
{
devices.add(device);
}
//devicesに保存されたBluetoothDeviceインスタンスを利用して順番に情報をログに出力していく
for(int i=0;i<devices.size();i++) Log.d("debug",devices.elementAt(i).getName()+":"+devices.elementAt(i).getAddress());

}

}
}

AndroidでBluetooth2

なかなかうまくいかなかったAndroidBluetootuプログラミング。
しかし今日は進展を見せた。

google がAndroidでのBluetooth公式APIの紹介のために公開しているサンプルプログラム。
とりあえずこれと、PyBluezでPC Android間Bluetooth通信を実現させたかったわけだが、なかなかうまくいかずにいたが、今日進展した。

まずアプリはAndroidMarketでBluetoothTalkという名前でサンプルコードをビルドしたものがあるのでそれを使っていた。
このプログラムはBluetoothでチャットができる。アプリが起動するとアプリはサーバーとして稼動して、クライアントが接続できるようになる。また、メニューからデバイスを探せば逆にクライアントとして機能する。

確かに、良サンプルではあるのだが、少しばかりコードが長く、もっと簡潔にして欲しかった。普通にチャットプログラムとして利用できる完成度である。

えーと、とにかく、このアプリを起動した後に、PyBluezの対話シェルとかで、ClientとしてAndroid端末にまずは接続してみようと思っていたわけです。で、まあうまくいかないことが6時間ほど続いて、他のサンプルを探し回ったりしたけど見つからなくて悩んだあげく気づいたことが、

通常のsocketプログラムでは接続にアドレスとポート番号、もしくはポート番号だけ使うことが多いのだけと、Androidのサンプルコードではポートが一切でてこない。代わりにUUIDなるものがでてきて、これを利用してポートを決定するようだ。
なぜわざわざUUIDを迂回して決まるのかはっきりとは知らないが、多分セキュリティ向上のためであろう。

とりあえず動く、をモットーとしているへっぽこプログラマな私にには不要である。


と、まあ、UUIDが接続に重要であることがわかったのでAndroid側のサンプルコードに記載されているUUIDの文字列をPyBluezのサンプルコードにコピーしたのが以下のコード


import bluetooth
import sys

uuid = "fa87c0d0-afac-11de-8a39-0800200c9a66"
sm = bluetooth.find_service(uuid=uuid)
if len(sm) == 0:
print "Servie couldn't find"
sys.exit(0)

fm = sm[0]
port = fm["port"]
name = fm["name"]
host = fm["host"]
sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
sock.connect((host, port))
while True:
sock.send("hello")

で、実際これを実行すると、Android側に hello が連呼されて おおー! ってなったよ。

それで
このコードのみそはfind_service指定したUUIDと同じUUIDを持つサーバーを探すして、そこから
port番号とかをgetしていること、あとは普通にsocketプログラム感覚でいける。


少し寝るか。

AndroidでBluetooth

AndroidのBluetoothプログラミングをしようと思ったら、参考文献が少なすぎて大変だった。

とりあえずできたとこまでのサンプルをあげておく

このサンプルではまずBluetoothを実行しているデバイスで使えるかまずチェックし、
Bluetoothが使えるようなら次は、Bluetoothの電源が入っているか確認し、ONだった
場合はペアリングリストを取得してトーストで表示してみる
OFFだった場合はONにするようにたずねる。
もしそこでキャンセルされたらプログラム終了する
OKだったらBluetoothがONになる。

REQEST_ENABLE_BT = 2; はなぜ「2」なのか
よく分からんがサンプルは2にしてたから一応それに習った。
多分意味はない。
参考ソースはサンプルでついてくるアプリのBluetoothChat
を参考にした。誰か日本語で分かりやすい説明を書いてくれると助かるなあ


package com.BluetothPairList;

import java.util.Set;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

public class BluetoothPairList extends Activity {
/** Called when the activity is first created. */
private static final int REQEST_ENABLE_BT = 2;
public static Context context;
public static Activity activity;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
BluetoothAdapter myBluetoothAdapter = BluetoothAdapter
.getDefaultAdapter();
if (myBluetoothAdapter == null) {
// もしデバイスがBluetoothをサポートしていなかった場合
Toast.makeText(this, "このデバイスはBluetoothをサポートしていません",
Toast.LENGTH_LONG).show();
return;
}
if (!myBluetoothAdapter.isEnabled()) {
// もしBluetoothの設定がオフになっていたらONにする
Intent set_enable = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(set_enable, REQEST_ENABLE_BT);
} else {
// 既にペアリングしているデバイスの名前とアドレスを取得する
Set<BluetoothDevice> paired_devices = myBluetoothAdapter
.getBondedDevices();
if (paired_devices.size() > 0) {
for (BluetoothDevice device : paired_devices) {
Toast.makeText(this,
device.getName() + device.getAddress(),
Toast.LENGTH_LONG).show();
}

} else
Toast.makeText(this, "ペアリングされているデバイスがみつかりませんでした",
Toast.LENGTH_LONG).show();
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
switch (requestCode) {
case REQEST_ENABLE_BT:
if (resultCode == Activity.RESULT_OK) {
// キャンセルされた場合
Toast.makeText(this, "BluetoothをONにしようとしましたが、失敗しました",
Toast.LENGTH_LONG).show();
finish();
} else {
// ONにすることに成功した場合
Toast.makeText(this, "BluetoothがONになりました", Toast.LENGTH_LONG)
.show();
}

}
}
}



androidアプリでバグレポート

アンドロイドOS2.2にはバグレポートの機能がついているらしいが、
現在普及しているアンドロイドOSにはそんな機能はついていないので、開発者側が実装する必要がある



Androidアプリのバグ報告システムを考える
http://www.adamrocker.com/blog/288/bug-report-system-for-android.html

というページが非常に参考になった。感動した。

ただし、この機能はマニフェストファイルで外部ストレージのパーミッションを宣言しておかないとSDカードに
書き込みができなくてはまる

Androiddアプリメモ

Androidアプリを開発していて気づいたメモ

パッケージ名はリファクタしてもマニフェストファイルは手動で書き直す必要がある。
さらにプログラム内でパッケージ名を使っているとそれもリファクタしないといけないので注意

違うパッケージ名で同名のソフトがインストールされるとややこしいので一回アンインストールしたほうが
いいかもしれない。

Charseqens?とかいうクラスがあるがこれとStringってどう違うんだろうか?
とりあえず、apiではCharseqens?って書いてあるメソッドに対して引数をStringに変えてみたところうまく
いった。CharseqensはStringを継承してるってこと???
よく分からん…
内容は違うは上の問題と同時に起こった問題はStringからなる配列を可変にしたい、つまりaddメソッド的なものをこの配列に対して使いたかったのだが、Pythonのリストのように何も考えずに適当にaddっというわけにはいかない。
どうやらこういうときはArrayListとかVectorを使えばいいらしい。

例をあげるならString[]を可変に扱うためには

Vector v = new Vector();
v.add("foo");
v.add("bar");

String[] result = new String[v.size()];
v.toArray(result);

というふうにしてやると
resultの中に欲しいStringの配列ができる。
これで2,3時間くらいはまった…

Paging Navigation

Navigations, etc.