やりかた
- BluetoothAdapter.getDefaultAdapter()を使って、アダプタを得る。
- アダプタにisEnabled()を呼び出して、Bluetooth設定が有効なことを確認する。
- インテントを出してユーザーに有効にしてもらうことも可能だけど、ここではしない。
- アダプタにgetBondedDevices()を呼び出して、ペアリングされたデバイスの一覧を得る。
- 探索してペアリングされたデバイス以外から探すことも可能だけど、ここではしない。
- デバイスのプロパティを見て、欲しいデバイスを探し出す。
- 本当はUI出して選んでもらうのがいいと思うけど、ここではしない。
- 欲しいデバイスにcreateRfcommSocketToServiceRecord()を呼び、必要なサービスのBluetoothSocketを得る。
- SPP (Serial Port Profile)のUUID(00001101-0000-1000-8000-00805F9B34FB)を渡す必要があるので、定数定義しておく。
- BluetoothSocketにconnect()を呼ぶ。
- BluetoothSocketにgetInputStream() / getOutputStream()を呼んで、適当に操作する。
- BluetoothSocketにclose()を呼ぶ。
このへんのページのほうが詳しいので、「ここではしない」ことがしたければこちらを参考に...
- ソフトウェア技術ドキュメントを勝手に翻訳 - Android 開発ガイド > フレームワークトピック > h. Bluetooth
- Androidアプリ開発 ~Bluetooth SPP による無線通信~
罠
罠1) getDefaultAdapter()は、Gingerbread (2.3)では、UIスレッドでしか呼べない。
いかにもUIなんか関係なさげなメソッドなのに、Handlerが取れなくて例外が出る。4.1では起きないらしいけど、2.3じゃダメだと…ねぇ?
cf: https://groups.google.com/forum/#!msg/android-developers/wFbD5V2DWRc/gv0VF4Y6ICwJ
罠2) BluetoothSocket#connect()は「Service discovery failed」でたまに失敗する
Webを見るとよくある話のようで、ウエイトを入れたり、アダプタにcancelDiscoveryをさせろとか、リフレクションで中のメソッドを呼び出せとか、いろいろある。どうにもすっきりしないし、時間がかかってNGなので、何かのタイムアウトなんだと思う。なので、とりあえずリトライすることにした(リトライの条件はもう少ししっかりしたほうがいいかも)cf: http://stackoverflow.com/questions/3397071/service-discovery-failed-exception-using-bluetooth-on-android
コード
ASCIIで1行書き込むと、1行返ってくる感じのサンプル。本当はすべてUIじゃないスレッドの中でのコードにしたかったのだけど、上述の罠があって、getDefaultAdapter()だけUIスレッドで渡すようにしているので、コピペでは現実的に動かない。
close()漏れとかあるので、ためしに書いてみるてな感じの参考程度に。sendLogMessage()は、適当なTextViewにログを出すためのメソッドなので、Log.dとかでよいです。