Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
BLE AdvertiseはRxJavaで何かが変わるのか
Search
Yoshihiro WADA
October 25, 2017
270
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
BLE AdvertiseはRxJavaで何かが変わるのか
2017/10/25 に開催された potatotips #44 にて発表した資料です。
Yoshihiro WADA
October 25, 2017
More Decks by Yoshihiro WADA
See All by Yoshihiro WADA
AndroidデバイスにFTPサーバを建立する
e10dokup
0
1.7k
Gradleの実行環境設定を見直す
e10dokup
0
1.4k
Firebase App Distributionのテストアプリ配信を試しやすくする
e10dokup
1
750
アプリに署名する 〜GitHub ActionsでのCIも見据えて〜
e10dokup
0
1.4k
Profileable buildでより正確なパフォーマンスを掴む
e10dokup
0
810
[DroidKaigi 2021] メディアアクセス古今東西 / Now and Future of Media Access
e10dokup
0
4.1k
今更「dp」を考える / Let's think about "dp" now
e10dokup
0
6k
1から学ぶAndroidアプリデバッグ - アプリの動作を追いかけよう / Learn Android application debugging from the scratch - track apps' behaviors
e10dokup
10
3.7k
Guide to background processingを読んでみる / Reading "Guide to background processing"
e10dokup
0
330
Featured
See All Featured
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
290
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
990
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
A Soul's Torment
seathinner
8
3.6k
Practical Orchestrator
shlominoach
192
12k
The Limits of Empathy - UXLibs8
cassininazir
1
670
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
470
Testing 201, or: Great Expectations
jmmastey
46
8.3k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
Transcript
BLE Advertiseは RxJavaで 何かが変わるのか Yoshihiro Wada a.k.a. @e10dokup 2017/10/25 @
potatotips #44
1 Yoshihiro Wada CyberAgent, Inc. / Adtech Studio (新卒)
@e10dokup
1 Yoshihiro Wada CyberAgent, Inc. / Adtech Studio (新卒)
@e10dokup
2 今日の話題 BLE ってご存知ですか
3 BLE とは BLE (Bluetooth Low Energy) Bluetooth 4.0 の規格の一部。
超低電力でボタン電池で最大 1 年くらい駆動可能。
4 そのなかでも BLE Advertise 未接続の BLE デバイス (ペリフェラル) が スマホ等の接続可能なデバイス
(セントラル) に対し 自身の存在を伝えるためにパケットの発信をする機能 BLE デバイス ワタシハココヨー
5 BLE Advertise BLE Advertise 時に最大 31byte のパケットを送信できる Advertising Packet
この中に規格に合わせて Service UUID 等の情報を埋めていく iBeacon や EddyStone は Advertising Packet の規格
6 BLE Advertise を Android で受け取る BluetoothLeScanner クラスを使う private val
scanner: BluetoothLeScanner private var scanCallback: ScanCallback? = null init { // Kotlinならrunとか使ってこんな風に書けそう scanner = context.run { val manager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager return@run manager.adapter.bluetoothLeScanner } }
7 BLE Advertise を Android で受け取る Scan に対してオプションが設定できる ScanFilter :
スキャン対象を Advertising Packet の中身で フィルタリングする ScanSetting : スキャン間隔や検出個数、 遅延スキャンや スキャン時の callback をどうトリガするなどを設定する startScan(ScanCallack, ScanFilter, ScanSetting) で Scan 開始 stopScan(ScanCallack) で Scan 停止
7 BLE Advertise を Android で受け取る Scan に対してオプションが設定できる ScanFilter :
スキャン対象を Advertising Packet の中身で フィルタリングする ScanSetting : スキャン間隔や検出個数、 遅延スキャンや スキャン時の callback をどうトリガするなどを設定する startScan(ScanCallack, ScanFilter, ScanSetting) で Scan 開始 stopScan(ScanCallack) で Scan 停止
8 ScanCallback onScanResult(int callbackType, ScanResult result) 一台の BLE Advertise を
Scan できた際に呼ばれる ScanFilter を設定していればそれにあったものが呼ばれる onScanFailed(int errorCode) BLE Advertise の Scan を実行できなかった際に呼ばれる すでに Scan を開始しているとか onBatchScanResults(List<ScanResult> results) 遅延 Scan を実行している際、 その遅延の間に Scan できた デバイスのリストが通知される
9 BLE Beacon デバイスで稀によくあること iBeacon の Major/Minor で Beacon の位置を定義してみたり
EddyStone で URL を伝えるようにしてみたり Advertising Packet で何かしら伝えようとしてくる 独自規格でセンサの状態をパケットに設定してきたり
9 BLE Beacon デバイスで稀によくあること iBeacon の Major/Minor で Beacon の位置を定義してみたり
EddyStone で URL を伝えるようにしてみたり Advertising Packet で何かしら伝えようとしてくる 独自規格でセンサの状態をパケットに設定してきたり いい感じに受け取りたい
10 RxJava を使ってみる filter を使って重複回避や本当に必要な分だけ取得したり map を使って Advertising Packet から欲しいデータを得たり
Scan 中は拾えた BLE デバイスがひたすら通知される Observable に扱えれば得られたデータを Web API に流したり とかできそう Observable に扱えるはず
11 実際に実装してみた 取得された Advertise から iBeacon とわかるものをフィルタ フィルタされた Advertise から
iBeacon の Major/Minor、 DeviceName だけを取り出して通知 呼び出し元に 「Scan した iBeacon のデータのみ」 を通知したい Observable.create で Scan 開始から callback までを包む Scan 停止時に disposable を破棄する
Scan 開始を Observable.create で包む // 単純にObservableを返すメソッドに変更 fun start(): Observable<ScanResult> {
return Observable.create { subscriber -> scanCallback = object: ScanCallback() { override fun onScanFailed(errorCode: Int) { subscriber.onError(Throwable(ERROR_MESSAGE)) } override fun onScanResult(callbackType: Int, result: ScanResult?) { super.onScanResult(callbackType, result) result ?: return subscriber.onNext(result) } // 他は省略 } scanner.startScan(scanCallback) } }
iBeacon とわかるものをフィルタ fun check(result: ScanResult): Boolean { // 取得したScan結果からAdvertising Packetを取得
val packet = result.scanRecord.bytes // iBeacon固定値の4byte目の0x02、5byte目の0x15があればtrue return packet[4] == 0x02.toByte() && packet[5] == 0x15.toByte() } scanDisposable = detector.start() .filter { check(it) } .map { transform(it) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ // onNext Log.d("MainActivity", String(it.major)) }, { // onError Log.d("MainActivity", it.message) })
必要なデータだけを取得 fun transform(result: ScanResult): IBeaconValue { val name = result.device.name
// デバイス名を取得 val packet = result.scanRecord.bytes val major = byteArrayOf(packet[22], packet[23]) val minor = byteArrayOf(packet[24], packet[25]) return IBeaconValue(name, major, minor) } scanDisposable = detector.start() .filter { check(it) } .map { transform(it) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ // onNext Log.d("MainActivity", String(it.major)) }, { // onError Log.d("MainActivity", it.message) })
Scan 開始と終了 // Scan開始 fun startScan() { scanDisposable = scanner.start()
.filter { check(it) } .map { transform(it) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ // onNext Log.d("MainActivity", String(it.major)) }, { // onError Log.d("MainActivity", it.message) }) } // Scan終了 fun stopScan() { scanner.stop() // スキャン自体の終了 scanDisposable?.dispose() // 明示的にDisposeさせる }
16 まとめ Scan 自体は Callback 地獄と言う訳ではないので嬉しさは…? おそらく RxJava で書けて嬉しいのは接続した後の処理から BLE
Advertise Scan は RxJava でそれっぽく書ける気がする BLE Advertise だけなら闇はほぼないのでお気軽に試せる ただ iBeacon の発信機は微妙に高い (製品だと 4000 円くらい) Android 5.0 以降なら Advertise の発信もできる いわゆる 「すれ違い」 アプリみたいなものはパパっとできる