2016/11/26 作成
AndroidのBLEは、単に一回動けば良いだけであればGoogleのサンプル通りでOKなんだけど、scanしながらconnectしながらread/writeしながらetc.とやると何故か突然動かなくなる。自分のプログラムの作り方が悪いのかもしれないけれど、非同期のくせに「1回には処理は1回にしろ(終わるまで待て)」とか「Mainスレッドで動くようにしろ」とか「連続して処理させるな」とか、トラブってググってから初めて分かるドキュメントに書かれていないノウハウが多すぎてなかなか大変。
で、色々探していたらそういう苦労をしないで良さそうなライブラリがあったので試してみる。
最初動かすのに少しだけ調べないといけなかったので、まとめておきます。
RxAndroidBle
https://www.polidea.com/blog/RxAndroidBLE_the_most_Simple_way_to_code_Bluetooth_Low_Energy_devices/
他にも幾つかあるけど、とりあえずアクセス数が多そうなRxAndroidBleを選んだ。
github
https://github.com/Polidea/RxAndroidBle
ここからまとめてライブラリも全部ダウンロードすると、sampleもそのまま動く。
この中でプログラムを作る分には多分困らないと思う。
でも、新しいプログラムを一から作ってみようと、README.md を見て作ると動かない。
どうも、色々予備知識があるのを前提に書かれているみたい。
##やったこと
- 新しいプロジェクトを作った。
Gradleに
compile "com.polidea.rxandroidble:rxandroidble:1.1.0"
を追加しろと書いてある。gradleは2つあるのど、とりあえず Module の方に入れた。
- clientを作る
RxBleClient rxBleClient;
rxBleClient = RxBleClient.create(this);
RxBleClient.setLogLevel(RxBleLog.DEBUG);
DEBUGの行はsampleから持ってきた。こうやると、どういうログが取れるのか未確認。
- SCANする
Subscription scanSubscription = rxBleClient.scanBleDevices()
.subscribe(
rxBleScanResult -> {
// Process scan result here.
Log.d("debug","scan");
},
throwable -> {
// Handle an error here.
Log.d("debug","error");
}
);
// When done, just unsubscribe.
//scanSubscription.unsubscribe();
// この行はコメントアウトしないと動かない。
最後の行は、README.mdからそのまま持ってきたけど、コメントアウトしないと動かない。
「処理が終わったら unsubscribe() を呼んでね。」というつもりなんだろうけど、、、。
で、これはラムダ式なので、Java1.8以降でないと使えない。
ラムダ式は、retrolambdaでないといけない。(** これ重要 **)
(もしかしたら、retrolambdaが使えればJava1.7以前でもいけるかもしれない。)
とりあえず以下のように、gradleを修正する。
(必要なのは、java8、retrolambda、mavenCentral、mavenLocal のところ)
apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'me.tatarka:gradle-retrolambda:3.3.1'
}
}
repositories {
mavenLocal()
}
android {
compileSdkVersion 24
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "com.ogilab.rxandroidbletest0"
minSdkVersion 22
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
compile "com.polidea.rxandroidble:rxandroidble:1.1.0"
}
AndroidManifest.xmlに以下を追加
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
これで一応 scan が表示されるようになった。
いろいろ初期設定をしているみたいなので、しばらく待たないと表示が開始されません。(*** ここでハマった、、、 ***)
この後、RxJavaの勉強もしないといけないので、本当に動くかどうかはこれからのお楽しみ。
peripheralの記述が見つからないのが不安といえば不安。Androidでも、peripheralはまあ安定しているけれど、同時に動かさないといけないので、両立するかどうかをこれから確認しないといけない。