2013年2月13日水曜日

[Android]Bluetoothマウスに自動接続ってどうやるの

AndroidでBluetoothの自動接続ってできるとかできないとか情報少ないから軽くまとめる。
ちなみにターゲットはアプリ、とくにプリインアプリでAndroid4.0.3くらい。
接続したいBluetoothの名前”hogehogeMouse”とか、PINを準備しといてね。



1.ペアリング済みかどうかみる
2.Bluetooth端末探す
ここら辺はBluetoothで通信を行う(1)参照。

本題は、Bluetooth端末見つかったら、特定の端末を自動接続したいっていう話
3.ペアリングする
2で探してたBluetoothDeviceをみつけたら、
BluetoothDevice::createBondを呼ぶ。
これ非公開なんでこんな感じに。
 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
 BluetoothDevice device = adapter.getRemoteDevice(bluetoothAddress);
 Method createBondMethod = BluetoothDevice.class.getMethod("createBond", new Class[]{});
 Boolean result = (Boolean)createBondMethod.invoke(device);

これでうまくいくと"android.bluetooth.device.action.PAIRING_REQUEST"がBroadcastされる。
PAIRING_REQUESTがきたらPINを入力する。
これも非公開
 Method convertPinToBytesMethod;
 convertPinToBytesMethod = BluetoothDevice.class.getMethod("convertPinToBytes", new Class[]{ String.class });
 byte[] pinCodes = (byte[])convertPinToBytesMethod.invoke(BluetoothDevice.class, PINCODE);
 Method setPinMethod = device.getClass().getMethod("setPin", new Class[]{ byte[].class });
 Boolean result = (Boolean)setPinMethod.invoke(device, pinCodes);


手元の環境だと、PAIRING_REQUESTは設定アプリでもみてて、例のPIN入力ダイアログが表示されるんだよね。
だけど、こちらから強制的にPIN入力すると諸事情でダイアログが消えるんだよね。
諸事情はcom.android.settings.bluetooth.BluetoothPairingRequest見るといいよ。
あと、ものによってはダイアログ表示しない奴もいるから、その場合はPAIRING_REQUESTが来る前にPIN入力してもいいのかも。実機動作見てくだしぃ。→20130225追記

4.接続
Bluetooth Health Deviceと通信するを理解しとく。
そのうえでcom.android.settings.bluetooth.HidProfileから処理を抜き出す

private void connectInputDevice(){
 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
 adapter.getProfileProxy(getBaseContext(),new InputDeviceServiceListener(), BluetoothProfile.INPUT_DEVICE);
}

private final class InputDeviceServiceListener
implements BluetoothProfile.ServiceListener {

 public void onServiceConnected(int profile, BluetoothProfile proxy) {
  mService =  (BluetoothInputDevice) proxy;
  Boolean result = mService.connect(mDevice);
 }

 public void onServiceDisconnected(int profile) {
  mService = null;
 }
}

Eclipceだとすごい怒られるから、てもとのAndroidビルド環境でビルドして確認したよ。
だからプリインターゲットかなって。

みんな頑張って

-----------
20130215追記
3.ペアリングするのPAIRING_REQUESTきたらPIN入力のところ、
Activityでこれを実装すると成功するんだけど、
Serviceで実装すると失敗した・・・。
ServiceでPAIRING_REQUESTきてから3秒後にPIN入力したら成功したからタイミング問題な気がするけど、
Broadcastされるタイミング的にSettingが先じゃないとだめとかなのかな。
まだまだ謎い…


-----------
20130225追記
ふつうに設定メニューのBluetooth接続でPIN入力ダイアログが出ない端末の場合、
setPin()しなくてもcreateBond()→connect()でつながるみたい。
根拠のない経験則なんで、誰かえろい人が調べてくれる、きっと。

0 件のコメント:

コメントを投稿