-コンテンツへスキップこのwebサイトの先進的な機能は、ブラウザーのJavaScriptを有効にする必要があります。コメントを残す古いAndroid端末を活用するのに、Arduinoなどのマイコンボードと通信出来ればぐっと利用価値が高まります。UARTが使えれば一番簡単だと思いますが、そんなものが無改造でつながる機種はレアでしょう。通信インタフェースとして使えそうでなものはUSB,Wifi,Bluetoothです。この中でBluetoothのSPプロファイルではRFCOMMというシリアル通信用プロトコルが利用できます。これを使えば、接続さえしてしまえばUARTと同じ感覚で使えます。都合の良いことにマイコンと接続出来るBluetoothモジュール(技適つき)は比較的に安価で販売されていて、ArduinoにはBluetoothモジュールを使ったサンプルプログラムもあります。ベストマッチと言いたいですが、Android1.6では通常はRFCOMMが使えない機種が多く、さらに独自実装であったりして一筋縄ではいきません(まさにIS01がこれです)。ここではAndroid1.6端末でRFCOMMを使う方法について記載したいと思います。今回の記事で使用した環境は以下の通りです。minicomなお、記事で使用したテストプログラムは以下リポジトリにアップロードしてあります。参考になればと思います。is01_bluetoothspp_samplehttps://gitlab.com/kirib/is01_bluetoothspp_sample/tree/masterRFCOMMサーバを準備する今回、Android端末とRFCOMM通信するためにPC上にテスト環境を用意しました。Android側をRFCOMMクライアントとして使うので、PC側はサーバとして接続を待ち受けることになります。サーバ環境はVirtualBoxの仮想環境にLinux(Ubuntu)をインストールして構築しました。Linux環境ではBluetoothの通信内容を簡単にキャプチャー出来るのでデバッグに重宝しました。下記の記事を参考にして頂ければと思います。android.bluetoothにアクセスできないため、通常は自作アプリケーションからBluetoothを操作することが出来ません。内部的にはBluetooth関連の機能が存在しているので、これにアクセスするためのライブラリがインターネット上に公開されています。このライブラリを使うことでアプリケーションからBluetoothをいじれるようになります(ライブラリ内部では非公開のAPIを呼び出すことで機能を実現しているようです)。私が探した限りでは、ライブラリは以下の2種類がありました。backport-android-bluetoothはAndroid公式APIと同じように使うことが出来るのでおすすめです。IS01はBluetoothの実装が他とは違うようでちょっとした改造が必要でした。IS01固有のものです。お使いの機種の実装次第なので断言は出来ませんが、IS01以外はこの項をすっ飛ばして素直にbackport-android-bluetoothライブラリを使えば動作するかと思います。RFCOMMを使うと落ちる意気揚々とライブラリを組み込んで動作させてみると、どうにも動作しません。両方のライブラリを試したのですが結果は同じです。BluetoothのON/OFFやペアリングしたデバイスの一覧は問題なく取得出来ているのですが、肝心のRFCOMMで接続しようとすると例外が発生して動作しません。エラーログを見ると、どうもRfcommSocket.initNativeが無いと言っているように見えます。雲行きが怪しくなってきました。moreIS01のBluetooth実装を調べるよそ様のブログを拝見していると、どうやらIS01にはライブラリが内部で使用しているRfcommSocketが実装されていないようです。シンボルテーブルを見ると別なクラスとして実装されている可能性があるようです。libandroid_runtime.soのシンボルテーブルを見てみると、たしかにBluetoothSocketなるシンボルがあります。2.0以降に実装されたクラスで、公式のAndroid1.6には存在しないクラスです。Master1"に似たような実装があるとの情報がありましたが、残念ながらOESFのリポジトリは非公開になっていました。会員のみに公開されている模様。会費は個人からすると高額でなんともなりません。仮にBluetoothの実装がどうなっているにせよ、IS01に初めから入っているアプリケーションがBluetoothを利用しているからにはどこかに実装があるはずです。IS01から以下のディレクトリをコピーして調べてみることにしました。frameworkはbaksmali/smaliやdex2jarを使ってdecompileです。/system/lib/system/frameworkすると、frameworkにandroid.bluetoothパッケージが含まれていることが分かりました。クラス構成を眺めていると、どうやらAndroid2.xに近いものがあります。リファレンスの公式APIとはメソッドが異なります。期待出来そうなクラスが見つかりました。BluetoothSocketRfcommSocketこのうち、RfcommSocketはframeworkにクラスこそあるものの肝心の処理が実装されていません。BluetoothSocketはライブラリにシンボルがあったので期待出来そうです。いえば、IS01が発売されるより前にAndroid2.xがリリースされていたはずです。憶測ですが、いくつかの機能をAndroid2.xから持ってきたのかもしれません。参考までに、Android1.6と2.0のコードは以下サイトで見ることができます。bluetoothhttps://android.googlesource.com/platform/frameworks/base.git/+/android-2.0_r1/core/java/android/bluetooth/テストプログラムで試行錯誤する公式リファレンス通りの実装ではないものの類推(あてずっぽうとも言う)出来そうな感じだったので、テストプログラムを作って動きを見てみることにしました。Deviceリストの取得処理などはライブラリで動作していたので、ライブラリが使える部分はそのまま使うことにしてRFCOMM処理の部分だけを作ります。この部分はIS01独自実装で非公開なのでそのままではbuild出来ません。非公開のAPIを利用する方法として以下の手段があります。Javaのreflectionを使用するビルド時にだけ参照するライブラリファイル(jar)を作る今回はjarファイルを作って対処しました。SDKにあるライブラリファイル(SDK/platforms/android-22/android.jar)のandroid.bluetoothパッケージをIS01から取り出したものとそっくり入れ替えます。これでbuildは通るようになります。5.1(API-22)をベースにしました。2.xで古い端末向けにbuildする際にいつも使用しているためです。Donuts(API-4)向けアプリをビルドする方法これが正しいやり方なのか自信はありませんが、この内容でLinux環境に構築したRFCOMMサーバと通信することが出来ました(短時間のテストなので安定しているかは不明です)。Frameworkのものを使用パッケージが混じっていて読みづらくて申し訳ありませんが、backport.android.bluetoothパッケージが非公式のbackport-android-bluetoothライブラリのものです。RFCOMMを使うためにBluetoothSocketクラスのみIS01本体のライブラリを参照しています。null;[/JAVA]ペアリングしたデバイス一覧の取得処理この部分はオリジナルのbackport-android-bluetoothライブラリを使った処理です。String[0]);}[/JAVA]RFCOMM接続処理IS01でRFCOMMを使うのに試行錯誤した部分です。BluetoothSocketクラスはbackportライブラリではなく、IS01のandroid.bluetoothパッケージのものを使用します。DaemonにSPPが追加されているかを確認してください。Bluetoothは接続時にSDPを使ってSPPをサポートしているかの問い合わせを行いますので、SDPにSPPが無いと接続できません。e);}}[/JAVA]メッセージの送受信処理テストなので、送信処理はお手軽にUIスレッドから実行しました。受信処理はAsyncTaskを使ってバックグラウンドで処理を行います。str){mEditTextLog.append(str);}[/JAVA]backport-android-bluetoothライブラリをIS01でも動作するよう改造するひとまずIS01でもRFCOMMが使用可能だと確認出来ました。この処理だと(恐らくは)IS01しか動きません。ただでさえAndroid1.6というガラクタ(失礼)をターゲットとしたアプリケーションを作っているのに、マニアックな一機種だけしか動かないのでは自分以外誰も使わない可能性が大です。そこで、backport-android-bluetoothライブラリに少し手を加えてIS01とほかの機種の処理を分けるようにしてみました(LazyLoadパターンというらしい)。IS01と他機種間の差異をライブラリ内で吸収しているので少しは汎用的に使えるアプリケーションが作れる、ハズです。IS01以外のAndroid1.6端末を持っていないので未確認ですが。変更した箇所は以下の通りです。addr;}}[/JAVA]この修正したライブラリを使うことで、IS01でも他機種と同様に接続が出来るようになります。}}[/JAVA]backport.bluetooth.androidライブラリを使ってテストアプリケーションを作るようやくここまで来ました(IS01ユーザ以外はそうでもない?)。簡単なテストプログラムを作成してPC環境と通信してみました。プロジェクト一式は以下にアップロードしています。Samplehttps://gitlab.com/kirib/is01_bluetoothspp_sample/tree/masterプロジェクトはIS01向けに修正したライブラリを含んでいますが、こちらは記事に書いたようにSDKに手を加えないとBuild出来ません。ライブラリ処理を修正するのでなければ、jarファイルをダウンロードしてプロジェクトに追加すればテストアプリケーションをBuild出来るかと思います。修正版backport.bluetooth.andoroidライブラリのjarファイルは以下にあります。IS01向けアプリケーションでRFCOMMを使われる方は使ってみてください。backport-bluetooth-android-for-is01.jar(IS01向け修正版)https://gitlab.com/kirib/is01_bluetoothspp_sample/tree/master/bluetooth/release以下がテストプログラムの画面です。ペアリング済みのデバイス一覧から接続先を選択して"connect"ボタンで接続されます。メッセージを送信するには画面下のテキストボックスに入力して"send"ボタンです。受信メッセージは中央に表示されます。以下はテストで使用したLinux環境のスクリーンショットです。プログラム(PC/Android)sukeについて自転車で日本一周旅行に出ようとー思い立ったエンジニア。ガジェット類やセミナーに目がない。コメントをキャンセルメールアドレスが公開されることはありません。コメントデータの処理方法の詳細はこちらをご覧ください。