本ライブラリは、Android端末上のユーザアプリケーションが収集したデータを SINETStream 経由で中継サーバ (ブローカ) に送信したり、 そこから受信したデータをユーザ アプリケーションに渡すといった機能を提供するものである。
Java版やPython版とは異なり、Android版のSINETStreamライブラリは 足回りのメッセージングシステムとして(現状では) Paho MQTT Android のみを利用する。
本ライブラリの設定方法として、以下の2通りを用意する。
2)設定サーバ(コンフィグサーバ)から設定内容を動的にダウンロードする
#----------------------------------+
| User Application |
+----------------------------------+
| A
==============|========|================ SINETStream API
methods | | callbacks
V |
+----------------------------------+
|/// SINETStream for Android ///| <--------+
+----------------------------------+ |
+-------------------+ A |
| Paho MQTT Android | | |
+-------------------+ | [SSL/TLS] | [config file]
| A | |
==============|========|==========|=============|======= Android System
V | | |
+--------------+ +----------+ +----------+
| Network | | KeyChain | | File I/O |
+--------------+ +----------+ +----------+
| A
==============|========|================================ Hardware
V |
[ MQTT Message ]
本方式による設定の場合、アプリケーション固有のデータ領域にYAML形式の 設定ファイル
(/data/data/__PACKAGE__/files/sinetstream_config.yml)
を事前に用意しておく。ファイル名は固定である。 本ライブラリ初期化時に上記設定ファイルが読み込まれ、動作内容が決定される。 書式など詳細は Android版のSINETStream設定ファイル を参照されたい。
なお、対向MQTTブローカとの接続にSSL/TLSを用いる設定の場合、後述の Androidシステム認証ストレージの利用 を参照のうえで、関連の証明書類も事前に手動で導入しておくこと。
#----------------------------------+ +-----------------+
| User Application | | Web Browser |
+----------------------------------+ +-----------------+
| A A
==============|========|================ API | [HTTPS]
methods | | callbacks |
V | V
+----------------------------------+ +-----------------+
|SINETStream for Android | | Config Server |
| +---------------+ | | |
| | Config Client | <--+ | [Database] |
| +---------------+ | | | A |
+-------------------------A--------+ | +-----------|-----+
+-------------------+ | | |
| Paho MQTT Android | | [HTTPS] | [AccessToken] |
+-------------------+ | | |
A | | |
==============|=============|===========|== Android |
V V | |
+-----------------------+ +----------+ |
| Network | | File I/O | |
+-----------------------+ +----------+ |
A A |
==============|=============|=========== Hardware |
| | |
V | |
[ MQTT Message ] +-----------[ HTTPS ]-----------+
本方式による設定の場合、SINETStream設定サーバ(
コンフィグサーバ
と呼称)と連携して運用する。
まずコンフィグサーバへの接続情報およびユーザ認証のためアクセストークン
が当該サーバから払い出される。これをAndroid端末のウェブブラウザChrome
などで事前にダウンロードしておく。失効した場合は新しいもので置き換える。
本ライブラリ初期化時にアクセストークン
と共にコンフィグサーバに接続する。
システム管理者によりコンフィグサーバ側で所用の情報が設定されているはずなので
必要なものを選択してダウンロードする。このときSSL/TLS証明書など秘匿情報が
あればこれらも併せて自動的に取得される。
本方式による設定では、各Android端末の動作内容はコンフィグサーバから動的に ダウンロードした設定情報で規定される。 すなわち、複数のAndroid端末で同一の設定内容を使用したり、特定用途の設定を 個別に用意したりと柔軟な運用が可能である。またシステムで用いるAndroid端末 群に関してコンフィグサーバ側で一元管理を図れることを意味する。
各Android端末上で管理すべき情報はアクセストークン
のみである。
コンフィグサーバから動的に取得した設定情報をメモリ上でのみ扱うようにする
ことで、情報セキュリティを強化できることにも注意されたい。
本章は手元で用意した設定ファイルを読み込ませる方式で適用される。 コンフィグサーバを利用する場合は所用のSSl/TLS証明書が自動的に ダウンロードされるため、本章は読み飛ばして構わない。
対向ブローカとのSSL/TLS接続時に クライアント証明書 や 自己署名サーバ証明書 (いわゆるオレオレサーバ証明書)が求められる運用があり得る。
本ライブラリ実装では、Androidキーストア[1]と呼ばれるシステム秘匿領域に 目的のブローカとのSSL/TLS接続に必要な証明書を事前に手動で導入しておき、 ユーザアプリケーション実行時にこれらを参照する方式とする。 SSL/TLS証明書が失効した場合は、再発行されたものと入れ替える必要がある。
対向ブローカとの通信路を秘匿するためにSSL/TLSを使うとして、データ
そのものを暗号化したい利用要件があり得る。
SINETStream設定ファイルの記述により、Writer
側での暗号化、および
Reader
側での復号処理を有効化できるようにした。
利用要件に合わせ、以下の各項目を適切に設定すること。
- 暗号化処理の利用
- アルゴリズム
- 鍵長
- モード
- パディング
- パスワード
- 鍵導出関数の利用
- アルゴリズム
- ソルト
- 繰り返し数
ユーザアプリケーション開発者は、自身のビルド制御ファイル 「$(TOP)/app/build.gradle」 に以下の内容を追記すること。
//
// We use the Eclipse Paho Android Service
// https://github.com/eclipse/paho.mqtt.android#gradle
//
repositories {
maven { url "https://niidp.pages.vcp-handson.org/sinetstream-android/" }
maven { url "https://repo.eclipse.org/content/repositories/paho-snapshots/" }
}
dependencies {
implementation 'jp.ad.sinet.stream.android:sinetstream-android:x.y.z' // 最新版を指定する
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
}
Android動作環境の制約(API 26未満では動かない)
「SINETStream for Android」は、メッセージのシリアライザ/デシリアライザ機能で 「Apache Avro」ライブラリを利用している。 このAvroの実装内容[2]が制約条件となり、本ライブラリ自身のみならず本ライブラリ を用いるユーザアプリケーションはすべて 「API 26 (Android 8.0)」以降でないと以下のようなビルドエラー[3]となる。
MethodHandle.invoke and MethodHandle.invokeExact are only supported starting with Android O (--min-api 26)
よって、プロジェクト全体のまたはモジュールごとのbuild.gradle
の該当箇所で
動作可能なAndroid OSの下限を明記すること。
android {
defaultConfig {
targetSdk: XX // 現時点の最新
minSdk: 26 // 動作可能なAndroid OS(APIレベル)の下限
// ...
}
}
[2]: Avro 1.9.2 Java library does not work on Android
[3]: build.gradleの「minSdkVersion」が26より小さい場合のビルドエラー
Android版のSINETStreamが利用する「Paho MQTT Android」では、 ユーザインタフェースを扱う MqttAndroidClient 、およびバックグラウンドで通信を担う MqttService から構成される。
概要欄で示したようなモジュール階層間の依存関係の連鎖を解決するため、 Android版のSINETStreamライブラリを用いるユーザアプリケーションは マニフェストファイルに MqttService の使用を宣言する必要がある。
この宣言を忘れると、対向ブローカと通信できない。
<manifest>
<application>
<!-- Paho MQTT Android 内部で利用するMQTTサービス -->
<service android:name="org.eclipse.paho.android.service.MqttService" />
</application>
</manifest>
また、インターネットアクセスに必要となる権限も併せて記述する。
<manifest>
<!-- インターネットアクセス用 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
注意
Androidの認証ストレージを利用するための実行時権限USE_CREDENTIALS
は Android 6 (APIレベル23)で削除されたため、本ライブラリ使用に関しては指定不要。 詳細は API23実行時権限差分 を参照のこと。
概要欄で述べたように、 アプリケーション固有のデータ領域にSINETStreamの設定ファイルを配置する。 その記述例を以下に示す。
service-1:
type: mqtt
brokers: mqtt.vcp-handson.org
tls: true
transport: websocket
username_pw_set:
username: mqtt
password: TlQr6657bEWP1zGp
topic: test-sinetstream-android-20191021
consistency: AT_LEAST_ONCE
retain: true
client_id: client-sinetstream-android-20191021-1
connect:
keepalive: 30
automatic_reconnect: true
冒頭に記述したとおり、本ライブラリではMQTTメッセージングシステムの足回りとして
Paho MQTT Android
を採用している。
Android 12におけるシステムAPIの挙動変更
ペンディングインテントの可変性
(PendingIntent
コンストラクタに渡す引数flags
に設定すべき値が追加された)により、
既存のPaho MQTT Android
実装だとブローカ接続直後に例外が発生するようになった。
本事象に対して修正パッチが何件か投稿されているが、肝心の本家のGitHubリポジトリ
eclipse/paho.mqtt.android
が数年も放置されている状態となっている。
最終的に本家GitHubで対応されるまでの時限的な繋ぎとして、Paho Mqtt Android
ライブラリを手元で修正した版(PahoMqttAndroid-Bugfix
)をリンクして使うことにする。
以下の利用権限を追加する。
<manifest>
<!-- PahoMqttAndroid (Android 12+): ブローカ死活監視用 -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
</manifest>
本家のorg.eclipse.paho.android.service
の代わりにpahomqttandroid-bugfix
を使う。
//
// We use the Eclipse Paho Android Service
// https://github.com/eclipse/paho.mqtt.android#gradle
//
repositories {
maven { url "https://niidp.pages.vcp-handson.org/sinetstream-android/" }
maven { url "https://repo.eclipse.org/content/repositories/paho-snapshots/" }
}
dependencies {
/* SINETStream-android */
implementation 'jp.ad.sinet.stream.android:sinetstream-android:x.y.z' // 最新版を指定する
/* Paho Mqtt */
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5' // 既存のものをそのまま使用
// implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1' // コメントアウト
implementation 'net.sinetstream:pahomqttandroid-bugfix:1.0.0' // PahoMqttAndroid修正版を使用
}