2000年3月16日星期四

Java查找Bluetooth设备

高木先生の書いた「Bluetoothで山手線の乗降パターンを追跡してみた」というエントリが、非常に興味深かったので、試しにJavaでBluetoothデバイスを探索するサンプルプログラムを作ってみました。

JavaでBluetooth関連をいじるには、JSR 82: Java APIs for Bluetoothという仕様があるので、それを参考にしました。

JSR 82自体はJavaでBluetoothをいじる仕様だけを定義していますので、実際のJSR 82の実装としてBlueCoveを使っています。

JSR 82: Java APIs for Bluetoothのサイトにあるのはドキュメント(Bluetooth関連の仕様書とAPIのJavadoc)になりますので、サンプルプログラムを動かしたいだけなら、BlueCoveのサイトからbluecove-2.1.0.jarをダウンロードしてクラスパスを通すだけでOKです。

実際のプログラムは次のような感じです。

BtSearch


import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;

/**
 * Bluetoothデバイス探索サンプルプログラム
 */
public class BtSearch implements DiscoveryListener {
    /**
     * DiscoveryAgent
     */
    private DiscoveryAgent agent;

    /**
     * 初期化
     */
    public BtSearch() throws BluetoothStateException {
        LocalDevice local = LocalDevice.getLocalDevice();
        agent = local.getDiscoveryAgent();
    }

    /**
     * Bluetoothデバイス検索メソッド
     */
    public void searchDevice() {
        try {
            agent.startInquiry(DiscoveryAgent.GIAC, this);

            synchronized (this) {
                try {
                    this.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (BluetoothStateException e) {
            e.printStackTrace();
        }
    }

    /**
     * Bluetoothデバイス検出メソッド
     */
    public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
        //デバイス情報の出力
        if(btDevice != null) {
            try {
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                System.out.println(df.format(new Date()) + " " +
                                                btDevice.getBluetoothAddress() + " " +
                                                btDevice.getFriendlyName(true));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * デバイス検索終了
     */
    public void inquiryCompleted(int discType) {
        synchronized (this) {
            try {
                this.notifyAll();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {

    }

    public void serviceSearchCompleted(int transID, int respCode) {

    }

    /**
     * BtSearchメイン
     */
    public static void main(String[] args) {
        try {
            BtSearch client = new BtSearch();
            client.searchDevice();
        } catch (BluetoothStateException e) {
            e.printStackTrace();
        }
    }
}


このプログラムを実行すると、近くにあるBluetoothデバイスを探索し、結果を出力してくれます。試しに、テスト用に借りてきたP906iを探索可能状態にして実行すると、

BlueCove version 2.1.0 on winsock
2009-03-08 00:06:17 001987xxxxxx P906i
BlueCove stack shutdown completed

というような感じで出力されます。なお、上記の例ではBluetoothアドレスの下位24bitは伏せていますが、実際に実行した際にはきちんと表示されます。

例によって例のごとく、かなーり適当なサンプルプログラムですので、参考程度にしてみてください。

ところで、通常Bluetoothデバイスを検出するには、検出される側のBluetoothデバイスが、探索可能状態になっていないといけません。例えば、上記のP906iの例では、

メニュー > LifeKit > Bluetooth > ダイアルアップ登録待機

という設定をやって探索可能状態にしないと検出できないのです。

高木先生の記事を読む限りでは、結構な数の携帯電話が常時探索可能状態になっているということみたいですが、なぜなんでしょうか?Bluetoothの使い方的には、ペアリングの時だけ探索可能状態にするっていうのが昔は一般的だったと思ったのですが、いつの間にか常時探索可能状態という設定が一般的になってきてるのでしょうか。

多分、利便性を追求した結果なのかなとは思いますが、メーカー、キャリア側としては、高木先生が指摘するような個人のトラッキングに使う気満々なのかも。なんて、うがった見方をしてしまいそうです。

どのメーカ、キャリアのどの機種がデフォルトで常時探索可能状態になっているかは、いろいろと調べて見ると面白いかもしれないですね。

没有评论:

发表评论