├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── compiler.xml
├── encodings.xml
├── gradle.xml
└── misc.xml
├── LICENSE
├── README.md
├── build.gradle
├── chapter1
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── sampleapp
│ │ └── MainActivity.kt
│ └── res
│ └── values
│ └── strings.xml
├── chapter2-RainbowHAT
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── androidthingssamples
│ │ ├── buttons
│ │ ├── ButtonDriverActivity.kt
│ │ ├── ButtonInputDriverActivity.kt
│ │ ├── SingleButtonDriverActivity.kt
│ │ └── SingleButtonInputDriverActivity.kt
│ │ ├── buzzer
│ │ └── PianoActivity.kt
│ │ ├── lcd
│ │ ├── Marquee.kt
│ │ └── MarqueeLcdActivity.kt
│ │ ├── led
│ │ ├── BlinkCoroutineActivity.kt
│ │ ├── BlinkHandlerActivity.kt
│ │ ├── BlinkLoopActivity.kt
│ │ ├── BlinkThreadActivity.kt
│ │ └── BlinkTimerActivity.kt
│ │ ├── ledstrip
│ │ ├── KnightRiderActivity.kt
│ │ └── KnightRiderSimpleActivity.kt
│ │ └── temperatureDisplay
│ │ ├── AllSensorsDriverActivity.kt
│ │ ├── PressureDisplayActivity.kt
│ │ ├── TemperatureDisplayActivity.kt
│ │ └── TemperatureSensorDriverActivity.kt
│ └── res
│ └── values
│ └── strings.xml
├── chapter3-gpio
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── gpiosamples
│ │ ├── BlinkTimerActivity.kt
│ │ ├── BoardDefaults.kt
│ │ ├── ButtonDriverActivity.kt
│ │ ├── ButtonGpioActivity.kt
│ │ ├── ButtonInputDriverActivity.kt
│ │ ├── DistanceSensorActivity.kt
│ │ ├── DistanceSensorDriverActivity.kt
│ │ ├── LCDClockActivity.kt
│ │ ├── Motor.kt
│ │ ├── RobotCarActivity.kt
│ │ └── StepperMotorActivity.kt
│ └── res
│ └── values
│ └── strings.xml
├── chapter4-pwm
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── pwmsamples
│ │ ├── BoardDefaults.kt
│ │ ├── LedBrightnessActivity.kt
│ │ ├── PianoPwmActivity.kt
│ │ ├── PianoSpeakerActivity.kt
│ │ └── ServoActivity.kt
│ └── res
│ └── values
│ └── strings.xml
├── chapter5-i2c
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── i2csamples
│ │ ├── BoardDefaults.kt
│ │ ├── I2cUtils.kt
│ │ ├── LcdDisplayActivity.kt
│ │ ├── LedActivity.kt
│ │ ├── Mpu6050Activity.kt
│ │ ├── Pca9685ServoActivity.kt
│ │ ├── RgbLedActivity.kt
│ │ ├── ScanI2cActivity.kt
│ │ ├── Ssd1306Activity.kt
│ │ └── TemperatureDisplayActivity.kt
│ └── res
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── chapter6-spi
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── spisamples
│ │ ├── BoardDefaults.kt
│ │ ├── LedMatrixActivity.kt
│ │ └── Ssd1306OverSpiActivity.kt
│ └── res
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── chapter7-android-ui
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── androidui
│ │ └── MainActivity.kt
│ └── res
│ ├── layout
│ └── activity_main.xml
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── chapter7-api-mobile
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── api
│ │ └── mobile
│ │ ├── LedValue.kt
│ │ ├── MainActivity.kt
│ │ ├── TemperatureResponse.kt
│ │ └── ThingsApi.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ └── ic_launcher_background.xml
│ ├── layout
│ └── activity_main.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── chapter7-api-things
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── api
│ │ └── things
│ │ ├── ApiListener.kt
│ │ ├── ApiServer.kt
│ │ └── MainActivity.kt
│ └── res
│ └── values
│ └── strings.xml
├── chapter7-firebase-mobile
├── .gitignore
├── build.gradle
├── google-services.json
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── firebase
│ │ └── mobile
│ │ └── MainActivity.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ └── ic_launcher_background.xml
│ ├── layout
│ └── activity_main.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── chapter7-firebase-things
├── .gitignore
├── build.gradle
├── google-services.json
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── firebase
│ │ └── things
│ │ └── MainActivity.kt
│ └── res
│ └── values
│ └── strings.xml
├── chapter7-nearby-mobile
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── nearby
│ │ └── mobile
│ │ └── MainActivity.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ └── ic_launcher_background.xml
│ ├── layout
│ └── activity_main.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── chapter7-nearby-things
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── plattysoft
│ │ └── nearby
│ │ └── things
│ │ └── MainActivity.kt
│ └── res
│ └── values
│ └── strings.xml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/libraries
5 | /.idea/modules.xml
6 | /.idea/workspace.xml
7 | .DS_Store
8 | /build
9 | /captures
10 | .externalNativeBuild
11 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
29 |
30 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Packt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.2.50'
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.1.3'
11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
12 | classpath 'com.google.gms:google-services:4.0.1'
13 |
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | google()
22 | jcenter()
23 | // maven {
24 | // url "https://dl.bintray.com/plattysoft/PlattyThings"
25 | // }
26 | }
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/chapter1/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter1/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion 27
6 |
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.sampleapp"
10 | minSdkVersion 27
11 | targetSdkVersion 27
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | implementation 'com.android.support:support-v4:27.1.1'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
34 | compileOnly 'com.google.android.things:androidthings:+'
35 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
36 | }
37 |
--------------------------------------------------------------------------------
/chapter1/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter1/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/chapter1/src/main/java/com/plattysoft/sampleapp/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.sampleapp
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 |
6 | private val TAG = MainActivity::class.java.simpleName
7 |
8 | class MainActivity : Activity() {
9 |
10 | override fun onCreate(savedInstanceState: Bundle?) {
11 | super.onCreate(savedInstanceState)
12 | }
13 |
14 | override fun onDestroy() {
15 | super.onDestroy()
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/chapter1/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | sampleApp
3 |
4 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | apply plugin: 'kotlin-android'
4 |
5 | apply plugin: 'kotlin-android-extensions'
6 |
7 | android {
8 | compileSdkVersion 27
9 | defaultConfig {
10 | applicationId "com.plattysoft.androidthingssamples"
11 | minSdkVersion 27
12 | targetSdkVersion 27
13 | versionCode 1
14 | versionName "1.0"
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(dir: 'libs', include: ['*.jar'])
27 | implementation 'com.android.support:support-v4:27.1.1'
28 | testImplementation 'junit:junit:4.12'
29 | androidTestImplementation 'com.android.support.test:runner:1.0.1'
30 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
31 |
32 | compileOnly 'com.google.android.things:androidthings:+'
33 | implementation 'com.google.android.things.contrib:driver-rainbowhat:+'
34 |
35 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.5"
36 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
37 | }
38 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/buttons/ButtonDriverActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.buttons
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.contrib.driver.button.Button
6 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
7 | import com.google.android.things.pio.Gpio
8 |
9 | /**
10 | * Created by Raul Portales on 28/04/18.
11 | */
12 | class ButtonDriverActivity : Activity() {
13 |
14 | private lateinit var redLed: Gpio
15 | private lateinit var greenLed: Gpio
16 | private lateinit var blueLed: Gpio
17 |
18 | private lateinit var buttonA: Button
19 | private lateinit var buttonB: Button
20 | private lateinit var buttonC: Button
21 |
22 | override fun onCreate(savedInstanceState: Bundle?) {
23 | super.onCreate(savedInstanceState)
24 |
25 | redLed = RainbowHat.openLedRed()
26 | greenLed = RainbowHat.openLedGreen()
27 | blueLed = RainbowHat.openLedBlue()
28 |
29 | buttonA = RainbowHat.openButtonA()
30 | buttonB = RainbowHat.openButtonB()
31 | buttonC = RainbowHat.openButtonC()
32 |
33 | buttonA.setOnButtonEventListener { button: Button, state: Boolean ->
34 | redLed.value = state
35 | }
36 | buttonB.setOnButtonEventListener { button: Button, state: Boolean ->
37 | greenLed.value = state
38 | }
39 | buttonC.setOnButtonEventListener { button: Button, state: Boolean ->
40 | blueLed.value = state
41 | }
42 | }
43 |
44 | override fun onDestroy() {
45 | super.onDestroy()
46 |
47 | redLed.close()
48 | greenLed.close()
49 | blueLed.close()
50 |
51 | buttonA.close()
52 | buttonB.close()
53 | buttonC.close()
54 | }
55 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/buttons/ButtonInputDriverActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.buttons
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.view.KeyEvent
6 | import android.view.KeyEvent.*
7 | import com.google.android.things.contrib.driver.button.ButtonInputDriver
8 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
9 | import com.google.android.things.pio.Gpio
10 |
11 | /**
12 | * Created by Raul Portales on 28/04/18.
13 | */
14 | class ButtonInputDriverActivity : Activity() {
15 |
16 | private lateinit var redLed: Gpio
17 | private lateinit var greenLed: Gpio
18 | private lateinit var blueLed: Gpio
19 |
20 | private lateinit var buttonA: ButtonInputDriver
21 | private lateinit var buttonB: ButtonInputDriver
22 | private lateinit var buttonC: ButtonInputDriver
23 |
24 | override fun onCreate(savedInstanceState: Bundle?) {
25 | super.onCreate(savedInstanceState)
26 |
27 | redLed = RainbowHat.openLedRed()
28 | greenLed = RainbowHat.openLedGreen()
29 | blueLed = RainbowHat.openLedBlue()
30 |
31 | buttonA = RainbowHat.createButtonAInputDriver(KeyEvent.KEYCODE_A)
32 | buttonB = RainbowHat.createButtonBInputDriver(KeyEvent.KEYCODE_B)
33 | buttonC = RainbowHat.createButtonCInputDriver(KeyEvent.KEYCODE_C)
34 |
35 | buttonA.register()
36 | buttonB.register()
37 | buttonC.register()
38 | }
39 |
40 | override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
41 | val led = getLedForKeycode(keyCode)
42 | if (led != null) {
43 | led.value = true
44 | return true
45 | } else {
46 | return super.onKeyDown(keyCode, event)
47 | }
48 | }
49 |
50 | override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
51 | val led = getLedForKeycode(keyCode)
52 | if (led != null) {
53 | led.value = false
54 | return true
55 | } else {
56 | return super.onKeyUp(keyCode, event)
57 | }
58 | }
59 |
60 | private fun getLedForKeycode(keyCode: Int): Gpio? {
61 | when (keyCode) {
62 | KEYCODE_A -> {
63 | return redLed
64 | }
65 | KEYCODE_B -> {
66 | return greenLed
67 | }
68 | KEYCODE_C -> {
69 | return blueLed
70 | }
71 | else -> {
72 | return null
73 | }
74 | }
75 | }
76 |
77 | override fun onDestroy() {
78 | super.onDestroy()
79 |
80 | redLed.close()
81 | greenLed.close()
82 | blueLed.close()
83 |
84 | buttonA.unregister()
85 | buttonB.unregister()
86 | buttonC.unregister()
87 | }
88 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/buttons/SingleButtonDriverActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.buttons
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.contrib.driver.button.Button
6 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
7 | import com.google.android.things.pio.Gpio
8 |
9 | /**
10 | * Created by Raul Portales on 28/04/18.
11 | */
12 | class SingleButtonDriverActivity : Activity() {
13 |
14 | private lateinit var redLed: Gpio
15 |
16 | private lateinit var buttonA: Button
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 |
21 | redLed = RainbowHat.openLedRed()
22 |
23 | buttonA = RainbowHat.openButtonA()
24 | buttonA.setOnButtonEventListener { button: Button, state: Boolean ->
25 | redLed.value = state
26 | }
27 | }
28 |
29 | override fun onDestroy() {
30 | super.onDestroy()
31 | redLed.close()
32 | buttonA.close()
33 | }
34 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/buttons/SingleButtonInputDriverActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.buttons
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.view.KeyEvent
6 | import android.view.KeyEvent.*
7 | import com.google.android.things.contrib.driver.button.ButtonInputDriver
8 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
9 | import com.google.android.things.pio.Gpio
10 |
11 | /**
12 | * Created by Raul Portales on 28/04/18.
13 | */
14 | class SingleButtonInputDriverActivity : Activity() {
15 |
16 | private lateinit var redLed: Gpio
17 | private lateinit var buttonInputDriverA: ButtonInputDriver
18 |
19 | override fun onCreate(savedInstanceState: Bundle?) {
20 | super.onCreate(savedInstanceState)
21 |
22 | redLed = RainbowHat.openLedRed()
23 | buttonInputDriverA = RainbowHat.createButtonAInputDriver(KeyEvent.KEYCODE_A)
24 | buttonInputDriverA.register()
25 | }
26 |
27 | override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
28 | if (keyCode == KEYCODE_A) {
29 | redLed.value = true
30 | return true
31 | } else {
32 | return super.onKeyDown(keyCode, event)
33 | }
34 | }
35 |
36 | override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
37 | if (keyCode == KEYCODE_A) {
38 | redLed.value = false
39 | return true
40 | } else {
41 | return super.onKeyUp(keyCode, event)
42 | }
43 | }
44 |
45 | override fun onDestroy() {
46 | super.onDestroy()
47 | redLed.close()
48 | buttonInputDriverA.unregister()
49 | }
50 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/buzzer/PianoActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.buzzer
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.view.KeyEvent
6 | import android.view.KeyEvent.*
7 | import com.google.android.things.contrib.driver.button.ButtonInputDriver
8 | import com.google.android.things.contrib.driver.pwmspeaker.Speaker
9 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
10 |
11 | /**
12 | * Created by Raul Portales on 29/04/18.
13 | */
14 | class PianoActivity : Activity() {
15 |
16 | private lateinit var buttonA: ButtonInputDriver
17 | private lateinit var buttonB: ButtonInputDriver
18 | private lateinit var buttonC: ButtonInputDriver
19 |
20 | private lateinit var buzzer: Speaker
21 |
22 | private val frequencies = hashMapOf(
23 | KEYCODE_A to 1000.0,
24 | KEYCODE_B to 3000.0,
25 | KEYCODE_C to 5000.0)
26 |
27 | override fun onCreate(savedInstanceState: Bundle?) {
28 | super.onCreate(savedInstanceState)
29 |
30 | buzzer = RainbowHat.openPiezo()
31 |
32 | buttonA = RainbowHat.createButtonAInputDriver(KEYCODE_A)
33 | buttonB = RainbowHat.createButtonBInputDriver(KEYCODE_B)
34 | buttonC = RainbowHat.createButtonCInputDriver(KEYCODE_C)
35 |
36 | buttonA.register()
37 | buttonB.register()
38 | buttonC.register()
39 | }
40 |
41 | override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
42 | val freqToPlay = frequencies[keyCode]
43 | if (freqToPlay != null) {
44 | buzzer.play(freqToPlay)
45 | return true
46 | } else {
47 | return false
48 | }
49 | }
50 |
51 | override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
52 | buzzer.stop()
53 | return true
54 | }
55 |
56 | override fun onDestroy() {
57 | super.onDestroy()
58 |
59 | buzzer.close()
60 |
61 | buttonA.unregister()
62 | buttonB.unregister()
63 | buttonC.unregister()
64 | }
65 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/lcd/Marquee.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.lcd
2 |
3 |
4 | import com.google.android.things.contrib.driver.ht16k33.AlphanumericDisplay
5 | import com.google.android.things.contrib.driver.ht16k33.Ht16k33
6 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
7 |
8 | import java.util.Timer
9 | import kotlin.concurrent.timerTask
10 |
11 | /**
12 | * Created by rportales on 03/05/2017.
13 | */
14 |
15 | class Marquee : AutoCloseable {
16 |
17 | companion object {
18 | private const val MARQUEE_INTERVAL: Long = 800
19 | private const val LCD_LENGTH = 4
20 | private const val PADDING = " "
21 | }
22 |
23 | private var timer: Timer? = null
24 | private var currentMarqueePos: Int = 0
25 | private var marqueeText: String = ""
26 |
27 | private val display: AlphanumericDisplay
28 |
29 | init {
30 | display = RainbowHat.openDisplay()
31 | display.setEnabled(true)
32 | display.setBrightness(Ht16k33.HT16K33_BRIGHTNESS_MAX)
33 | }
34 |
35 | override fun close() {
36 | stop()
37 | display.close()
38 | }
39 |
40 | fun stop() {
41 | if (timer != null) {
42 | timer!!.cancel()
43 | timer!!.purge()
44 | timer = null
45 | }
46 | }
47 |
48 | fun displayText(text: String) {
49 | marqueeText = PADDING + text + PADDING
50 | currentMarqueePos = 0
51 | stop()
52 | timer = Timer()
53 | timer!!.schedule(timerTask {
54 | updateMarquee()
55 | }, 0, MARQUEE_INTERVAL)
56 | }
57 |
58 | private fun updateMarquee() {
59 | // In this display, the character '.' does not count as such (unless consecutive)
60 | // The length of the string to display depends on the number of dots there
61 | if (marqueeText[currentMarqueePos] == '.') {
62 | currentMarqueePos++
63 | }
64 | val displayText = splitString(marqueeText, currentMarqueePos)
65 | display.display(displayText)
66 |
67 | currentMarqueePos++
68 | if (currentMarqueePos + displayText.length >= marqueeText.length) {
69 | currentMarqueePos = 0
70 | }
71 | }
72 |
73 | private fun splitString(string: String, startPos: Int): String {
74 | var currentPos = startPos
75 | for (numProperCharacters in 0 until LCD_LENGTH) {
76 | // A dot after the current character is considered part of the character
77 | if (string.length > currentPos + 1 && string[currentPos + 1] == '.') {
78 | currentPos++
79 | }
80 | currentPos++
81 | }
82 | return string.substring(startPos, currentPos)
83 | }
84 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/lcd/MarqueeLcdActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.lcd
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 |
6 | /**
7 | * Created by Raul Portales on 29/04/18.
8 | */
9 | class MarqueeLcdActivity : Activity() {
10 |
11 | private lateinit var marquee: Marquee
12 |
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | marquee = Marquee()
16 | marquee.displayText("SOMETHING LONG")
17 | }
18 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/led/BlinkCoroutineActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.led
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
6 | import com.google.android.things.pio.Gpio
7 | import kotlinx.coroutines.experimental.*
8 |
9 | class BlinkCoroutineActivity : Activity() {
10 |
11 | private lateinit var led: Gpio
12 | private lateinit var job: Job
13 |
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | setup()
17 | job = launch {
18 | while (isActive) {
19 | loop()
20 | }
21 | }
22 | }
23 |
24 | private fun setup() {
25 | led = RainbowHat.openLedGreen()
26 | }
27 |
28 | private suspend fun loop() {
29 | led.value = !led.value
30 | delay(1000)
31 | }
32 |
33 | override fun onDestroy() {
34 | super.onDestroy()
35 | job.cancel()
36 | led.close()
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/led/BlinkHandlerActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.led
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
7 | import com.google.android.things.pio.Gpio
8 |
9 | class BlinkHandlerActivity : Activity() {
10 |
11 | private lateinit var led: Gpio
12 | private val handler = Handler()
13 |
14 | private val ledRunnable = object : Runnable {
15 | override fun run() {
16 | led.value = !led.value
17 | handler.postDelayed(this, 1000)
18 | }
19 | }
20 |
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | super.onCreate(savedInstanceState)
23 | led = RainbowHat.openLedGreen()
24 | handler.post(ledRunnable)
25 | }
26 |
27 | override fun onDestroy() {
28 | super.onDestroy()
29 | handler.removeCallbacks(ledRunnable)
30 | led.close()
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/led/BlinkLoopActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.led
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
6 | import com.google.android.things.pio.Gpio
7 |
8 | class BlinkLoopActivity : Activity() {
9 |
10 | private lateinit var led: Gpio
11 |
12 | override fun onCreate(savedInstanceState: Bundle?) {
13 | super.onCreate(savedInstanceState)
14 | setup()
15 | while (true) {
16 | loop()
17 | }
18 | }
19 |
20 | private fun setup() {
21 | led = RainbowHat.openLedRed()
22 | }
23 |
24 | private fun loop() {
25 | led.value = !led.value
26 | Thread.sleep(1000)
27 | }
28 |
29 | override fun onDestroy() {
30 | super.onDestroy()
31 | led.close()
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/led/BlinkThreadActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.led
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
6 | import com.google.android.things.pio.Gpio
7 |
8 | class BlinkThreadActivity : Activity() {
9 |
10 | private lateinit var led: Gpio
11 |
12 | private val thread = Thread {
13 | while (true) {
14 | loop()
15 | }
16 | }
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | setup()
21 | thread.start()
22 | }
23 |
24 | private fun setup() {
25 | led = RainbowHat.openLedGreen()
26 | }
27 |
28 | private fun loop() {
29 | led.value = !led.value
30 | Thread.sleep(1000)
31 | }
32 |
33 | override fun onDestroy() {
34 | super.onDestroy()
35 | thread.interrupt()
36 | led.close()
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/led/BlinkTimerActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.led
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
6 | import com.google.android.things.pio.Gpio
7 | import java.util.*
8 | import kotlin.concurrent.timerTask
9 |
10 | class BlinkTimerActivity : Activity() {
11 |
12 | private lateinit var led: Gpio
13 | private val timer = Timer()
14 |
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | led = RainbowHat.openLedGreen()
18 | timer.schedule(timerTask {
19 | led.value = !led.value
20 | }, 0, 1000)
21 | }
22 |
23 | override fun onDestroy() {
24 | super.onDestroy()
25 | timer.cancel()
26 | timer.purge()
27 | led.close()
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/ledstrip/KnightRiderActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.ledstrip
2 |
3 | import android.app.Activity
4 | import android.graphics.Color
5 | import android.os.Bundle
6 | import android.view.KeyEvent
7 | import com.google.android.things.contrib.driver.apa102.Apa102
8 | import com.google.android.things.contrib.driver.button.ButtonInputDriver
9 | import com.google.android.things.contrib.driver.ht16k33.Ht16k33
10 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
11 | import java.util.*
12 | import kotlin.concurrent.timerTask
13 |
14 |
15 | /**
16 | * Created by Raul Portales on 06/05/18.
17 | */
18 | class KnightRiderActivity : Activity() {
19 |
20 | companion object {
21 | private const val MIN_INTERVAL = 25
22 | private const val MAX_INTERVAL = 400
23 | }
24 |
25 | private var timer: Timer? = null
26 | private var goingUp = true
27 | private var currentPos = 0
28 | private var interval: Long = 200
29 |
30 | private lateinit var inputDriverA: ButtonInputDriver
31 | private lateinit var inputDriverB: ButtonInputDriver
32 | private lateinit var inputDriverC: ButtonInputDriver
33 |
34 | private lateinit var ledStrip: Apa102
35 |
36 | private val colors = IntArray(RainbowHat.LEDSTRIP_LENGTH)
37 |
38 | override fun onCreate(savedInstanceState: Bundle?) {
39 | super.onCreate(savedInstanceState)
40 |
41 | val alphanumericDisplay = RainbowHat.openDisplay()
42 | alphanumericDisplay.setBrightness(Ht16k33.HT16K33_BRIGHTNESS_MAX)
43 | alphanumericDisplay.setEnabled(true)
44 | alphanumericDisplay.display("KITT")
45 | alphanumericDisplay.close()
46 |
47 | ledStrip = RainbowHat.openLedStrip()
48 | ledStrip.brightness = 31
49 | ledStrip.direction = Apa102.Direction.NORMAL
50 |
51 | inputDriverA = RainbowHat.createButtonAInputDriver(KeyEvent.KEYCODE_A)
52 | inputDriverA.register()
53 | inputDriverB = RainbowHat.createButtonBInputDriver(KeyEvent.KEYCODE_B)
54 | inputDriverB.register()
55 | inputDriverC = RainbowHat.createButtonCInputDriver(KeyEvent.KEYCODE_C)
56 | inputDriverC.register()
57 | }
58 |
59 | override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
60 | if (keyCode == KeyEvent.KEYCODE_A) {
61 | if (timer == null) {
62 | startTimer()
63 | } else {
64 | stopTimer()
65 | }
66 | } else if (keyCode == KeyEvent.KEYCODE_B) {
67 | if (interval > MIN_INTERVAL) {
68 | interval /= 2
69 | restartTimer()
70 | }
71 | } else if (keyCode == KeyEvent.KEYCODE_C) {
72 | if (interval < MAX_INTERVAL) {
73 | interval *= 2
74 | restartTimer()
75 | }
76 | }
77 | return super.onKeyUp(keyCode, event)
78 | }
79 |
80 | override fun onDestroy() {
81 | super.onDestroy()
82 | stopTimer()
83 |
84 | inputDriverA.unregister()
85 | inputDriverB.unregister()
86 | inputDriverC.unregister()
87 |
88 | ledStrip.close()
89 | }
90 |
91 | private fun restartTimer() {
92 | stopTimer()
93 | startTimer()
94 | }
95 |
96 | private fun stopTimer() {
97 | if (timer != null) {
98 | timer!!.cancel()
99 | timer = null
100 | }
101 | }
102 |
103 | private fun startTimer() {
104 | timer = Timer()
105 | timer!!.schedule(timerTask {
106 | knightRider()
107 | }, interval, interval)
108 | }
109 |
110 | private fun knightRider() {
111 | updateCurrentPos()
112 | updateLedStrip()
113 | }
114 |
115 | private fun updateCurrentPos() {
116 | if (goingUp) {
117 | currentPos++
118 | if (currentPos == RainbowHat.LEDSTRIP_LENGTH - 1) {
119 | goingUp = false
120 | }
121 | } else {
122 | currentPos--
123 | if (currentPos == 0) {
124 | goingUp = true
125 | }
126 | }
127 | }
128 |
129 | private fun updateLedStrip() {
130 | for (i in colors.indices) {
131 | if (i == currentPos) {
132 | colors[i] = Color.RED
133 | } else {
134 | colors[i] = Color.TRANSPARENT
135 | }
136 | }
137 | ledStrip.write(colors)
138 | }
139 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/ledstrip/KnightRiderSimpleActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.ledstrip
2 |
3 | import android.app.Activity
4 | import android.graphics.Color
5 | import android.os.Bundle
6 | import com.google.android.things.contrib.driver.apa102.Apa102
7 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
8 | import java.util.*
9 | import kotlin.concurrent.timerTask
10 |
11 |
12 | /**
13 | * Created by Raul Portales on 06/05/18.
14 | */
15 | class KnightRiderSimpleActivity : Activity() {
16 | private val timer: Timer = Timer()
17 | private var goingUp = true
18 | private var currentPos = 0
19 | private val interval: Long = 100
20 |
21 | private val colors = IntArray(RainbowHat.LEDSTRIP_LENGTH)
22 | private lateinit var ledStrip: Apa102
23 |
24 | override fun onCreate(savedInstanceState: Bundle?) {
25 | super.onCreate(savedInstanceState)
26 |
27 | ledStrip = RainbowHat.openLedStrip()
28 | ledStrip.brightness = Apa102.MAX_BRIGHTNESS
29 | ledStrip.direction = Apa102.Direction.NORMAL
30 |
31 | timer.schedule(timerTask {
32 | knightRider()
33 | }, 0, interval)
34 | }
35 |
36 | override fun onDestroy() {
37 | super.onDestroy()
38 | timer.cancel()
39 | ledStrip.close()
40 | }
41 |
42 | private fun knightRider() {
43 | updateCurrentPos()
44 | updateLedStrip()
45 | }
46 |
47 | private fun updateCurrentPos() {
48 | if (goingUp) {
49 | currentPos++
50 | if (currentPos == RainbowHat.LEDSTRIP_LENGTH - 1) {
51 | goingUp = false
52 | }
53 | } else {
54 | currentPos--
55 | if (currentPos == 0) {
56 | goingUp = true
57 | }
58 | }
59 | }
60 |
61 | private fun updateLedStrip() {
62 | for (i in colors.indices) {
63 | if (i == currentPos) {
64 | colors[i] = Color.RED
65 | } else {
66 | colors[i] = Color.TRANSPARENT
67 | }
68 | }
69 | ledStrip.write(colors)
70 | }
71 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/temperatureDisplay/AllSensorsDriverActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.temperatureDisplay
2 |
3 | import android.app.Activity
4 | import android.content.ContentValues.TAG
5 | import android.content.Context
6 | import android.hardware.Sensor
7 | import android.hardware.SensorEvent
8 | import android.hardware.SensorEventListener
9 | import android.hardware.SensorManager
10 | import android.os.Bundle
11 | import android.util.Log
12 | import com.google.android.things.contrib.driver.bmx280.Bmx280SensorDriver
13 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
14 |
15 | /**
16 | * Created by Raul Portales on 07/05/18.
17 | */
18 | class AllSensorsDriverActivity : Activity() {
19 |
20 | private val sensorCallback = object : SensorManager.DynamicSensorCallback() {
21 | override fun onDynamicSensorConnected(sensor: Sensor?) {
22 | if (sensor?.type == Sensor.TYPE_AMBIENT_TEMPERATURE) {
23 | registerTemperatureListener(sensor)
24 | }
25 | if (sensor?.type == Sensor.TYPE_PRESSURE) {
26 | registerPressureListener(sensor)
27 | }
28 | }
29 | }
30 |
31 | private val temperatureSensorListener = object : SensorEventListener {
32 | override fun onSensorChanged(event: SensorEvent) {
33 | Log.i(TAG, "temperature changed: ${event.values[0]}")
34 | }
35 |
36 | override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
37 | Log.i(TAG, "accuracy changed: $accuracy")
38 | }
39 | }
40 |
41 | private val pressureSensorListener = object : SensorEventListener {
42 | override fun onSensorChanged(event: SensorEvent) {
43 | Log.i(TAG, "pressure changed: ${event.values[0]}")
44 | }
45 |
46 | override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
47 | Log.i(TAG, "accuracy changed: $accuracy")
48 | }
49 | }
50 |
51 | private lateinit var sensorManager: SensorManager
52 | private lateinit var sensorDriver: Bmx280SensorDriver
53 |
54 | override fun onCreate(savedInstanceState: Bundle?) {
55 | super.onCreate(savedInstanceState)
56 | sensorDriver = RainbowHat.createSensorDriver()
57 | sensorDriver.registerTemperatureSensor()
58 | sensorDriver.registerPressureSensor()
59 |
60 | sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
61 | sensorManager.registerDynamicSensorCallback(sensorCallback)
62 | }
63 |
64 | private fun registerTemperatureListener(sensor: Sensor) {
65 | sensorManager.registerListener(temperatureSensorListener, sensor, SensorManager.SENSOR_DELAY_NORMAL)
66 | }
67 |
68 | private fun registerPressureListener(sensor: Sensor) {
69 | sensorManager.registerListener(pressureSensorListener, sensor, SensorManager.SENSOR_DELAY_NORMAL)
70 | }
71 |
72 | override fun onDestroy() {
73 | super.onDestroy()
74 | sensorManager.unregisterListener(temperatureSensorListener)
75 | sensorManager.unregisterListener(pressureSensorListener)
76 | sensorDriver.unregisterTemperatureSensor()
77 | sensorDriver.unregisterPressureSensor()
78 | sensorDriver.close()
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/temperatureDisplay/PressureDisplayActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.temperatureDisplay
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import com.google.android.things.contrib.driver.bmx280.Bmx280
7 | import com.google.android.things.contrib.driver.ht16k33.AlphanumericDisplay
8 | import com.google.android.things.contrib.driver.ht16k33.Ht16k33
9 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
10 |
11 | /**
12 | * Created by Raul Portales on 07/05/18.
13 | */
14 | class PressureDisplayActivity : Activity() {
15 |
16 | private val handler = Handler()
17 |
18 | private lateinit var sensor: Bmx280
19 | private lateinit var alphanumericDisplay: AlphanumericDisplay
20 |
21 | private val displayPressureRunnable = object : Runnable {
22 | override fun run() {
23 | val pressure = sensor.readPressure().toDouble()
24 | alphanumericDisplay.display(pressure)
25 | handler.postDelayed(this, 1000)
26 | }
27 | }
28 | // Use the RainbowUtil.getWeatherStripColors() helper to convert the pressure value into a color array for the Apa102 driver.
29 |
30 | override fun onCreate(savedInstanceState: Bundle?) {
31 | super.onCreate(savedInstanceState)
32 |
33 | sensor = RainbowHat.openSensor()
34 | sensor.temperatureOversampling = Bmx280.OVERSAMPLING_1X
35 | sensor.pressureOversampling = Bmx280.OVERSAMPLING_1X
36 |
37 | alphanumericDisplay = RainbowHat.openDisplay()
38 | alphanumericDisplay.setBrightness(Ht16k33.HT16K33_BRIGHTNESS_MAX)
39 | alphanumericDisplay.setEnabled(true)
40 |
41 | handler.post(displayPressureRunnable)
42 | }
43 |
44 | override fun onDestroy() {
45 | super.onDestroy()
46 | sensor.close()
47 | alphanumericDisplay.close()
48 | }
49 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/temperatureDisplay/TemperatureDisplayActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.temperatureDisplay
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import com.google.android.things.contrib.driver.bmx280.Bmx280
7 | import com.google.android.things.contrib.driver.ht16k33.AlphanumericDisplay
8 | import com.google.android.things.contrib.driver.ht16k33.Ht16k33
9 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
10 |
11 | /**
12 | * Created by Raul Portales on 07/05/18.
13 | */
14 | class TemperatureDisplayActivity : Activity() {
15 |
16 | private val handler = Handler()
17 |
18 | private lateinit var sensor: Bmx280
19 | private lateinit var alphanumericDisplay: AlphanumericDisplay
20 |
21 | private val displayTemperatureRunnable = object : Runnable {
22 | override fun run() {
23 | val temperature = sensor.readTemperature().toDouble()
24 | // Display the temperature on the alphanumeric display.
25 | alphanumericDisplay.display(temperature)
26 | handler.post(this)
27 | }
28 | }
29 |
30 | override fun onCreate(savedInstanceState: Bundle?) {
31 | super.onCreate(savedInstanceState)
32 | sensor = RainbowHat.openSensor()
33 | sensor.temperatureOversampling = Bmx280.OVERSAMPLING_1X
34 | sensor.setMode(Bmx280.MODE_NORMAL)
35 |
36 | alphanumericDisplay = RainbowHat.openDisplay()
37 | alphanumericDisplay.setBrightness(Ht16k33.HT16K33_BRIGHTNESS_MAX)
38 | alphanumericDisplay.setEnabled(true)
39 |
40 | handler.post(displayTemperatureRunnable)
41 | }
42 |
43 | override fun onDestroy() {
44 | super.onDestroy()
45 | handler.removeCallbacks(displayTemperatureRunnable)
46 | sensor.close()
47 | alphanumericDisplay.close()
48 | }
49 | }
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/java/com/plattysoft/androidthingssamples/temperatureDisplay/TemperatureSensorDriverActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidthingssamples.temperatureDisplay
2 |
3 | import android.app.Activity
4 | import android.content.ContentValues.TAG
5 | import android.content.Context
6 | import android.hardware.Sensor
7 | import android.hardware.SensorEvent
8 | import android.hardware.SensorEventListener
9 | import android.hardware.SensorManager
10 | import android.os.Bundle
11 | import android.util.Log
12 | import com.google.android.things.contrib.driver.bmx280.Bmx280SensorDriver
13 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
14 |
15 | /**
16 | * Created by Raul Portales on 07/05/18.
17 | */
18 | class TemperatureSensorDriverActivity : Activity() {
19 |
20 | private val sensorCallback = object : SensorManager.DynamicSensorCallback() {
21 | override fun onDynamicSensorConnected(sensor: Sensor?) {
22 | if (sensor?.type == Sensor.TYPE_AMBIENT_TEMPERATURE) {
23 | registerTemperatureListener(sensor)
24 | }
25 | }
26 | }
27 |
28 | private val temperatureSensorListener = object : SensorEventListener {
29 | override fun onSensorChanged(event: SensorEvent) {
30 | Log.i(TAG, "temperature changed: ${event.values[0]}")
31 | }
32 |
33 | override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
34 | Log.i(TAG, "accuracy changed: $accuracy")
35 | }
36 | }
37 |
38 | private lateinit var sensorManager: SensorManager
39 | private lateinit var sensorDriver: Bmx280SensorDriver
40 |
41 | override fun onCreate(savedInstanceState: Bundle?) {
42 | super.onCreate(savedInstanceState)
43 |
44 | sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
45 | sensorManager.registerDynamicSensorCallback(sensorCallback)
46 |
47 | sensorDriver = RainbowHat.createSensorDriver()
48 | sensorDriver.registerTemperatureSensor()
49 | }
50 |
51 | private fun registerTemperatureListener(sensor: Sensor) {
52 | sensorManager.registerListener(temperatureSensorListener, sensor, SensorManager.SENSOR_DELAY_NORMAL)
53 | }
54 |
55 | override fun onDestroy() {
56 | super.onDestroy()
57 | sensorManager.unregisterDynamicSensorCallback(sensorCallback)
58 | sensorManager.unregisterListener(temperatureSensorListener)
59 | sensorDriver.unregisterTemperatureSensor()
60 | sensorDriver.close()
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/chapter2-RainbowHAT/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AndroidThingsSamples
3 |
4 |
--------------------------------------------------------------------------------
/chapter3-gpio/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter3-gpio/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion 27
6 |
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.gpiosamples"
10 | minSdkVersion 27
11 | targetSdkVersion 27
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | implementation 'com.android.support:support-v4:27.1.1'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
34 | compileOnly 'com.google.android.things:androidthings:+'
35 |
36 | implementation 'com.google.android.things.contrib:driver-button:+'
37 | implementation 'com.google.android.things.contrib:driver-tm1637:+'
38 |
39 | implementation 'com.plattysoft.things:l298n:0.1.0'
40 | implementation 'com.plattysoft.things:uln2003:1.0.0'
41 |
42 | implementation 'com.leinardi.android.things:driver-hcsr04:+'
43 |
44 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
45 | }
46 |
--------------------------------------------------------------------------------
/chapter3-gpio/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/BlinkTimerActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.pio.Gpio
6 | import com.google.android.things.pio.PeripheralManager
7 | import java.util.*
8 | import kotlin.concurrent.timerTask
9 |
10 | class BlinkTimerActivity : Activity() {
11 |
12 | private lateinit var led: Gpio
13 | private val timer = Timer()
14 |
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | led = PeripheralManager.getInstance().openGpio(BoardDefaults.ledR)
18 | led.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW)
19 | timer.schedule(timerTask {
20 | led.value = !led.value
21 | }, 0, 1000)
22 | }
23 |
24 | override fun onDestroy() {
25 | super.onDestroy()
26 | timer.cancel()
27 | timer.purge()
28 | led.close()
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/BoardDefaults.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import android.os.Build
4 |
5 | object BoardDefaults {
6 | private const val DEVICE_RPI3 = "rpi3"
7 | private const val DEVICE_IMX7D_PICO = "imx7d_pico"
8 |
9 | val i2cBus: String
10 | get() = when (Build.DEVICE) {
11 | DEVICE_RPI3 -> "I2C1"
12 | DEVICE_IMX7D_PICO -> "I2C1"
13 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
14 | }
15 | val spiBus: String
16 | get() = when (Build.DEVICE) {
17 | DEVICE_RPI3 -> "SPI0.0"
18 | DEVICE_IMX7D_PICO -> "SPI3.1"
19 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
20 | }
21 | val piezoPwm: String
22 | get() = when (Build.DEVICE) {
23 | DEVICE_RPI3 -> "PWM1"
24 | DEVICE_IMX7D_PICO -> "PWM2"
25 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
26 | }
27 | val servoPwm: String
28 | get() = when (Build.DEVICE) {
29 | DEVICE_RPI3 -> "PWM0"
30 | DEVICE_IMX7D_PICO -> "PWM1"
31 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
32 | }
33 | val buttonA: String
34 | get() = when (Build.DEVICE) {
35 | DEVICE_RPI3 -> "BCM21"
36 | DEVICE_IMX7D_PICO -> "GPIO6_IO14"
37 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
38 | }
39 | val buttonB: String
40 | get() = when (Build.DEVICE) {
41 | DEVICE_RPI3 -> "BCM20"
42 | DEVICE_IMX7D_PICO -> "GPIO6_IO15"
43 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
44 | }
45 | val buttonC: String
46 | get() = when (Build.DEVICE) {
47 | DEVICE_RPI3 -> "BCM16"
48 | DEVICE_IMX7D_PICO -> "GPIO2_IO07"
49 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
50 | }
51 | val ledR: String
52 | get() = when (Build.DEVICE) {
53 | DEVICE_RPI3 -> "BCM6"
54 | DEVICE_IMX7D_PICO -> "GPIO2_IO02"
55 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
56 | }
57 | val ledG: String
58 | get() = when (Build.DEVICE) {
59 | DEVICE_RPI3 -> "BCM19"
60 | DEVICE_IMX7D_PICO -> "GPIO2_IO00"
61 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
62 | }
63 | val ledB: String
64 | get() = when (Build.DEVICE) {
65 | DEVICE_RPI3 -> "BCM26"
66 | DEVICE_IMX7D_PICO -> "GPIO2_IO05"
67 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
68 | }
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/ButtonDriverActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.contrib.driver.button.Button
6 | import com.google.android.things.pio.Gpio
7 | import com.google.android.things.pio.PeripheralManager
8 |
9 | /**
10 | * Created by Raul Portales on 28/04/18.
11 | */
12 | class ButtonDriverActivity : Activity() {
13 |
14 | private lateinit var redLed: Gpio
15 | private lateinit var buttonA: Button
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 |
20 | redLed = PeripheralManager.getInstance().openGpio(BoardDefaults.ledR)
21 | redLed.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW)
22 |
23 | buttonA = Button(BoardDefaults.buttonA, Button.LogicState.PRESSED_WHEN_LOW)
24 | buttonA.setOnButtonEventListener { button: Button, state: Boolean ->
25 | redLed.value = state
26 | }
27 | }
28 |
29 | override fun onDestroy() {
30 | super.onDestroy()
31 | redLed.close()
32 | buttonA.close()
33 | }
34 | }
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/ButtonGpioActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.pio.Gpio
6 | import com.google.android.things.pio.PeripheralManager
7 |
8 | /**
9 | * Created by Raul Portales on 28/04/18.
10 | */
11 | class ButtonGpioActivity : Activity() {
12 |
13 | private lateinit var redLed: Gpio
14 | private lateinit var buttonA: Gpio
15 |
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | super.onCreate(savedInstanceState)
18 |
19 | redLed = PeripheralManager.getInstance().openGpio(BoardDefaults.ledR)
20 | redLed.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW)
21 |
22 | buttonA = PeripheralManager.getInstance().openGpio(BoardDefaults.buttonA)
23 | buttonA.setDirection(Gpio.DIRECTION_IN)
24 | buttonA.setActiveType(Gpio.ACTIVE_LOW)
25 | buttonA.setEdgeTriggerType(Gpio.EDGE_BOTH)
26 | buttonA.registerGpioCallback {
27 | redLed.value = it.value
28 | true
29 | }
30 | }
31 |
32 | override fun onDestroy() {
33 | super.onDestroy()
34 | redLed.close()
35 | buttonA.close()
36 | }
37 | }
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/ButtonInputDriverActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.view.KeyEvent
6 | import android.view.KeyEvent.KEYCODE_A
7 | import com.google.android.things.contrib.driver.button.Button
8 | import com.google.android.things.contrib.driver.button.ButtonInputDriver
9 | import com.google.android.things.pio.Gpio
10 | import com.google.android.things.pio.PeripheralManager
11 |
12 | /**
13 | * Created by Raul Portales on 28/04/18.
14 | */
15 | class ButtonInputDriverActivity : Activity() {
16 |
17 | private lateinit var redLed: Gpio
18 |
19 | private lateinit var buttonDriverA: ButtonInputDriver
20 |
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | super.onCreate(savedInstanceState)
23 |
24 | redLed = PeripheralManager.getInstance().openGpio(BoardDefaults.ledR)
25 | redLed.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW)
26 |
27 | buttonDriverA = ButtonInputDriver(BoardDefaults.buttonA, Button.LogicState.PRESSED_WHEN_LOW, KEYCODE_A)
28 | buttonDriverA.register()
29 | }
30 |
31 | override fun onDestroy() {
32 | super.onDestroy()
33 | redLed.close()
34 | buttonDriverA.close()
35 | }
36 |
37 | override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
38 | if (keyCode == KEYCODE_A) {
39 | redLed.value = true
40 | return true
41 | } else {
42 | return super.onKeyDown(keyCode, event)
43 | }
44 | }
45 |
46 | override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
47 | if (keyCode == KEYCODE_A) {
48 | redLed.value = false
49 | return true
50 | } else {
51 | return super.onKeyUp(keyCode, event)
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/DistanceSensorActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import android.util.Log
7 | import com.leinardi.android.things.driver.hcsr04.Hcsr04
8 |
9 | /**
10 | * Created by Raul Portales on 13/05/18.
11 | */
12 | class DistanceSensorActivity : Activity() {
13 | companion object {
14 | private const val triggerGpio = "BCM23"
15 | private const val echoGpio = "BCM24"
16 | }
17 |
18 | private lateinit var sensor: Hcsr04
19 | private val handler = Handler()
20 |
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | super.onCreate(savedInstanceState)
23 | sensor = Hcsr04(triggerGpio, echoGpio)
24 |
25 | handler.post(object : Runnable {
26 | override fun run() {
27 | val distance = sensor.readDistance()
28 | Log.d("DistanceSensorActivity", "distance: $distance")
29 | handler.post(this)
30 | }
31 | })
32 | }
33 |
34 | override fun onDestroy() {
35 | super.onDestroy()
36 | sensor.close()
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/DistanceSensorDriverActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import android.app.Activity
4 | import android.content.ContentValues
5 | import android.content.Context
6 | import android.hardware.Sensor
7 | import android.hardware.SensorEvent
8 | import android.hardware.SensorEventListener
9 | import android.hardware.SensorManager
10 | import android.os.Build
11 | import android.os.Bundle
12 | import android.util.Log
13 | import com.leinardi.android.things.driver.hcsr04.Hcsr04SensorDriver
14 |
15 | /**
16 | * Created by Raul Portales on 13/05/18.
17 | */
18 | class DistanceSensorDriverActivity : Activity() {
19 | companion object {
20 | private const val DEVICE_RPI3 = "rpi3"
21 | private const val DEVICE_IMX7D_PICO = "imx7d_pico"
22 |
23 | private val triggerGpio: String
24 | get() = when (Build.DEVICE) {
25 | DEVICE_RPI3 -> "BCM23"
26 | DEVICE_IMX7D_PICO -> "GPIO2_IO13"
27 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
28 | }
29 | private val echoGpio: String
30 | get() = when (Build.DEVICE) {
31 | DEVICE_RPI3 -> "BCM24"
32 | DEVICE_IMX7D_PICO -> "GPIO2_IO12"
33 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
34 | }
35 | }
36 |
37 | private val sensorCallback = object : SensorManager.DynamicSensorCallback() {
38 | override fun onDynamicSensorConnected(sensor: Sensor?) {
39 | if (sensor?.type == Sensor.TYPE_PROXIMITY) {
40 | sensorManager.registerListener(sensorListener,
41 | sensor, SensorManager.SENSOR_DELAY_FASTEST)
42 | }
43 | }
44 | }
45 |
46 | private val sensorListener = object : SensorEventListener {
47 | override fun onSensorChanged(event: SensorEvent) {
48 | val distance = event.values[0]
49 | Log.i(ContentValues.TAG, "proximity changed: $distance")
50 | }
51 |
52 | override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
53 | Log.i(ContentValues.TAG, "accuracy changed: $accuracy")
54 | }
55 | }
56 |
57 | private lateinit var sensorManager: SensorManager
58 | private lateinit var sensorDriver: Hcsr04SensorDriver
59 |
60 | override fun onCreate(savedInstanceState: Bundle?) {
61 | super.onCreate(savedInstanceState)
62 |
63 | sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
64 | sensorDriver = Hcsr04SensorDriver(triggerGpio, echoGpio)
65 |
66 | sensorManager.registerDynamicSensorCallback(sensorCallback)
67 | sensorDriver.registerProximitySensor()
68 | }
69 |
70 | override fun onDestroy() {
71 | super.onDestroy()
72 | sensorManager.unregisterDynamicSensorCallback(sensorCallback)
73 | sensorDriver.unregisterProximitySensor()
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/LCDClockActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import android.app.Activity
4 | import android.os.Build
5 | import android.os.Bundle
6 | import com.google.android.things.contrib.driver.tm1637.NumericDisplay
7 | import java.text.SimpleDateFormat
8 | import java.util.*
9 | import kotlin.concurrent.timerTask
10 |
11 | /**
12 | * Created by Raul Portales on 12/05/18.
13 | */
14 | class LCDClockActivity : Activity() {
15 |
16 | companion object {
17 | private const val DEVICE_RPI3 = "rpi3"
18 | private const val DEVICE_IMX7D_PICO = "imx7d_pico"
19 |
20 | private val dataGpioPinName: String
21 | get() = when (Build.DEVICE) {
22 | DEVICE_RPI3 -> "BCM23"
23 | DEVICE_IMX7D_PICO -> "GPIO2_IO13"
24 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
25 | }
26 | private val clockGpioPinName: String
27 | get() = when (Build.DEVICE) {
28 | DEVICE_RPI3 -> "BCM24"
29 | DEVICE_IMX7D_PICO -> "GPIO2_IO12"
30 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
31 | }
32 | }
33 |
34 | private val dateFormat = SimpleDateFormat("HHmm")
35 | private val date = Date()
36 |
37 | lateinit var display: NumericDisplay
38 |
39 | override fun onCreate(savedInstanceState: Bundle?) {
40 | super.onCreate(savedInstanceState)
41 | display = NumericDisplay(dataGpioPinName, clockGpioPinName)
42 | display.setBrightness(NumericDisplay.MAX_BRIGHTNESS)
43 |
44 | Timer().schedule(timerTask {
45 | // Blink the colon
46 | display.colonEnabled = !display.colonEnabled
47 | // Update the values
48 | date.time = System.currentTimeMillis()
49 | display.display(dateFormat.format(date))
50 | }, 0, 1000)
51 | }
52 |
53 | override fun onDestroy() {
54 | super.onDestroy()
55 | display.close()
56 | }
57 | }
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/Motor.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import com.google.android.things.pio.Gpio
4 | import com.google.android.things.pio.PeripheralManager
5 |
6 | class Motor(gpioForwardPin: String, gpioBackwardPin: String) : AutoCloseable {
7 | private val gpioForward: Gpio
8 | private val gpioBackward: Gpio
9 |
10 | init {
11 | val service = PeripheralManager.getInstance()
12 |
13 | gpioForward = service.openGpio(gpioForwardPin)
14 | gpioForward.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW)
15 | gpioBackward = service.openGpio(gpioBackwardPin)
16 | gpioBackward.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW)
17 | }
18 |
19 | override fun close() {
20 | gpioForward.close()
21 | gpioBackward.close()
22 | }
23 |
24 | fun forward() {
25 | gpioForward.value = true
26 | gpioBackward.value = false
27 | }
28 |
29 | fun backward() {
30 | gpioForward.value = false
31 | gpioBackward.value = true
32 | }
33 |
34 | fun stop() {
35 | gpioForward.value = false
36 | gpioBackward.value = false
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/RobotCarActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.view.KeyEvent
6 | import com.plattysoft.l298n.L298N
7 | import com.plattysoft.l298n.MotorMode
8 |
9 |
10 | /**
11 | * Created by Raul Portales on 18/05/18.
12 | */
13 | class RobotCarActivity : Activity() {
14 |
15 | private lateinit var motorController: L298N
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 | // PINS for the motor controller L298N
20 | // BCM22, BCM23, BCM24, BCM25
21 | // mMotorController = L298N.open("BCM22", "BCM23", "BCM24", "BCM25")
22 | motorController = L298N.open("GPIO2_IO00", "GPIO2_IO05",
23 | "GPIO2_IO07", "GPIO6_IO15")
24 | motorController.setMode(MotorMode.STOP)
25 | }
26 |
27 | override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
28 | if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
29 | motorController.setMode(MotorMode.FORWARD)
30 | } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
31 | motorController.setMode(MotorMode.BACKWARD)
32 | } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
33 | motorController.setMode(MotorMode.TURN_LEFT)
34 | } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
35 | motorController.setMode(MotorMode.TURN_RIGHT)
36 | }
37 | return super.onKeyDown(keyCode, event)
38 | }
39 |
40 | override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
41 | motorController.setMode(MotorMode.STOP)
42 | return super.onKeyUp(keyCode, event)
43 | }
44 |
45 | override fun onDestroy() {
46 | super.onDestroy()
47 | motorController.close()
48 | }
49 | }
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/java/com/plattysoft/gpiosamples/StepperMotorActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.gpiosamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.util.Log
6 | import com.plattysoft.uln2003.Direction
7 | import com.plattysoft.uln2003.driver.ULN2003Resolution
8 | import com.plattysoft.uln2003.listener.RotationListener
9 | import com.plattysoft.uln2003.motor.ULN2003StepperMotor
10 |
11 | /**
12 | * Created by Raul Portales on 19/05/18.
13 | */
14 | class StepperMotorActivity : Activity() {
15 |
16 | companion object {
17 | private val TAG = StepperMotorActivity::class.java.simpleName!!
18 | }
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 |
23 | val in1Pin = "BCM4"
24 | val in2Pin = "BCM17"
25 | val in3Pin = "BCM27"
26 | val in4Pin = "BCM22"
27 |
28 | val stepper = ULN2003StepperMotor(in1Pin, in2Pin, in3Pin, in4Pin)
29 |
30 | //Perform a rotation and add rotation listener
31 | stepper.rotate(degrees = 180.0,
32 | direction = Direction.CLOCKWISE,
33 | resolutionId = ULN2003Resolution.HALF.id,
34 | rpm = 2.5,
35 | rotationListener = object : RotationListener {
36 | override fun onStarted() {
37 | Log.i(TAG, "rotation started")
38 | }
39 |
40 | override fun onFinishedSuccessfully() {
41 | Log.i(TAG, "rotation finished")
42 | }
43 |
44 | override fun onFinishedWithError(degreesToRotate: Double, rotatedDegrees: Double, exception: Exception) {
45 | Log.e(TAG, "error, degrees to rotate: {$degreesToRotate} rotated degrees: {$rotatedDegrees}")
46 | }
47 | })
48 |
49 | // Close the ULN2003StepperMotor when all moves are finished. Otherwise close() will terminate current and pending rotations.
50 | stepper.close()
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/chapter3-gpio/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | GPIO samples
3 |
4 |
--------------------------------------------------------------------------------
/chapter4-pwm/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter4-pwm/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion 27
6 |
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.pwmsamples"
10 | minSdkVersion 27
11 | targetSdkVersion 27
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | implementation 'com.android.support:support-v4:27.1.1'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
34 | compileOnly 'com.google.android.things:androidthings:+'
35 |
36 | implementation 'com.google.android.things.contrib:driver-button:+'
37 | implementation 'com.google.android.things.contrib:driver-pwmspeaker:+'
38 | implementation 'com.google.android.things.contrib:driver-pwmservo:+'
39 | implementation 'com.google.android.things.contrib:driver-button:+'
40 | implementation 'com.google.android.things.contrib:driver-ht16k33:+'
41 |
42 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
43 | }
44 |
--------------------------------------------------------------------------------
/chapter4-pwm/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter4-pwm/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/chapter4-pwm/src/main/java/com/plattysoft/pwmsamples/BoardDefaults.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.pwmsamples
2 |
3 | import android.os.Build
4 |
5 | object BoardDefaults {
6 | private const val DEVICE_RPI3 = "rpi3"
7 | private const val DEVICE_IMX7D_PICO = "imx7d_pico"
8 |
9 | val i2cBus: String
10 | get() = when (Build.DEVICE) {
11 | DEVICE_RPI3 -> "I2C1"
12 | DEVICE_IMX7D_PICO -> "I2C1"
13 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
14 | }
15 | val spiBus: String
16 | get() = when (Build.DEVICE) {
17 | DEVICE_RPI3 -> "SPI0.0"
18 | DEVICE_IMX7D_PICO -> "SPI3.1"
19 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
20 | }
21 | val piezoPwm: String
22 | get() = when (Build.DEVICE) {
23 | DEVICE_RPI3 -> "PWM1"
24 | DEVICE_IMX7D_PICO -> "PWM2"
25 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
26 | }
27 | val servoPwm: String
28 | get() = when (Build.DEVICE) {
29 | DEVICE_RPI3 -> "PWM0"
30 | DEVICE_IMX7D_PICO -> "PWM1"
31 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
32 | }
33 | val buttonA: String
34 | get() = when (Build.DEVICE) {
35 | DEVICE_RPI3 -> "BCM21"
36 | DEVICE_IMX7D_PICO -> "GPIO6_IO14"
37 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
38 | }
39 | val buttonB: String
40 | get() = when (Build.DEVICE) {
41 | DEVICE_RPI3 -> "BCM20"
42 | DEVICE_IMX7D_PICO -> "GPIO6_IO15"
43 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
44 | }
45 | val buttonC: String
46 | get() = when (Build.DEVICE) {
47 | DEVICE_RPI3 -> "BCM16"
48 | DEVICE_IMX7D_PICO -> "GPIO2_IO07"
49 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
50 | }
51 | val ledR: String
52 | get() = when (Build.DEVICE) {
53 | DEVICE_RPI3 -> "BCM6"
54 | DEVICE_IMX7D_PICO -> "GPIO2_IO02"
55 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
56 | }
57 | val ledG: String
58 | get() = when (Build.DEVICE) {
59 | DEVICE_RPI3 -> "BCM19"
60 | DEVICE_IMX7D_PICO -> "GPIO2_IO00"
61 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
62 | }
63 | val ledB: String
64 | get() = when (Build.DEVICE) {
65 | DEVICE_RPI3 -> "BCM26"
66 | DEVICE_IMX7D_PICO -> "GPIO2_IO05"
67 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
68 | }
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/chapter4-pwm/src/main/java/com/plattysoft/pwmsamples/LedBrightnessActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.pwmsamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import com.google.android.things.pio.PeripheralManager
7 | import com.google.android.things.pio.Pwm
8 |
9 | /**
10 | * Created by Raul Portales on 13/05/18.
11 | */
12 | class LedBrightnessActivity : Activity() {
13 |
14 | private val initialTime = System.currentTimeMillis()
15 | private lateinit var pwm: Pwm
16 | private val handler = Handler()
17 |
18 | private val ledRunnable = object : Runnable {
19 | override fun run() {
20 | val elapsedSeconds = (System.currentTimeMillis() - initialTime) / 1000.0
21 | val dutyCycle = Math.cos(elapsedSeconds) * 50.0 + 50
22 | pwm.setPwmDutyCycle(dutyCycle)
23 | handler.post(this)
24 | }
25 | }
26 |
27 | override fun onCreate(savedInstanceState: Bundle?) {
28 | super.onCreate(savedInstanceState)
29 |
30 | pwm = PeripheralManager.getInstance().openPwm(BoardDefaults.servoPwm)
31 | pwm.setPwmFrequencyHz(50.0)
32 | pwm.setEnabled(true)
33 |
34 | handler.post(ledRunnable)
35 | }
36 |
37 | override fun onDestroy() {
38 | super.onDestroy()
39 | handler.removeCallbacks(ledRunnable)
40 | pwm.close()
41 | }
42 | }
--------------------------------------------------------------------------------
/chapter4-pwm/src/main/java/com/plattysoft/pwmsamples/PianoPwmActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.pwmsamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.view.KeyEvent
6 | import android.view.KeyEvent.*
7 | import com.google.android.things.contrib.driver.button.Button
8 | import com.google.android.things.contrib.driver.button.ButtonInputDriver
9 | import com.google.android.things.pio.PeripheralManager
10 | import com.google.android.things.pio.Pwm
11 | import com.plattysoft.pwmsamples.BoardDefaults
12 |
13 | /**
14 | * Created by Raul Portales on 29/04/18.
15 | */
16 | class PianoPwmActivity : Activity() {
17 |
18 | private lateinit var buttonA: ButtonInputDriver
19 | private lateinit var buttonB: ButtonInputDriver
20 | private lateinit var buttonC: ButtonInputDriver
21 |
22 | private lateinit var buzzer: Pwm
23 |
24 | private val frequencies = hashMapOf(
25 | KEYCODE_A to 1000.0,
26 | KEYCODE_B to 3000.0,
27 | KEYCODE_C to 5000.0)
28 |
29 | override fun onCreate(savedInstanceState: Bundle?) {
30 | super.onCreate(savedInstanceState)
31 |
32 | val pioService = PeripheralManager.getInstance()
33 | buzzer = pioService.openPwm(BoardDefaults.piezoPwm)
34 | buzzer.setPwmDutyCycle(50.0)
35 |
36 | buttonA = ButtonInputDriver(BoardDefaults.buttonA, Button.LogicState.PRESSED_WHEN_LOW, KEYCODE_A)
37 | buttonB = ButtonInputDriver(BoardDefaults.buttonB, Button.LogicState.PRESSED_WHEN_LOW, KEYCODE_B)
38 | buttonC = ButtonInputDriver(BoardDefaults.buttonC, Button.LogicState.PRESSED_WHEN_LOW, KEYCODE_B)
39 |
40 | buttonA.register()
41 | buttonB.register()
42 | buttonC.register()
43 | }
44 |
45 | override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
46 | val freqToPlay = frequencies[keyCode]
47 | if (freqToPlay != null) {
48 | buzzer.setPwmFrequencyHz(freqToPlay)
49 | buzzer.setEnabled(true)
50 | return true
51 | } else {
52 | return false
53 | }
54 | }
55 |
56 | override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
57 | buzzer.setEnabled(false)
58 | return true
59 | }
60 |
61 | override fun onDestroy() {
62 | super.onDestroy()
63 |
64 | buzzer.close()
65 |
66 | buttonA.unregister()
67 | buttonB.unregister()
68 | buttonC.unregister()
69 | }
70 | }
--------------------------------------------------------------------------------
/chapter4-pwm/src/main/java/com/plattysoft/pwmsamples/PianoSpeakerActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.pwmsamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.view.KeyEvent
6 | import android.view.KeyEvent.*
7 | import com.google.android.things.contrib.driver.button.Button
8 | import com.google.android.things.contrib.driver.button.ButtonInputDriver
9 | import com.google.android.things.contrib.driver.pwmspeaker.Speaker
10 | import com.plattysoft.pwmsamples.BoardDefaults
11 |
12 | /**
13 | * Created by Raul Portales on 29/04/18.
14 | */
15 | class PianoSpeakerActivity : Activity() {
16 |
17 | private lateinit var buttonA: ButtonInputDriver
18 | private lateinit var buttonB: ButtonInputDriver
19 | private lateinit var buttonC: ButtonInputDriver
20 |
21 | private lateinit var buzzer: Speaker
22 |
23 | private val frequencies = hashMapOf(
24 | KEYCODE_A to 1000.0,
25 | KEYCODE_B to 3000.0,
26 | KEYCODE_C to 5000.0)
27 |
28 | override fun onCreate(savedInstanceState: Bundle?) {
29 | super.onCreate(savedInstanceState)
30 |
31 | buzzer = Speaker(BoardDefaults.piezoPwm)
32 |
33 | buttonA = ButtonInputDriver(BoardDefaults.buttonA, Button.LogicState.PRESSED_WHEN_LOW, KEYCODE_A)
34 | buttonB = ButtonInputDriver(BoardDefaults.buttonB, Button.LogicState.PRESSED_WHEN_LOW, KEYCODE_B)
35 | buttonC = ButtonInputDriver(BoardDefaults.buttonC, Button.LogicState.PRESSED_WHEN_LOW, KEYCODE_B)
36 |
37 | buttonA.register()
38 | buttonB.register()
39 | buttonC.register()
40 | }
41 |
42 | override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
43 | val freqToPlay = frequencies[keyCode]
44 | if (freqToPlay != null) {
45 | buzzer.play(freqToPlay)
46 | return true
47 | } else {
48 | return false
49 | }
50 | }
51 |
52 | override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
53 | buzzer.stop()
54 | return true
55 | }
56 |
57 | override fun onDestroy() {
58 | super.onDestroy()
59 |
60 | buzzer.close()
61 |
62 | buttonA.unregister()
63 | buttonB.unregister()
64 | buttonC.unregister()
65 | }
66 | }
--------------------------------------------------------------------------------
/chapter4-pwm/src/main/java/com/plattysoft/pwmsamples/ServoActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.pwmsamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.view.KeyEvent
6 | import android.view.KeyEvent.*
7 | import com.google.android.things.contrib.driver.button.Button
8 | import com.google.android.things.contrib.driver.button.ButtonInputDriver
9 | import com.google.android.things.contrib.driver.ht16k33.AlphanumericDisplay
10 | import com.google.android.things.contrib.driver.pwmservo.Servo
11 |
12 | /**
13 | * Created by Raul Portales on 13/05/18.
14 | */
15 | class ServoActivity : Activity() {
16 |
17 | private lateinit var buttonA: ButtonInputDriver
18 | private lateinit var buttonB: ButtonInputDriver
19 | private lateinit var buttonC: ButtonInputDriver
20 | private lateinit var servo: Servo
21 | private lateinit var display: AlphanumericDisplay
22 |
23 | private var targetAngle = 0.0
24 |
25 | override fun onCreate(savedInstanceState: Bundle?) {
26 | super.onCreate(savedInstanceState)
27 |
28 | servo = Servo(BoardDefaults.servoPwm)
29 | servo.setPulseDurationRange(0.65, 2.5)
30 | servo.setAngleRange(0.0, 180.0)
31 | servo.setEnabled(true)
32 |
33 | display = AlphanumericDisplay(BoardDefaults.i2cBus)
34 | display.setEnabled(true)
35 | display.setBrightness(AlphanumericDisplay.HT16K33_BRIGHTNESS_MAX)
36 |
37 | buttonA = ButtonInputDriver(BoardDefaults.buttonA, Button.LogicState.PRESSED_WHEN_LOW, KEYCODE_A)
38 | buttonB = ButtonInputDriver(BoardDefaults.buttonB, Button.LogicState.PRESSED_WHEN_LOW, KEYCODE_B)
39 | buttonC = ButtonInputDriver(BoardDefaults.buttonC, Button.LogicState.PRESSED_WHEN_LOW, KEYCODE_C)
40 |
41 | buttonA.register()
42 | buttonB.register()
43 | buttonC.register()
44 | }
45 |
46 | override fun onDestroy() {
47 | super.onDestroy()
48 |
49 | servo.close()
50 | display.close()
51 |
52 | buttonA.unregister()
53 | buttonB.unregister()
54 | buttonC.unregister()
55 | }
56 |
57 |
58 | override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
59 | if (handleKeyCode(keyCode)) {
60 | return true
61 | }
62 | return super.onKeyDown(keyCode, event)
63 | }
64 |
65 | override fun onKeyMultiple(keyCode: Int, repeatCount: Int, event: KeyEvent?): Boolean {
66 | if (handleKeyCode(keyCode)) {
67 | return true
68 | }
69 | return super.onKeyMultiple(keyCode, repeatCount, event)
70 | }
71 |
72 | private fun handleKeyCode(keyCode: Int): Boolean {
73 | when (keyCode) {
74 | KEYCODE_A -> {
75 | decreaseAngle()
76 | return true
77 | }
78 | KEYCODE_B -> {
79 | increaseAngle()
80 | return true
81 | }
82 | KEYCODE_C -> {
83 | servo.angle = targetAngle
84 | return true
85 | }
86 | else -> {
87 | return false
88 | }
89 | }
90 | }
91 |
92 | private fun decreaseAngle() {
93 | targetAngle--
94 | if (targetAngle < servo.minimumAngle) {
95 | targetAngle = servo.minimumAngle
96 | }
97 | display.display(targetAngle)
98 | }
99 |
100 | private fun increaseAngle() {
101 | targetAngle++
102 | if (targetAngle > servo.maximumAngle) {
103 | targetAngle = servo.maximumAngle
104 | }
105 | display.display(targetAngle)
106 | }
107 | }
--------------------------------------------------------------------------------
/chapter4-pwm/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | PWM Samples
3 |
4 |
--------------------------------------------------------------------------------
/chapter5-i2c/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter5-i2c/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion 27
6 |
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.i2csamples"
10 | minSdkVersion 27
11 | targetSdkVersion 27
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | implementation 'com.android.support.constraint:constraint-layout:1.1.0'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
34 | compileOnly 'com.google.android.things:androidthings:+'
35 |
36 | implementation 'com.google.android.things.contrib:driver-ht16k33:+'
37 | implementation 'com.google.android.things.contrib:driver-bmx280:+'
38 | implementation 'com.google.android.things.contrib:driver-ssd1306:+'
39 | implementation 'com.google.android.things.contrib:driver-button:+'
40 |
41 | implementation 'com.nilhcem.androidthings:driver-lcd-pcf8574:+'
42 |
43 | implementation 'com.plattysoft.things:pcf8591:+'
44 | implementation 'com.plattysoft.things:mpu6050:+'
45 | implementation 'com.plattysoft.things:pca9685:+'
46 |
47 | implementation 'com.android.support:support-annotations:25.3.1'
48 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
49 | }
50 |
--------------------------------------------------------------------------------
/chapter5-i2c/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/java/com/plattysoft/i2csamples/BoardDefaults.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.i2csamples
2 |
3 | import android.os.Build
4 |
5 | object BoardDefaults {
6 | private const val DEVICE_RPI3 = "rpi3"
7 | private const val DEVICE_IMX7D_PICO = "imx7d_pico"
8 |
9 | val buttonA: String
10 | get() = when (Build.DEVICE) {
11 | DEVICE_RPI3 -> "BCM21"
12 | DEVICE_IMX7D_PICO -> "GPIO6_IO14"
13 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
14 | }
15 | val buttonB: String
16 | get() = when (Build.DEVICE) {
17 | DEVICE_RPI3 -> "BCM20"
18 | DEVICE_IMX7D_PICO -> "GPIO6_IO15"
19 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
20 | }
21 | val buttonC: String
22 | get() = when (Build.DEVICE) {
23 | DEVICE_RPI3 -> "BCM16"
24 | DEVICE_IMX7D_PICO -> "GPIO2_IO07"
25 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/java/com/plattysoft/i2csamples/I2cUtils.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.i2csamples
2 |
3 | import com.google.android.things.pio.PeripheralManager
4 | import java.io.IOException
5 |
6 | /**
7 | * Created by Raul Portales on 26/05/18.
8 | */
9 | object I2cUtils {
10 |
11 | fun getBus(): String {
12 | val peripheralManager = PeripheralManager.getInstance()
13 | val deviceList = peripheralManager.i2cBusList
14 | return if (deviceList.isEmpty()) {
15 | "I2C1"
16 | } else {
17 | deviceList[0]
18 | }
19 | }
20 |
21 | fun scanAvailableAddresses(i2cName: String): List {
22 | val pm = PeripheralManager.getInstance()
23 | val availableAddresses = mutableListOf()
24 | for (address in 0..127) {
25 | val device = pm.openI2cDevice(i2cName, address)
26 | try {
27 | device.write(ByteArray(1), 1)
28 | availableAddresses.add(address)
29 | } catch (e: IOException) {
30 | // Not available, not adding it
31 | } finally {
32 | device.close()
33 | }
34 | }
35 | return availableAddresses
36 | }
37 | }
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/java/com/plattysoft/i2csamples/LcdDisplayActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.i2csamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.nilhcem.androidthings.driver.lcdpcf8574.LcdPcf8574
6 |
7 |
8 | /**
9 | * Created by Raul Portales on 05/06/18.
10 | */
11 | class LcdDisplayActivity : Activity() {
12 |
13 | companion object {
14 | private const val I2C_ADDRESS = 0x27
15 | }
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 | val lcd = LcdPcf8574(I2cUtils.getBus(), I2C_ADDRESS)
20 | lcd.begin(16, 2)
21 | lcd.setBacklight(true)
22 |
23 | lcd.clear()
24 | lcd.print("Hello,")
25 | lcd.setCursor(0, 1)
26 | lcd.print("Android Things!")
27 |
28 | lcd.close()
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/java/com/plattysoft/i2csamples/LedActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.i2csamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import com.plattysoft.pca9685.PCA9685
7 |
8 | /**
9 | * Created by Raul Portales on 23/05/18.
10 | */
11 | class LedActivity : Activity() {
12 |
13 | private lateinit var pwmExpander: PCA9685
14 | private val handler = Handler()
15 |
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | super.onCreate(savedInstanceState)
18 | pwmExpander = PCA9685()
19 | pwmExpander.setPwmFreq(50)
20 | val initialTime = System.currentTimeMillis()
21 |
22 | handler.post(object : Runnable {
23 | override fun run() {
24 | val elapsedSeconds = (System.currentTimeMillis() - initialTime) / 1000.0
25 | val dutyCycle = Math.cos(elapsedSeconds) * 50.0 + 50
26 | pwmExpander.setPwmDutyCycle(12, dutyCycle.toInt())
27 | handler.post(this)
28 | }
29 | })
30 | }
31 |
32 | override fun onDestroy() {
33 | super.onDestroy()
34 | pwmExpander.close()
35 | }
36 | }
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/java/com/plattysoft/i2csamples/Mpu6050Activity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.i2csamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.util.Log
6 | import com.plattysoft.mpu6050.Mpu6050
7 |
8 | /**
9 | * Created by Raul Portales on 16/05/18.
10 | */
11 | class Mpu6050Activity : Activity() {
12 |
13 | companion object {
14 | private const val TAG = "Mpu6050Activity"
15 | }
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 | val gyroscope = Mpu6050.open()
20 | // Values are on accelXYZ and gyroXYZ
21 | Log.d(TAG, "Accel: x:${gyroscope.accelX} y:${gyroscope.accelY} z:${gyroscope.accelZ}")
22 | Log.d(TAG, "Gyro: x:${gyroscope.gyroX} y:${gyroscope.gyroY} z:${gyroscope.gyroZ}")
23 | gyroscope.close()
24 | }
25 | }
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/java/com/plattysoft/i2csamples/Pca9685ServoActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.i2csamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.view.KeyEvent
6 | import com.google.android.things.contrib.driver.button.Button
7 | import com.google.android.things.contrib.driver.button.ButtonInputDriver
8 | import com.google.android.things.contrib.driver.ht16k33.AlphanumericDisplay
9 | import com.plattysoft.pca9685.PCA9685
10 | import com.plattysoft.pca9685.ServoUnderPca9685
11 |
12 | /**
13 | * Created by Raul Portales on 09/06/18.
14 | */
15 | class Pca9685ServoActivity : Activity() {
16 | private lateinit var buttonA: ButtonInputDriver
17 | private lateinit var buttonB: ButtonInputDriver
18 | private lateinit var buttonC: ButtonInputDriver
19 | private lateinit var pca9685: PCA9685
20 | private lateinit var servo: ServoUnderPca9685
21 | private lateinit var display: AlphanumericDisplay
22 |
23 | private var targetAngle = 0.0
24 |
25 | override fun onCreate(savedInstanceState: Bundle?) {
26 | super.onCreate(savedInstanceState)
27 |
28 | pca9685 = PCA9685()
29 | servo = pca9685.openServo(0)
30 |
31 | servo.setPulseDurationRange(0.65, 2.5)
32 | servo.setAngleRange(0.0, 180.0)
33 |
34 | display = AlphanumericDisplay(I2cUtils.getBus())
35 | display.setEnabled(true)
36 | display.setBrightness(AlphanumericDisplay.HT16K33_BRIGHTNESS_MAX)
37 |
38 | buttonA = ButtonInputDriver(BoardDefaults.buttonA, Button.LogicState.PRESSED_WHEN_LOW, KeyEvent.KEYCODE_A)
39 | buttonB = ButtonInputDriver(BoardDefaults.buttonB, Button.LogicState.PRESSED_WHEN_LOW, KeyEvent.KEYCODE_B)
40 | buttonC = ButtonInputDriver(BoardDefaults.buttonC, Button.LogicState.PRESSED_WHEN_LOW, KeyEvent.KEYCODE_C)
41 |
42 | buttonA.register()
43 | buttonB.register()
44 | buttonC.register()
45 | }
46 |
47 | override fun onDestroy() {
48 | super.onDestroy()
49 |
50 | pca9685.close()
51 | display.close()
52 |
53 | buttonA.unregister()
54 | buttonB.unregister()
55 | buttonC.unregister()
56 | }
57 |
58 |
59 | override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
60 | if (handleKeyCode(keyCode)) {
61 | return true
62 | }
63 | return super.onKeyDown(keyCode, event)
64 | }
65 |
66 | override fun onKeyMultiple(keyCode: Int, repeatCount: Int, event: KeyEvent?): Boolean {
67 | if (handleKeyCode(keyCode)) {
68 | return true
69 | }
70 | return super.onKeyMultiple(keyCode, repeatCount, event)
71 | }
72 |
73 | private fun handleKeyCode(keyCode: Int): Boolean {
74 | when (keyCode) {
75 | KeyEvent.KEYCODE_A -> {
76 | decreaseAngle()
77 | return true
78 | }
79 | KeyEvent.KEYCODE_B -> {
80 | increaseAngle()
81 | return true
82 | }
83 | KeyEvent.KEYCODE_C -> {
84 | servo.angle = targetAngle
85 | return true
86 | }
87 | else -> {
88 | return false
89 | }
90 | }
91 | }
92 |
93 | private fun decreaseAngle() {
94 | targetAngle--
95 | if (targetAngle < servo.minimumAngle) {
96 | targetAngle = servo.minimumAngle
97 | }
98 | display.display(targetAngle)
99 | }
100 |
101 | private fun increaseAngle() {
102 | targetAngle++
103 | if (targetAngle > servo.maximumAngle) {
104 | targetAngle = servo.maximumAngle
105 | }
106 | display.display(targetAngle)
107 | }
108 | }
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/java/com/plattysoft/i2csamples/RgbLedActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.i2csamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import com.plattysoft.pca9685.PCA9685
7 | import com.plattysoft.pcf8591.Pcf8591
8 |
9 | /**
10 | * Created by Raul Portales on 23/05/18.
11 | */
12 | class RgbLedActivity : Activity() {
13 |
14 | private lateinit var pwmExpander: PCA9685
15 | private lateinit var adc: Pcf8591
16 | private val handler = Handler()
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | adc = Pcf8591.open()
21 | pwmExpander = PCA9685()
22 |
23 | handler.post(object : Runnable {
24 | override fun run() {
25 | val values = adc.readAllValues()
26 | for (i in 0..2) {
27 | pwmExpander.setPwmDutyCycle(i, (values[i] / 256.0).toInt())
28 | }
29 | handler.postDelayed(this, 200)
30 | }
31 | })
32 | }
33 |
34 | override fun onDestroy() {
35 | super.onDestroy()
36 | adc.close()
37 | pwmExpander.close()
38 | }
39 | }
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/java/com/plattysoft/i2csamples/ScanI2cActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.i2csamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.util.Log
6 |
7 | /**
8 | * Created by Raul Portales on 17/06/18.
9 | */
10 | class ScanI2cActivity : Activity() {
11 |
12 | override fun onCreate(savedInstanceState: Bundle?) {
13 | super.onCreate(savedInstanceState)
14 | val defaultBus = I2cUtils.getBus()
15 | val activeAddresses = I2cUtils.scanAvailableAddresses(defaultBus)
16 | for (address in activeAddresses) {
17 | Log.d("ScanI2cActivity", "Address found: 0x${address.toString(16)}")
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/java/com/plattysoft/i2csamples/Ssd1306Activity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.i2csamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.contrib.driver.ssd1306.Ssd1306
6 |
7 | /**
8 | * Created by Raul Portales on 30/05/18.
9 | */
10 | class Ssd1306Activity : Activity() {
11 |
12 | override fun onCreate(savedInstanceState: Bundle?) {
13 | super.onCreate(savedInstanceState)
14 | val display = Ssd1306(I2cUtils.getBus())
15 | for (i in 0 until display.lcdWidth) {
16 | for (j in 0 until display.lcdHeight) {
17 | display.setPixel(i, j, i % display.lcdHeight > j)
18 | }
19 | }
20 | // render the pixel data
21 | display.show()
22 | // Cleanup
23 | display.close()
24 | }
25 | }
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/java/com/plattysoft/i2csamples/TemperatureDisplayActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.i2csamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import com.google.android.things.contrib.driver.bmx280.Bmx280
7 | import com.google.android.things.contrib.driver.ht16k33.AlphanumericDisplay
8 | import com.google.android.things.contrib.driver.ht16k33.Ht16k33
9 |
10 | /**
11 | * Created by Raul Portales on 07/05/18.
12 | */
13 | class TemperatureDisplayActivity : Activity() {
14 |
15 |
16 | private val i2cBusName = I2cUtils.getBus()
17 |
18 | private val handler = Handler()
19 |
20 | private lateinit var sensor: Bmx280
21 | private lateinit var alphanumericDisplay: AlphanumericDisplay
22 |
23 | private val displayTemperatureRunnable = object : Runnable {
24 | override fun run() {
25 | val temperature = sensor.readTemperature().toDouble()
26 | // Display the temperature on the alphanumeric display.
27 | alphanumericDisplay.display(temperature)
28 | handler.post(this)
29 | }
30 | }
31 |
32 | override fun onCreate(savedInstanceState: Bundle?) {
33 | super.onCreate(savedInstanceState)
34 | sensor = Bmx280(i2cBusName)
35 | sensor.temperatureOversampling = Bmx280.OVERSAMPLING_1X
36 | sensor.setMode(Bmx280.MODE_NORMAL)
37 |
38 | alphanumericDisplay = AlphanumericDisplay(i2cBusName)
39 | alphanumericDisplay.setBrightness(Ht16k33.HT16K33_BRIGHTNESS_MAX)
40 | alphanumericDisplay.setEnabled(true)
41 |
42 | handler.post(displayTemperatureRunnable)
43 | }
44 |
45 | override fun onDestroy() {
46 | super.onDestroy()
47 | handler.removeCallbacks(displayTemperatureRunnable)
48 | sensor.close()
49 | alphanumericDisplay.close()
50 | }
51 | }
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | I2C samples
3 |
4 |
--------------------------------------------------------------------------------
/chapter5-i2c/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/chapter6-spi/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter6-spi/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion 27
6 |
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.spisamples"
10 | minSdkVersion 27
11 | targetSdkVersion 27
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | implementation 'com.android.support.constraint:constraint-layout:1.1.0'
31 | testImplementation 'junit:junit:4.12'
32 |
33 | implementation 'com.nilhcem.androidthings:driver-max72xx:+'
34 | implementation 'com.plattysoft.things:ssd1306:+'
35 |
36 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
37 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
38 | compileOnly 'com.google.android.things:androidthings:+'
39 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
40 | }
41 |
--------------------------------------------------------------------------------
/chapter6-spi/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter6-spi/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/chapter6-spi/src/main/java/com/plattysoft/spisamples/BoardDefaults.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.spisamples
2 |
3 | import android.os.Build
4 |
5 | object BoardDefaults {
6 | private const val DEVICE_RPI3 = "rpi3"
7 | private const val DEVICE_IMX7D_PICO = "imx7d_pico"
8 |
9 | val spiBus: String
10 | get() = when (Build.DEVICE) {
11 | DEVICE_RPI3 -> "SPI0.0"
12 | DEVICE_IMX7D_PICO -> "SPI3.1"
13 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
14 | }
15 | val spiHatBus: String
16 | get() = when (Build.DEVICE) {
17 | DEVICE_RPI3 -> "SPI0.1"
18 | DEVICE_IMX7D_PICO -> "SPI3.0"
19 | else -> throw IllegalStateException("Unknown Build.DEVICE ${Build.DEVICE}")
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/chapter6-spi/src/main/java/com/plattysoft/spisamples/LedMatrixActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.spisamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.nilhcem.androidthings.driver.max72xx.LedControl
6 | import java.util.*
7 | import kotlin.concurrent.timerTask
8 |
9 | class LedMatrixActivity : Activity() {
10 |
11 | private val SPI_BUS: String = BoardDefaults.spiHatBus
12 |
13 | private var currentSprite = 0
14 | private val sprites = arrayOf(
15 | byteArrayOf(
16 | 0b00011000.toByte(),
17 | 0b00111100.toByte(),
18 | 0b01111110.toByte(),
19 | 0b11011011.toByte(),
20 | 0b11111111.toByte(),
21 | 0b00100100.toByte(),
22 | 0b01011010.toByte(),
23 | 0b10100101.toByte()
24 | ),
25 | byteArrayOf(
26 | 0b00011000.toByte(),
27 | 0b00111100.toByte(),
28 | 0b01111110.toByte(),
29 | 0b11011011.toByte(),
30 | 0b11111111.toByte(),
31 | 0b01011010.toByte(),
32 | 0b10000001.toByte(),
33 | 0b01000010.toByte()
34 | )
35 | )
36 |
37 | private lateinit var ledControl: LedControl
38 | private val timer = Timer()
39 |
40 | override fun onCreate(savedInstanceState: Bundle?) {
41 | super.onCreate(savedInstanceState)
42 | ledControl = LedControl(SPI_BUS, 1) // second parameter is the number of chained matrices. Here, we only use 1 LED matrix module (8x8).
43 | initLedMatrix()
44 | timer.schedule(timerTask {
45 | swapSprite()
46 | }, 1000, 1000)
47 | }
48 |
49 | private fun initLedMatrix() {
50 | for (i in 0 until ledControl.getDeviceCount()) {
51 | ledControl.setIntensity(i, 1)
52 | ledControl.shutdown(i, false)
53 | ledControl.clearDisplay(i)
54 | }
55 | }
56 |
57 | override fun onDestroy() {
58 | super.onDestroy()
59 | timer.cancel()
60 | timer.purge()
61 | ledControl.close()
62 | }
63 |
64 | private fun swapSprite() {
65 | currentSprite++
66 | for (row in 0..7) {
67 | ledControl.setRow(0, row, sprites[currentSprite % sprites.size][row])
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/chapter6-spi/src/main/java/com/plattysoft/spisamples/Ssd1306OverSpiActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.spisamples
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.plattysoft.androidthings.ssd1306.Ssd1306
6 |
7 |
8 | /**
9 | * Created by Raul Portales on 30/05/18.
10 | */
11 | class Ssd1306OverSpiActivity : Activity() {
12 |
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | val display = Ssd1306.openSpi("SPI0.0", "BCM25", "BCM24", 128, 64)
16 | for (i in 0 until display.lcdWidth) {
17 | for (j in 0 until display.lcdHeight) {
18 | display.setPixel(i, j, i % display.lcdHeight > j)
19 | }
20 | }
21 | // Render the pixel data
22 | display.show()
23 | // Cleanup
24 | display.close()
25 | }
26 | }
--------------------------------------------------------------------------------
/chapter6-spi/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/chapter6-spi/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | spisamples
3 |
4 |
--------------------------------------------------------------------------------
/chapter6-spi/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/chapter7-android-ui/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter7-android-ui/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion 27
6 |
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.androidui"
10 | minSdkVersion 27
11 | targetSdkVersion 27
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | testImplementation 'junit:junit:4.12'
31 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
32 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
33 | compileOnly 'com.google.android.things:androidthings:+'
34 |
35 | implementation 'com.google.android.things.contrib:driver-rainbowhat:+'
36 |
37 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
38 | }
39 |
--------------------------------------------------------------------------------
/chapter7-android-ui/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter7-android-ui/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/chapter7-android-ui/src/main/java/com/plattysoft/androidui/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.androidui
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import android.os.Looper
7 | import android.widget.CompoundButton
8 | import com.google.android.things.contrib.driver.bmx280.Bmx280
9 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
10 | import com.google.android.things.pio.Gpio
11 | import kotlinx.android.synthetic.main.activity_main.*
12 |
13 | class MainActivity : Activity() {
14 |
15 | lateinit var redLed: Gpio
16 | lateinit var temperatureSensor: Bmx280
17 |
18 | private val handler = Handler(Looper.getMainLooper())
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 | setContentView(R.layout.activity_main)
23 |
24 | redLed = RainbowHat.openLedRed()
25 |
26 | temperatureSensor = RainbowHat.openSensor()
27 | temperatureSensor.setMode(Bmx280.MODE_NORMAL)
28 | temperatureSensor.temperatureOversampling = Bmx280.OVERSAMPLING_1X
29 |
30 | configureLedSwitch()
31 |
32 | configureTemperatureReading()
33 | }
34 |
35 | override fun onDestroy() {
36 | super.onDestroy()
37 | redLed.close()
38 | temperatureSensor.close()
39 | }
40 |
41 | private fun configureLedSwitch() {
42 | redLedSwitch.setOnCheckedChangeListener { compoundButton: CompoundButton, b: Boolean ->
43 | redLed.value = b
44 | }
45 | }
46 |
47 | private fun configureTemperatureReading() {
48 | handler.post(object : Runnable {
49 | override fun run() {
50 | val temperature = temperatureSensor.readTemperature()
51 | temperatureValue.text = temperature.toString()
52 | handler.postDelayed(this, 1000)
53 | }
54 | })
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/chapter7-android-ui/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
28 |
29 |
39 |
40 |
--------------------------------------------------------------------------------
/chapter7-android-ui/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/chapter7-android-ui/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | android-ui
3 | Red LED
4 | Temperature:
5 |
6 |
--------------------------------------------------------------------------------
/chapter7-android-ui/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion 27
6 |
7 | defaultConfig {
8 | applicationId "com.plattysoft.api.mobile"
9 | minSdkVersion 27
10 | targetSdkVersion 27
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(dir: 'libs', include: ['*.jar'])
27 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
28 | implementation 'com.android.support:appcompat-v7:27.1.1'
29 | implementation 'com.android.support.constraint:constraint-layout:1.1.0'
30 | testImplementation 'junit:junit:4.12'
31 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
32 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
33 | compileOnly 'com.google.android.things:androidthings:+'
34 | implementation 'com.google.code.gson:gson:2.8.2'
35 | implementation 'com.squareup.retrofit2:retrofit:2.3.0'
36 | implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
37 | implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
38 | implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/java/com/plattysoft/api/mobile/LedValue.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.api.mobile
2 |
3 | import com.google.gson.annotations.SerializedName
4 |
5 | class LedValue {
6 | @SerializedName("status")
7 | var status: Boolean = false
8 | }
9 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/java/com/plattysoft/api/mobile/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.api.mobile
2 |
3 | import android.support.v7.app.AppCompatActivity
4 | import android.os.Bundle
5 | import android.util.Log
6 | import android.widget.*
7 | import okhttp3.OkHttpClient
8 | import okhttp3.logging.HttpLoggingInterceptor
9 | import retrofit2.Call
10 | import retrofit2.Callback
11 | import retrofit2.Response
12 | import retrofit2.converter.gson.GsonConverterFactory
13 | import retrofit2.Retrofit
14 |
15 | class MainActivity : AppCompatActivity() {
16 |
17 | companion object {
18 | const val BASE_URL = "http://192.168.42.38:8080/"
19 | }
20 |
21 | private val apiService: ThingsApi
22 |
23 | init {
24 | val logging = HttpLoggingInterceptor()
25 | logging.level = HttpLoggingInterceptor.Level.BASIC
26 | val client = OkHttpClient.Builder()
27 | .addInterceptor(logging)
28 | .build()
29 | val retrofit = Retrofit.Builder()
30 | .baseUrl(BASE_URL)
31 | .client(client)
32 | .addConverterFactory(GsonConverterFactory.create())
33 | .build()
34 | apiService = retrofit.create(ThingsApi::class.java)
35 |
36 | }
37 |
38 | val handler = android.os.Handler()
39 |
40 | override fun onCreate(savedInstanceState: Bundle?) {
41 | super.onCreate(savedInstanceState)
42 | setContentView(R.layout.activity_main)
43 | configureLedSwitch()
44 | configureTemperatureReading()
45 | }
46 |
47 | private fun configureLedSwitch() {
48 | findViewById(R.id.redLedSwitch).setOnCheckedChangeListener { _: CompoundButton, b: Boolean ->
49 | sendPostLed(b)
50 | }
51 | }
52 |
53 | private fun sendPostLed(status: Boolean) {
54 | val ledValue = LedValue()
55 | ledValue.status = status
56 | apiService.setLedValue(ledValue).enqueue(object: Callback {
57 | override fun onFailure(call: Call?, t: Throwable?) {
58 | Log.e("MainActivity", t.toString())
59 | }
60 |
61 | override fun onResponse(call: Call?, response: Response?) {
62 | // All good
63 | }
64 | })
65 | }
66 |
67 | private fun configureTemperatureReading() {
68 | handler.post(object : Runnable {
69 | override fun run() {
70 | updateTemperature()
71 | handler.postDelayed(this, 1000)
72 | }
73 | })
74 | }
75 |
76 | private fun updateTemperature() {
77 | val result = apiService.getTemperature().enqueue (object: Callback {
78 | override fun onFailure(call: Call?, t: Throwable?) {
79 | Log.e("MainActivity", t.toString())
80 | }
81 |
82 | override fun onResponse(call: Call?, response: Response?) {
83 | runOnUiThread {
84 | findViewById(R.id.temperatureValue).text = response!!.body()!!.temperature.toString()
85 | }
86 | }
87 | })
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/java/com/plattysoft/api/mobile/TemperatureResponse.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.api.mobile
2 |
3 | import com.google.gson.annotations.SerializedName
4 |
5 | class TemperatureResponse {
6 | @SerializedName("temperature")
7 | val temperature: Double = 0.0
8 | }
9 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/java/com/plattysoft/api/mobile/ThingsApi.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.api.mobile
2 |
3 | import retrofit2.Call
4 | import retrofit2.http.Body
5 | import retrofit2.http.GET
6 | import retrofit2.http.POST
7 |
8 | /**
9 | * Created by Raul Portales on 13/06/18.
10 | */
11 | interface ThingsApi {
12 |
13 | @GET("/temperature")
14 | fun getTemperature() : Call
15 |
16 | @POST("/led")
17 | fun setLedValue(@Body ledValue: LedValue): Call
18 | }
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
27 |
28 |
38 |
39 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-api-mobile/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-api-mobile/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-api-mobile/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-api-mobile/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-api-mobile/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-api-mobile/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-api-mobile/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-api-mobile/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-api-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-api-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | api-mobile
3 | Temperature:
4 | Red LED
5 |
6 |
--------------------------------------------------------------------------------
/chapter7-api-mobile/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/chapter7-api-things/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter7-api-things/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion 27
6 |
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.api.things"
10 | minSdkVersion 27
11 | targetSdkVersion 27
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | implementation 'com.android.support:support-v4:27.1.1'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
34 | compileOnly 'com.google.android.things:androidthings:+'
35 | implementation 'com.google.android.things.contrib:driver-rainbowhat:+'
36 | implementation 'org.nanohttpd:nanohttpd:2.2.0'
37 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
38 | }
39 |
--------------------------------------------------------------------------------
/chapter7-api-things/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter7-api-things/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/chapter7-api-things/src/main/java/com/plattysoft/api/things/ApiListener.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.api.things
2 |
3 | import org.json.JSONObject
4 |
5 | interface ApiListener {
6 |
7 | fun onGetTemperature(): JSONObject
8 |
9 | fun onPostLed(request: JSONObject)
10 | }
11 |
--------------------------------------------------------------------------------
/chapter7-api-things/src/main/java/com/plattysoft/api/things/ApiServer.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.api.things
2 |
3 | import fi.iki.elonen.NanoHTTPD
4 | import org.json.JSONObject
5 |
6 | class ApiServer(private val listener: ApiListener) : NanoHTTPD(8080) {
7 |
8 | init {
9 | start(NanoHTTPD.SOCKET_READ_TIMEOUT, false)
10 | }
11 |
12 | override fun serve(session: IHTTPSession): Response {
13 | val path = session.uri
14 | val method = session.method
15 |
16 | if (method === Method.GET && path == "/temperature") {
17 | val response = listener.onGetTemperature()
18 | return newFixedLengthResponse(response.toString())
19 | }
20 | else if (method === Method.POST && path == "/led") {
21 | val request = getBodyAsJson(session)
22 | listener.onPostLed(request)
23 | return newFixedLengthResponse("")
24 | }
25 | return newFixedLengthResponse(Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "Error 404, file not found.")
26 | }
27 |
28 | private fun getBodyAsJson(session: NanoHTTPD.IHTTPSession): JSONObject {
29 | val files = HashMap()
30 | session.parseBody(files)
31 | var content = files["postData"]
32 | return JSONObject(content)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/chapter7-api-things/src/main/java/com/plattysoft/api/things/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.api.things
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import com.google.android.things.contrib.driver.bmx280.Bmx280
6 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
7 | import com.google.android.things.pio.Gpio
8 | import org.json.JSONObject
9 |
10 | class MainActivity : Activity(), ApiListener {
11 |
12 | lateinit var redLed: Gpio
13 | lateinit var temperatureSensor: Bmx280
14 |
15 | lateinit var apiServer: ApiServer
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 |
20 | redLed = RainbowHat.openLedRed()
21 |
22 | temperatureSensor = RainbowHat.openSensor()
23 | temperatureSensor.setMode(Bmx280.MODE_NORMAL)
24 | temperatureSensor.temperatureOversampling = Bmx280.OVERSAMPLING_1X
25 |
26 | apiServer = ApiServer(this)
27 | }
28 |
29 | override fun onDestroy() {
30 | super.onDestroy()
31 | apiServer.stop()
32 | redLed.close()
33 | temperatureSensor.close()
34 | }
35 |
36 | override fun onGetTemperature(): JSONObject {
37 | val response = JSONObject()
38 | val value = temperatureSensor.readTemperature().toDouble()
39 | response.put("temperature", value)
40 | return response
41 | }
42 |
43 | override fun onPostLed(request: JSONObject) {
44 | val status = request.get("status") as Boolean
45 | redLed.value = status
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/chapter7-api-things/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | api-things
3 |
4 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 |
5 | android {
6 | compileSdkVersion 26
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.firebase.mobile"
10 | minSdkVersion 26
11 | targetSdkVersion 26
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
31 | implementation 'com.android.support:appcompat-v7:26.1.0'
32 |
33 | testImplementation 'junit:junit:4.12'
34 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
35 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
36 |
37 | implementation 'com.google.firebase:firebase-core:16.0.0'
38 | implementation 'com.google.firebase:firebase-database:16.0.1'
39 | }
40 |
41 | apply plugin: 'com.google.gms.google-services'
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "529784314078",
4 | "firebase_url": "https://androidthingsquickstartguide.firebaseio.com",
5 | "project_id": "androidthingsquickstartguide",
6 | "storage_bucket": "androidthingsquickstartguide.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:529784314078:android:e462098bb7288f82",
12 | "android_client_info": {
13 | "package_name": "com.plattysoft.firebase.mobile"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "529784314078-jdflrt6cjcjh5oslbv5aevqeoptbqb7o.apps.googleusercontent.com",
19 | "client_type": 3
20 | }
21 | ],
22 | "api_key": [
23 | {
24 | "current_key": "AIzaSyDKBhkGIQtqSBL0wGIUi30NQH94vF2Mqz0"
25 | }
26 | ],
27 | "services": {
28 | "analytics_service": {
29 | "status": 1
30 | },
31 | "appinvite_service": {
32 | "status": 1,
33 | "other_platform_oauth_client": []
34 | },
35 | "ads_service": {
36 | "status": 2
37 | }
38 | }
39 | },
40 | {
41 | "client_info": {
42 | "mobilesdk_app_id": "1:529784314078:android:81ab44fc52d461a0",
43 | "android_client_info": {
44 | "package_name": "com.plattysoft.firebase.things"
45 | }
46 | },
47 | "oauth_client": [
48 | {
49 | "client_id": "529784314078-jdflrt6cjcjh5oslbv5aevqeoptbqb7o.apps.googleusercontent.com",
50 | "client_type": 3
51 | }
52 | ],
53 | "api_key": [
54 | {
55 | "current_key": "AIzaSyDKBhkGIQtqSBL0wGIUi30NQH94vF2Mqz0"
56 | }
57 | ],
58 | "services": {
59 | "analytics_service": {
60 | "status": 1
61 | },
62 | "appinvite_service": {
63 | "status": 1,
64 | "other_platform_oauth_client": []
65 | },
66 | "ads_service": {
67 | "status": 2
68 | }
69 | }
70 | }
71 | ],
72 | "configuration_version": "1"
73 | }
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/java/com/plattysoft/firebase/mobile/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.firebase.mobile
2 |
3 | import android.support.v7.app.AppCompatActivity
4 | import android.os.Bundle
5 | import android.widget.CompoundButton
6 | import com.google.firebase.FirebaseApp
7 | import com.google.firebase.database.*
8 | import kotlinx.android.synthetic.main.activity_main.*
9 |
10 | class MainActivity : AppCompatActivity() {
11 |
12 | private lateinit var firebaseReference: DatabaseReference
13 |
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | setContentView(R.layout.activity_main)
17 |
18 | FirebaseApp.initializeApp(this)
19 | val database = FirebaseDatabase.getInstance()
20 | firebaseReference = database.getReference()
21 |
22 | redLedSwitch.setOnCheckedChangeListener {
23 | compoundButton: CompoundButton, b: Boolean ->
24 | firebaseReference.child("redLED").setValue(b)
25 | }
26 |
27 | firebaseReference.child("temperature").addValueEventListener(object: ValueEventListener {
28 | override fun onDataChange(snapshot: DataSnapshot) {
29 | runOnUiThread {
30 | val temperature = snapshot.getValue(Double::class.java)
31 | temperatureValue.text = temperature.toString()
32 | }
33 | }
34 | override fun onCancelled(p0: DatabaseError) {
35 | // Nothing to do here
36 | }
37 | })
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
27 |
28 |
38 |
39 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-firebase-mobile/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-firebase-mobile/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-firebase-mobile/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-firebase-mobile/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-firebase-mobile/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-firebase-mobile/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-firebase-mobile/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-firebase-mobile/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-firebase-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-firebase-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | firebase-mobile
3 | Red LED
4 | Temperature:
5 |
6 |
--------------------------------------------------------------------------------
/chapter7-firebase-mobile/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/chapter7-firebase-things/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter7-firebase-things/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | android {
5 | compileSdkVersion 27
6 |
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.firebase.things"
10 | minSdkVersion 27
11 | targetSdkVersion 27
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | testImplementation 'junit:junit:4.12'
31 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
32 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
33 | compileOnly 'com.google.android.things:androidthings:+'
34 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
35 |
36 | implementation 'com.google.android.things.contrib:driver-rainbowhat:+'
37 |
38 | implementation 'com.google.firebase:firebase-core:16.0.0'
39 | implementation 'com.google.firebase:firebase-database:16.0.1'
40 | }
41 |
42 | apply plugin: 'com.google.gms.google-services'
--------------------------------------------------------------------------------
/chapter7-firebase-things/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "529784314078",
4 | "firebase_url": "https://androidthingsquickstartguide.firebaseio.com",
5 | "project_id": "androidthingsquickstartguide",
6 | "storage_bucket": "androidthingsquickstartguide.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:529784314078:android:e462098bb7288f82",
12 | "android_client_info": {
13 | "package_name": "com.plattysoft.firebase.mobile"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "529784314078-jdflrt6cjcjh5oslbv5aevqeoptbqb7o.apps.googleusercontent.com",
19 | "client_type": 3
20 | }
21 | ],
22 | "api_key": [
23 | {
24 | "current_key": "AIzaSyDKBhkGIQtqSBL0wGIUi30NQH94vF2Mqz0"
25 | }
26 | ],
27 | "services": {
28 | "analytics_service": {
29 | "status": 1
30 | },
31 | "appinvite_service": {
32 | "status": 1,
33 | "other_platform_oauth_client": []
34 | },
35 | "ads_service": {
36 | "status": 2
37 | }
38 | }
39 | },
40 | {
41 | "client_info": {
42 | "mobilesdk_app_id": "1:529784314078:android:81ab44fc52d461a0",
43 | "android_client_info": {
44 | "package_name": "com.plattysoft.firebase.things"
45 | }
46 | },
47 | "oauth_client": [
48 | {
49 | "client_id": "529784314078-jdflrt6cjcjh5oslbv5aevqeoptbqb7o.apps.googleusercontent.com",
50 | "client_type": 3
51 | }
52 | ],
53 | "api_key": [
54 | {
55 | "current_key": "AIzaSyDKBhkGIQtqSBL0wGIUi30NQH94vF2Mqz0"
56 | }
57 | ],
58 | "services": {
59 | "analytics_service": {
60 | "status": 1
61 | },
62 | "appinvite_service": {
63 | "status": 1,
64 | "other_platform_oauth_client": []
65 | },
66 | "ads_service": {
67 | "status": 2
68 | }
69 | }
70 | }
71 | ],
72 | "configuration_version": "1"
73 | }
--------------------------------------------------------------------------------
/chapter7-firebase-things/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter7-firebase-things/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/chapter7-firebase-things/src/main/java/com/plattysoft/firebase/things/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.firebase.things
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import com.google.android.things.contrib.driver.bmx280.Bmx280
7 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
8 | import com.google.android.things.pio.Gpio
9 | import com.google.firebase.FirebaseApp
10 | import com.google.firebase.database.*
11 |
12 | class MainActivity : Activity() {
13 |
14 | private lateinit var redLed: Gpio
15 | private lateinit var temperatureSensor: Bmx280
16 |
17 | private lateinit var firebaseReference: DatabaseReference
18 |
19 | private val handler = Handler()
20 |
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | super.onCreate(savedInstanceState)
23 | FirebaseApp.initializeApp(this)
24 | val database = FirebaseDatabase.getInstance()
25 | firebaseReference = database.getReference()
26 |
27 | redLed = RainbowHat.openLedRed()
28 |
29 | temperatureSensor = RainbowHat.openSensor()
30 | temperatureSensor.setMode(Bmx280.MODE_NORMAL)
31 | temperatureSensor.temperatureOversampling = Bmx280.OVERSAMPLING_1X
32 |
33 | configureTemperatureReading()
34 | configureLedSwitch()
35 | }
36 |
37 | override fun onDestroy() {
38 | super.onDestroy()
39 | redLed.close()
40 | temperatureSensor.close()
41 | }
42 |
43 | private fun configureTemperatureReading() {
44 | handler.post(object : Runnable {
45 | override fun run() {
46 | val temperature = temperatureSensor.readTemperature()
47 | firebaseReference.child("temperature").setValue(temperature)
48 | handler.postDelayed(this, 1000)
49 | }
50 | })
51 | }
52 |
53 | private fun configureLedSwitch() {
54 | firebaseReference.child("redLED").addValueEventListener(
55 | object : ValueEventListener {
56 | override fun onCancelled(p0: DatabaseError) {
57 | // Nothing to do here
58 | }
59 |
60 | override fun onDataChange(snapshot: DataSnapshot) {
61 | val redLedState = snapshot.getValue(Boolean::class.java)
62 | if (redLedState != null) {
63 | redLed.value = redLedState
64 | }
65 | }
66 | })
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/chapter7-firebase-things/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | firebase-things
3 |
4 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 |
5 | android {
6 | compileSdkVersion 26
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.nearby.mobile"
10 | minSdkVersion 26
11 | targetSdkVersion 26
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
31 | testImplementation 'junit:junit:4.12'
32 | implementation 'com.android.support:appcompat-v7:26.1.0'
33 | implementation 'com.google.android.gms:play-services-nearby:15.0.1'
34 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
35 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
36 | }
37 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/java/com/plattysoft/nearby/mobile/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.nearby.mobile
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.util.Log
6 | import android.widget.CompoundButton
7 | import android.widget.Switch
8 | import android.widget.TextView
9 | import com.google.android.gms.nearby.Nearby
10 | import com.google.android.gms.nearby.connection.*
11 | import com.google.android.gms.nearby.connection.ConnectionsStatusCodes.STATUS_OK
12 | import org.json.JSONObject
13 |
14 | class MainActivity : Activity() {
15 |
16 | companion object {
17 | private val TAG = MainActivity::class.java.simpleName
18 |
19 | private const val SERVICE_ID = "com.plattysoft.nearby"
20 | private const val NICKNAME = "IoT Phone" // This could be the device ID
21 | private val STRATEGY = Strategy.P2P_STAR
22 | }
23 |
24 | lateinit var nearbyConnection : ConnectionsClient
25 | private var connectedEndpoint: String? = null
26 |
27 | private val endpointDiscoveryCallback = object : EndpointDiscoveryCallback() {
28 | override fun onEndpointFound(endpointId: String, discoveredEndpointInfo: DiscoveredEndpointInfo) {
29 | connectToEndpoint(endpointId)
30 | }
31 | override fun onEndpointLost(endpointId: String) {
32 | // A previously discovered endpoint has gone away.
33 | }
34 | }
35 |
36 | private val connectionLifecycleCallback = object : ConnectionLifecycleCallback(){
37 | override fun onConnectionResult(endpointId: String, result: ConnectionResolution) {
38 | if (result.status.statusCode == STATUS_OK) {
39 | connectedEndpoint = endpointId
40 | }
41 | }
42 | override fun onDisconnected(endpointId: String) {
43 | if (endpointId.equals(connectedEndpoint)) {
44 | connectedEndpoint = null
45 | }
46 | }
47 | override fun onConnectionInitiated(endpointId: String, connectionInfo: ConnectionInfo) {
48 | nearbyConnection.acceptConnection(endpointId, payloadCallback)
49 | }
50 | }
51 |
52 | private val payloadCallback = object: PayloadCallback() {
53 | override fun onPayloadReceived(p0: String, payload: Payload) {
54 | // Info about the temperature
55 | val json = payload.getAsJson()
56 | runOnUiThread {
57 | val value = json.getDouble("temperature").toString()
58 | findViewById(R.id.temperatureValue).text = value
59 | }
60 | }
61 |
62 | override fun onPayloadTransferUpdate(p0: String, p1: PayloadTransferUpdate) {
63 | // Nothing to do here
64 | }
65 | }
66 |
67 | override fun onCreate(savedInstanceState: Bundle?) {
68 | super.onCreate(savedInstanceState)
69 | setContentView(R.layout.activity_main)
70 | nearbyConnection = Nearby.getConnectionsClient(this)
71 | startDiscovery()
72 | findViewById(R.id.redLedSwitch).setOnCheckedChangeListener { compoundButton: CompoundButton, status: Boolean ->
73 | if (connectedEndpoint != null) {
74 | val jsonObject = JSONObject()
75 | jsonObject.put("status", status)
76 | nearbyConnection.sendPayload(connectedEndpoint!!, Payload.fromBytes(jsonObject.toString().toByteArray()))
77 | }
78 | }
79 | }
80 |
81 | override fun onDestroy() {
82 | super.onDestroy()
83 | nearbyConnection.stopDiscovery()
84 | }
85 |
86 | private fun connectToEndpoint(endpointId: String) {
87 | nearbyConnection.requestConnection(
88 | NICKNAME,
89 | endpointId,
90 | connectionLifecycleCallback)
91 | }
92 |
93 | private fun startDiscovery() {
94 | nearbyConnection.startDiscovery(
95 | SERVICE_ID,
96 | endpointDiscoveryCallback,
97 | DiscoveryOptions.Builder().setStrategy(STRATEGY).build())
98 | .addOnFailureListener {
99 | Log.e(TAG, "onFailure: "+it.localizedMessage)
100 | }
101 | .addOnSuccessListener {
102 | Log.e(TAG, "Discovering...")
103 | }
104 | }
105 |
106 | private fun Payload.getAsJson(): JSONObject {
107 | val string = String(this.asBytes()!!)
108 | return JSONObject(string)
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
27 |
28 |
38 |
39 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-nearby-mobile/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-nearby-mobile/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-nearby-mobile/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-nearby-mobile/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-nearby-mobile/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-nearby-mobile/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-nearby-mobile/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-nearby-mobile/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-nearby-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/chapter7-nearby-mobile/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | nearby-mobile
3 | Red LED
4 | Temperature:
5 |
6 |
--------------------------------------------------------------------------------
/chapter7-nearby-mobile/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/chapter7-nearby-things/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chapter7-nearby-things/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 |
5 | android {
6 | compileSdkVersion 27
7 |
8 | defaultConfig {
9 | applicationId "com.plattysoft.nearby.rhings"
10 | minSdkVersion 27
11 | targetSdkVersion 27
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: 'libs', include: ['*.jar'])
30 | implementation 'com.android.support:support-v4:27.1.1'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
34 | compileOnly 'com.google.android.things:androidthings:+'
35 | implementation 'com.google.android.things.contrib:driver-rainbowhat:+'
36 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
37 | implementation 'com.google.android.gms:play-services-nearby:15.0.1'
38 | }
--------------------------------------------------------------------------------
/chapter7-nearby-things/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/chapter7-nearby-things/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/chapter7-nearby-things/src/main/java/com/plattysoft/nearby/things/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.plattysoft.nearby.things
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import android.util.Log
7 | import com.google.android.gms.nearby.Nearby
8 | import com.google.android.gms.nearby.connection.*
9 | import com.google.android.gms.nearby.connection.ConnectionsStatusCodes.STATUS_OK
10 | import com.google.android.things.contrib.driver.bmx280.Bmx280
11 | import com.google.android.things.contrib.driver.rainbowhat.RainbowHat
12 | import com.google.android.things.pio.Gpio
13 | import org.json.JSONObject
14 |
15 | class MainActivity : Activity() {
16 | companion object {
17 | private val TAG = MainActivity::class.java.simpleName
18 |
19 | private const val SERVICE_ID = "com.plattysoft.nearby"
20 | private const val NICKNAME = "IoT Temp Sensor"
21 | private val STRATEGY = Strategy.P2P_STAR
22 | }
23 |
24 | private lateinit var temperatureSensor: Bmx280
25 | private lateinit var redLed: Gpio
26 |
27 | private lateinit var nearbyConnections: ConnectionsClient
28 |
29 | private var connectedEndpoint: String? = null
30 | private val handler = Handler()
31 |
32 | private val payloadCallback= object: PayloadCallback() {
33 | override fun onPayloadReceived(p0: String, p1: Payload) {
34 | // I have received something
35 | val jsonObject = p1.getAsJson()
36 | val redLedStatus = jsonObject.getBoolean("status")
37 | redLed.value = redLedStatus
38 | }
39 |
40 | override fun onPayloadTransferUpdate(p0: String, p1: PayloadTransferUpdate) {
41 | }
42 | }
43 |
44 | private val connectionLifecycleCallback= object : ConnectionLifecycleCallback (){
45 | override fun onConnectionResult(endpointId: String, result: ConnectionResolution) {
46 | if (result.status.statusCode == STATUS_OK) {
47 | connectedEndpoint = endpointId
48 | }
49 | }
50 | override fun onDisconnected(endpointId: String) {
51 | if (endpointId.equals(connectedEndpoint)) {
52 | connectedEndpoint = null
53 | }
54 | }
55 | override fun onConnectionInitiated(endpointId: String, connectionInfo: ConnectionInfo) {
56 | nearbyConnections.acceptConnection(endpointId, payloadCallback)
57 | }
58 | }
59 |
60 | override fun onCreate(savedInstanceState: Bundle?) {
61 | super.onCreate(savedInstanceState)
62 |
63 | nearbyConnections = Nearby.getConnectionsClient(this)
64 |
65 | startAdvertising()
66 |
67 | redLed = RainbowHat.openLedRed()
68 |
69 | temperatureSensor = RainbowHat.openSensor()
70 | temperatureSensor.setMode(Bmx280.MODE_NORMAL)
71 | temperatureSensor.temperatureOversampling = Bmx280.OVERSAMPLING_1X
72 |
73 | handler.post(object: Runnable {
74 | override fun run() {
75 | val temp = temperatureSensor.readTemperature()
76 | Log.d(TAG, "Temperature: "+temp.toDouble())
77 | if (connectedEndpoint != null) {
78 | sendTemperatureToNearby(temp)
79 | }
80 | handler.postDelayed(this, 1000)
81 | }
82 | })
83 | }
84 |
85 | private fun sendTemperatureToNearby(temp: Float) {
86 | val json = JSONObject()
87 | json.put("temperature", temp)
88 | val payload = Payload.fromBytes(json.toString().toByteArray())
89 | nearbyConnections.sendPayload(connectedEndpoint!!, payload)
90 | }
91 |
92 | private fun startAdvertising() {
93 | nearbyConnections.startAdvertising(
94 | NICKNAME,
95 | SERVICE_ID,
96 | connectionLifecycleCallback,
97 | AdvertisingOptions.Builder().setStrategy(STRATEGY).build())
98 | .addOnSuccessListener {
99 | Log.e(TAG, "Advertising...")
100 | }
101 | .addOnFailureListener {
102 | Log.e(TAG, "onFailure: "+it.localizedMessage)
103 | }
104 | }
105 |
106 | override fun onDestroy() {
107 | super.onDestroy()
108 | temperatureSensor.close()
109 | redLed.close()
110 | nearbyConnections.stopAdvertising()
111 | }
112 | }
113 |
114 | private fun Payload.getAsJson(): JSONObject {
115 | val string = String(this.asBytes()!!)
116 | return JSONObject(string)
117 | }
118 |
--------------------------------------------------------------------------------
/chapter7-nearby-things/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | nearby-things
3 |
4 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Android-Things-Quick-Start-Guide/62344e949cf1103889086a844de24fa2830db7f6/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 25 23:13:36 IST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':chapter1', ':chapter2-RainbowHAT', ':chapter3-gpio', ':chapter4-pwm', ':chapter5-i2c', ':chapter6-spi', ':chapter7-android-ui', ':chapter7-api-mobile', ':chapter7-api-things', ':chapter7-firebase-mobile', ':chapter7-firebase-things', ':chapter7-nearby-mobile', ':chapter7-nearby-things'
--------------------------------------------------------------------------------