Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Connect your Phone and Home with Firebase and...
Search
James Coggan
December 28, 2017
Programming
120
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Connect your Phone and Home with Firebase and Android Things
Presentation done at Droidcon Tel Aviv 2017
James Coggan
December 28, 2017
More Decks by James Coggan
See All by James Coggan
Build accessible conversational Experiences with Actions on Google
jamescoggan
0
70
How to test your Android Things code in a clean way
jamescoggan
0
100
GDG DevFest Kansas city - Connect your Phone and Home with Firebase and Android Things
jamescoggan
0
66
GDG DevFest Minneapolis - How to write your own custom driver for Android Things
jamescoggan
0
70
Londroind - Thingyfy your home with Android Things and Firebase
jamescoggan
0
110
Other Decks in Programming
See All in Programming
The NotImplementedError Problem in Ruby
koic
1
810
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
180
「エンジニアインターン、どうやって取った?」準備のリアルを語るLT会 Progate BAR
akiomatic
0
130
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
810
Agentic UI
manfredsteyer
PRO
0
170
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
11
4.2k
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
210
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
Contextとはなにか
chiroruxx
1
330
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
570
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
110
Featured
See All Featured
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
200
Utilizing Notion as your number one productivity tool
mfonobong
4
320
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
390
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Chasing Engaging Ingredients in Design
codingconduct
0
220
Everyday Curiosity
cassininazir
0
230
Six Lessons from altMBA
skipperchong
29
4.3k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
580
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
Transcript
James Coggan, MyDrive Solutions Connect your Phone and Home with
Firebase and Android Things We are hiring! https://www.mydrivesolutions.com/jobs Q&A sli.do #thingstelaviv
A little bit about me.. James Coggan Android tech lead
https://jamescoggan.com @mad_team
None
What is Android Things?
Android + Internet of Things Android Things
The hardware NXP Pico i.MX7D Raspberry Pi 3 NXP Argon
i.MX6UL NXP Pico i.MX6UL
Development kits NXP Pico i.MX7D Raspberry pi kit
Android
Android Things
What Android Things does support
What Android Things doesn’t support
Good to know • Main application started on boot •
Permissions are free and set on reboot • adb connect 192.168.1.111:5555
Why Android Things? • Kotlin :) • Maintained by Google
• OTA updates • Android community • Hardware agnostic • Relatively cheap hardware • Reusable code
Getting started https://partner.android.com/things/console/u/0/#/tools
Getting started
Getting started
Supported I/Os • General Purpose Input/Output (GPIO): Binary • Pulse
Width Modulation (PWM): Servo motors, DC motors • Inter-Integrated Circuit(I2C) • Serial Peripheral Interface (SPI) • Universal Asynchronous Receiver Transmitter (UART)
None
None
Raspberry Pi NXP MX7D
val pioService = PeripheralManagerService() try { val pinName = "BCM6"
ledGpio = pioService.openGpio(pinName) ledGpio?.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW) } catch (e: IOException) { e.printStackTrace() }
val pioService = PeripheralManagerService() try { val pinName = "BCM21"
button = ButtonInputDriver( pinName, Button.LogicState.PRESSED_WHEN_LOW, KeyEvent.KEYCODE_SPACE) button?.register() } catch (e: IOException) { e.printStackTrace() }
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { if (keyCode
== KeyEvent.KEYCODE_SPACE) { setLedValue(true) return true } return super.onKeyDown(keyCode, event) }
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { if (keyCode
== KeyEvent.KEYCODE_SPACE) { setLedValue(false) return true } return super.onKeyUp(keyCode, event) }
val gpioForLED: String // Pin 31 get() { return when
(Build.DEVICE) { DEVICE_RPI3 -> "BCM6" DEVICE_IMX6UL_PICO -> "GPIO4_IO22" DEVICE_IMX7D_PICO -> "GPIO2_IO02" else -> throw IllegalStateException("Unknown Build.DEVICE " + Build.DEVICE) } }
val gpioForButton: String // Pin 40 get() { return when
(Build.DEVICE) { DEVICE_RPI3 -> "BCM21" DEVICE_IMX6UL_PICO -> "GPIO2_IO03" DEVICE_IMX7D_PICO -> "GPIO6_IO14" else -> throw IllegalStateException("Unknown Build.DEVICE " + Build.DEVICE) } }
val pinName = gpioForLED ledGpio = pioService.openGpio(pinName) ... val pinName
= gpioForButton button = ButtonInputDriver( pinName, Button.LogicState.PRESSED_WHEN_LOW, KeyEvent.KEYCODE_SPACE) ...
None
None
None
Setting up Firebase https://console.firebase.google.com • Create a new Firebase project
• Add a new Android app to the project with your package name: ie: com.jamescoggan.thingspresentation • Enable anonymous login on (temporarily)
• Setup a database // Database { "light" : true
} • Add the rules // Rules - don’t expose your data for the world { "rules": { ".write": "auth != null", ".read": "auth != null", } }
// Base build.gradle for all modules buildscript { ... dependencies
{ classpath "com.google.gms:google-services:$googleServicesClassVersion" } }
// mobile & things build.gradle dependencies { ... implementation "com.google.firebase:firebase-core:$playServicesVersion"
implementation "com.google.firebase:firebase-database:$playServicesVersion" implementation "com.google.firebase:firebase-auth:$playServicesVersion" implementation "android.arch.lifecycle:extensions:$androidArchComponentsVersion" } apply plugin: "com.google.gms.google-services"
// MainActivity.kt (Both modules - mobile and things) override fun
onCreate(savedInstanceState: Bundle?) { FirebaseApp.initializeApp(this) // Move me to the Application class val firebaseAuth = FirebaseAuth.getInstance() val databaseReference = FirebaseDatabase.getInstance().reference }
// MainActivity.kt override fun onCreate(savedInstanceState: Bundle?) { ... val databaseReference
= FirebaseDatabase.getInstance().reference firebaseAuth.signInAnonymously() .addOnCompleteListener { task -> if (task.isSuccessful) { observeLightsData() } else { Timber.e(task.exception, "FirebaseAuth:failed") } } }
// Light.kt class FirebaseTables { companion object { val LIGHTS_BASE
= "light" } } data class Light(val light : Boolean)
class LightLiveData(val firebase: DatabaseReference) : LiveData<Light>() { private val valueEventListener
= object : ValueEventListener { override fun onDataChange(snapshot: DataSnapshot) { val newValue = snapshot.getValue(Boolean::class.java) ?: false value = Light(newValue) } override fun onCancelled(error: DatabaseError) { } } override fun onActive() { firebase.child(LIGHTS_BASE).addValueEventListener(valueEventListener) } override fun onInactive() { firebase.child(LIGHTS_BASE).removeEventListener(valueEventListener) } }
// Things Activity private val lightsDataObserver = Observer<Light> { lightState
-> Timber.d("LightState changed: ${lightState?.isOn}") led.setValue(lightState?.isOn ?: false) } override fun onCreate(savedInstanceState: Bundle?) { ... firebaseAuth.signInAnonymously() .addOnCompleteListener { task -> if (task.isSuccessful) { lightsLiveData.observe(this, lightsDataObserver) } else { Timber.e(task.exception, "FirebaseAuth:failed")
// Mobile Activity override fun onCreate(savedInstanceState: Bundle?) { ... toggleButton.setOnCheckedChangeListener({
_, state: Boolean -> databaseReference.child("light").setValue(state) }) }
None
None
None
Nearby • Pub/Sub • Send messages, files or stream data
• No need for server • Peer to peer • Wifi or BLE
Nearby
googleApiClient = GoogleApiClient.Builder(this) .addApi(Nearby.CONNECTIONS_API) .addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks { override fun
onConnected(connectionHint: Bundle?) { startService() } override fun onConnectionSuspended(cause: Int) { failed() } }) .build()
private fun startService() { // Android Things Nearby.Connections.startAdvertising( googleApiClient, "appName",
"serviceId", connectionLifecycleCallback, AdvertisingOptions(Strategy.P2P_STAR)) .setResultCallback { result -> when { result.status.isSuccess -> Timber.d("startAdvertising:onResult: SUCCESS") else -> Timber.w("STATE_READY")
private fun startService() { // Phone Nearby.Connections.startDiscovery( googleApiClient, "serviceId", endpointDiscoveryCallback,
DiscoveryOptions(Strategy.P2P_STAR)) .setResultCallback { result -> when { result.status.isSuccess -> Timber.d("startDiscovery:SUCCESS") else -> { Timber.w("startDiscovery:FAILURE ${result.statusMessage}")
private val connectionLifecycleCallback = object : ConnectionLifecycleCallback() { override fun
onConnectionResult(endpointId: String?, result: ConnectionResolution?) { Timber.d("connectionResult from " + endpointId, result) sendDataPayload() } }
// Phone private fun sendDataPayload(email : String, password: String) {
val credentials = Credentials(email, password) val adapter = moshi.adapter(Credentials::class.java) val json = adapter.toJson(credentials) Nearby.Connections.sendPayload( googleApiClient, currentEndpointId, Payload.fromBytes(json.toByteArray()) ) }
private val payloadCallback = object : PayloadCallback() { override fun
onPayloadReceived(endpointId: String?, payload: Payload?) { val adapter = moshi.adapter(Credentials::class.java) val credentials = adapter.fromJson(jsonString) credentials?.let { saveCredentials(credentials) } } }
firebaseAuth.signInWithEmailAndPassword(email,password) .addOnFailureListener { exception -> exception.printStackTrace() } .addOnSuccessListener { loadData()
} }
Success!!
https://github.com/jamescoggan/thingspresentationn • Common code in shared module • Nearby •
RainbowHat: ◦ Sensors ◦ Led ◦ Button • Philips Hue (in progress)
Q&A sli.do #thingstelaviv
Feedback: https://goo.gl/gwPxpY Thank you! https://jamescoggan.com @mad_team