2016/06/11

[android][ble]BLE接続する (2)

前回はBLE接続しただけで終わった。

しかし、あっさり「BLE接続」と書いているが、どこまでシーケンスが進んだら「成功」と見なしているのだろうか?
それに、このconnect()は同期で結果が返ってきているのだけど、だいたいこういうのは非同期でやるものではなかろうか?

疑問が尽きないので、connect()が何をしているのか見てみよう。


BleAdapterService.java#L212

やっているのは、これ。

  1. BLEアドレスからBluetoothDeviceを取得(メンバ変数…じゃなくてフィールド)
  2. BluetoothDevice#connectGatt()

引数にcallbackとか着いているから、これは接続要求を出しただけだろう。
それならば、納得だ。

 

コールバックになっているmGattCallbackが、大きい。
L71~L170まである。
中で持っているのは、これら。

  • onConnectionStateChange()
  • onServiceDiscovered()
  • onCharacteristicRead()
  • onCharacteristicWrite()
  • onCharacteristicChanged()
  • onDescriptorWrite()
  • onReadRemoteRssi()

なんとなく名前でわかるようにしてあるところが偉いな。

Changedは状態変化通知、特にonCharacteristicChanged()はNotification/Indicationだろう。
Read, Writeは要求した結果が返ってくるだろう。Write Without ResponseでもonCharacteristicWrite()は呼ばれたと思う。

 

というわけで、connectGatt()したらonConnectionStateChange()が呼ばれるはず。
L80でサービスを見に行くようにしてあるのだろう。
そしたら、onServicesDiscovered()が呼ばれるはずだ。

さて、ではこれがどうやってActivityと会話しているかというと、たぶんMessage.obtain()というやつだろう。
前回、よくわからないままコピーしたものがいくつかあるのだが、ActivityにHandlerを追加しているのだ。

Handlerは、スレッド間通信のしくみらしい。
Handlerをnewした方がサーバになって、メッセージをobtain()したときだけhandleMessage()が実行される、ということだろうか。

ちょっと話が脱線するが、Androidアプリは同一プロセスで動いているんじゃなかったっけ?
スレッド間通信といっても、同じプロセス内だったら関数コールでもなんでもいいんじゃなかろうか。。。
mutexとか、そういうのをJavaがうまいこと隠蔽しているのかも。

ともかく、ログを入れて試したところでは認識通りのようだ。
connect()を呼ぶと、handleMessage()のGATT_SERVICES_DISCOVEREDまで呼ばれて終わった。

 

元のBDSサンプルでは、数字を打ち込むTextViewとWriteやReadのButtonが並んでいる画面が表示される。
接続するまでは非アクティブで、接続するとアクティブになる。
そういった処理をこのhandleMessage()でやるのだな。

わかった気がする。

 

では、次回はCharacteristicのアクセスについて見ていこう。
BDSサンプルだと、UUIDをxml側に書いているから、そこをどうするか考えないとねぇ。


コールバックされる内容と、Activityへの通知方法がわかったので、なんとなくだが理解の半分くらいまで届いたんじゃなかろうか、という気がしている。

この「気がしている」という感覚が大切で、わからんわからんと思っているだけだと、けっこうつらいのよね。。。
長いことこういうお仕事してるけど、いつかは「わかった!」という瞬間が来るはず、という自信が支えているところはあるねぇ(偽りの自信かもしれんが)。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。