こんにちは。ECF Tech ブログ担当のmichiです。

今回から何回かに分けて、BLE(Bluetooth Low Energy)を使ってAndroidアプリとマイクロビットが通信をするまでを書いていきたいと思います。マイクロビットとAndroidアプリをBLEで接続することでこんなことができます。

BLE(Bluetooth Low Energy)とは

BLEは名前のとおり、省エネルギーでデバイス同士の通信を可能にするために策定された、IoTを意識した通信規格です。本記事ではBLEについて、Androidアプリとの動作上で最低限必要な部分の説明に留めたいと思います。詳しくご覧になりたい方は、こちらのサイトが参考になります。ご覧ください。

というわけで、本記事では次のような読者を想定しております。

  • AndroidアプリでBLEを使用するためのサンプルプログラムが見たい
  • マイクロビットとAndroidアプリをつなげるための方法を知りたい

Androidの実装方法はこちらの公式サイト(英語)を参考にしておりますが、同記事はAndroid4.3以降をベースに記載されたものとなっているため、やや実装方法が異なっています。

BLEの概要

でははじめに、通信のための簡単な流れを見ていきましょう。BLEでは通信に用いられる2台の端末をペリフェラル(peripheral)とセントラルと言います。ペリフェラルは周辺機器の意味です。セントラルは主にスマートフォンなどのペリフェラルから情報を受け取って処理をする機器を指します。

またこの2つはクライアントとサーバのような関係にあります。

例えば心拍数を計測するウォッチを腕につけ、そこからBLE通信により送られてくる情報をスマートフォンのアプリで表示するしくみを例に挙げると、ウォッチが一定時間ごとに心拍数の数値を送信するサービスを提供するサーバとしての役割を果たし、スマートフォン側はその情報を受け取ってアプリケーションで利用するクライアントの役割となります。

本記事で紹介する接続例でも、マイクロビットがサーバの役割を果たし、スマートフォンがクライアントの役割を果たします。接続までの流れは概ね次のようになります。

では、1つ1つを順に見ていきましょう。まずはマイクロビット側が行なうアドバタイジング(Advertising:宣伝する)です。アドバタイジングは周辺機器がその存在を知らせるために行なう通信です。マイクロビットの場合、あらかじめ下記のようにプログラムを準備しておきます。

一方のアプリ側ではスキャニング(scanning)を行ないます。Androidアプリにおいてこのスキャニングを行なうまでの手順は次のようになります。

スキャニングまでのプログラム

まずはじめに、Android ManifestによるPermissionの設定です。最低限下記3つのPermission設定がなされていなければいけません。

Bluetoothに関連するPermissionと位置情報に関するPermissionです。位置情報に関するPermissionはAndroid 5.0(API Level 21)より塔載されたBluetoothLeScannerクラスを利用する場合は必須です。今回は本クラスを用いた構築となるため追加しています。もちろんこちらは、ACCESS_FINE_LOCATIONのPermissionを用いても構いません。

今回はMainActivityなクラスにすべて実装したコードで見ていきたいと思います。

onCreateメソッドで行っている処理から説明します。

まず最初にAndroid端末自体がBLE対応端末かどうかを調べています。対応端末でない場合は、適切なメッセージを出して、アプリを終了しています。

次にBluetoothAdapterを取得します。BLE接続を行なう際はBluetoothManagerを取得し、そこからアダプターを取り出す流れとなります。

次に該当端末が、Bluetooth接続を許可しているかを確認します。許可していない場合は、設定画面へ移動。許可している場合はボタンのテキストを「CONNECT」にして示しています。

ボタンを押した時の処理は以下です。

BluetoothAdapterから、BLE用のスキャナ(BluetoothLeScanner)インスタンスを取得します。

その次の行は、スキャン成功(BLE端末が見つかった)際にコールされるコールバックメソッドを実装したクラスのインスタンスを生成します。同クラスのソースは後ほど。

下記でスキャンを開始します。Handlerを使って別スレッドにてスキャニングを停止するメソッドを10秒後(SCAN_PERIODに定義済み)にコールしています。startScanメソッドでスキャンを開始するとstopScanメソッドでスキャンを停止しなければいけないためです。

スキャンが成功した時にコールされるコールバックメソッドを実装したクラスが下記です。

とりあえず動作する実装を目指したので、成功時にバックするonScanResultメソッドだけを実装しています m( _ _ )m。

最初のいくつかのifはBLE端末が取得出来ているかをチェックしています。マイクロビットは識別名として「BBC micro:bit」を含んだ文字列を返すので、これによりマイクロビット端末であることを判断しています。

その後はデバイス情報をフィールド deviceに保持して、メインスレッドでボタンのテキスト文字列を変化させています。最後にスキャン作業をストップさせて終了です。

BLE端末(マイクロビット)の情報が取得出来たら、次にその端末が提供してくれるサービスの情報を取得します。コード中に登場する「GATT(General ATTribute Profile)」はBLE端末とのデータ送受信に用いられるプロトコルです。GATTサービスなどと呼ばれます。今回は、再度画面上のボタンを押した際に発動するようにしました。ボタンを押した際の処理は以下です。

MyGattCallbackは、BLE端末からサービスが取得出来た際にコールされるコールバックメソッドの実装クラスです。次行の connectGattメソッドでGATTサービスへのアクセスを開始します。

無事接続が行われると、BluetoothGattCallbackインタフェースを実装した次のメソッドがコールされます。

メソッド内でステータスが接続状態(BluetoothProfile.STATE_CONNECTED)になったら、使用可能なサービスを取得します。

ここまでがAndroidとBLE端末を接続する際の基本の流れになります。ここ以降はマイクロビット端末固有の処理になっていきますので、一旦ここまでとさせて頂きます。m( _ _ )m

全体のソースコードの閲覧を希望の際は、こちらでご確認ください。