You are on page 1of 21

IT FOCUS ON DEVELOPMENT

GETTING STARTED
WITH ANDROID THINGS
DEVELOPMENT

codeguru <HTMLGOODIES/>
TM

INFOSTOR
®
CONTENTS
W hether you are a professional device creator seeking reference materials, or a hobbyist looking for an introduction
to the Android Things API, this guide is sure to help.

Android Things is an Android-based OS that supports new embedded single board computer like the Raspberry Pi 3 and
introduces a new set of Hardware APIs to access GPIO, SPI, I2C, PWM and UART peripherals. Android Things development
is very similar to traditional Android mobile development in that apps are written using the Android framework and tools.
To get started, all you need is a development board flashed with the Android Things OS and the required peripherals for
your device. Making the jump from Android mobile development to Android Things is not difficult, since basic concepts
and general coding practices of core Android development transfer over nicely to Android Things development.

This guide gives you all the information you need to get started quickly with a supported board. Youll learn how to set
up your initial development environment and how to start writing apps for Android Things. If you’ve never developed
an Android Things app, start by following the Getting Started with Android Things Development tutorial. Here’s the
full list of tutorials covered in this eBook:

02‹
Getting Started with Android Things Development
This section will get you started with Android Things and show you how to set up the required hardware
and software. You will learn how to set up the Android Things operating system and connect your
device to a Raspberry Pi 3 processor board and peripherals.

05‹
Building an Android Things Application
Having set up your device and tools, you’ll now learn how to build a simple application that controls an
LED on our board.

10‹
Handling Android Things Peripheral Events
Continuing with your development, in this section you will learn to use the Peripheral Driver Library.
You will see how to control an LED via a button click as well as learn about using the Peripheral Driver
Library to control an astounding array of peripheral devices including buttons, temperature readers,
speakers, and handheld GPSes.

14‹
How to Run Google Assistant on Android Things Using the Any Voice Kit
Next, you’ll learn how you can run Android Things on the Voice Kit launched by AIY Projets and Google.
This will include the ability to fully integrate with the Google Assistant SDK. You will see how the various
components fit together by building the Google Assistant API sample for Android Things.

17‹
Configure the Google Assistant API to Develop
Android Things Apps for the AIY Voice Kit
Finally, you’ll learn how to configure the Google API Project you’ve built so that you can converse with
Google Assistant.

About the Author: Rob Gravelle resides in Ottawa, Canada, and has built Web applications for numerous businesses and
government agencies. Email him for a quote on your project.

Rob’s alter-ego, “Blackjacques,” is an accomplished guitar player, who has released several CDs. His band, Ivory Knight, was
rated as one of Canada’s top hard rock and metal groups by Brave Words magazine (issue #92) and reached the #1 spot in
the National Heavy Metal charts on ReverbNation.com.
Getting Started with Android Things Development
T he Internet of Things (IoT for short) is a phrase used
to describe the connecting of electronic devices over
the Internet that participate together on a system. In many
• Intel Joule: Intel’s highest-performing system-on-
module, packs powerful computing capabilities in
a thumb-sized, low-power package. The Intel Joule
cases, people also need to communicate with devices 550x/570x developer kit enables developers to rapidly
via their smartphones, tablets, and even watches. That’s prototype all manner of autonomous robots and
IoT applications requiring computer vision or edge
where Android Things comes in. Launched by Google on
processing. Price: approx. $340.00 USD
13 December 2016, Android Things is an Android-based
OS for the Internet of Things that can run on products like • NXP i.MX6UL: Expanding the i.MX 6 series,
connected speakers, smart thermostats, security cameras, the i.MX 6UltraLite is a high performance, and
routers, and many other devices. This tutorial will get you ultra-efficient processor family featuring an advanced
started with Android Things and show you how to set up implementation of a single ARM Cortex-A7 core. The
the required hardware and software. Pico variant is pin-compatible with the Intel Edison for
sensors and low-speed I/O, but also adds additional
What You’ll Need expansion possibilities for multimedia and connectivity,
providing cutting edge technology that can easily be
Before you can begin programming for Android Things, expanded and implemented for IoT designs. Price:
you’ll need to set up a physical development board approx. $70.00 USD
flashed with the Android Things OS and the required
peripherals for your device. There are currently several • Raspberry Pi 3: Raspberry Pi 3 Model B is the latest
options for boards: iteration of the world’s most popular single board
computer. It provides a quad-core 64-bit ARM
• Intel Edison: A small and powerful System on a Chip Cortex-A53 CPU running at 1.2GHz, four USB 2.0 ports,
(SoC) that includes a CPU, MCU, memory, storage, and wired and wireless networking, HDMI and composite
dual-band Wi-Fi and Bluetooth. The module can be video output, and a 40-pin GPIO connector for physical
mounted onto a system of expansion boards, enabling interfacing projects. Price: aprox. $40.00 USD ($60.00
the quick prototyping of light IoT applications. Price: for the development kit)
approx. $49.95 USD

2
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

For this tutorial, we’ll be using the Adafruit Project Kit intended to produce a computer that would run only
with Raspberry Pi, because it’s the most popular and the Python.
cheapest of the preceding choices. The Project Kit comes
equipped with all of the peripherals that you’ll need, Flashing the Image
including sensors, jumper wires, and resistors.
To put Android Things on the Raspberry Pi, you’ll need
the following additional general purpose items:

• HDMI cable and a display (such as a computer monitor)

• Ethernet cable connected to your Internet

• Micro-USB cable

• Micro SD card with at least 8GB of space, and an SD


card adapter

• A computer that can read and write to an SD card

Once you have all of the required components, you


will need to download the latest system image for the
Raspberry Pi from the Google Android Things System
Image Downloads page.
Figure 1: The Adafruit Project Kit with Raspberry Pi
You will need to unzip the downloaded file to retrieve the
.img file. Some programs, such as the standard Archive
Origins and Terminology Explained Utility on OS X, may have a problem unzipping, due to
the large size of the file. If that happens, you can install
In the processor description above, you’ll see a reference
Unarchiver for OS X or 7-Zip for Windows to extract the
to the “GPIO connector.” GPIO stands for “General
file properly.
Purpose Input/Output.” It contains ports for sensors,
LED, button and other thingamagigs. The peripheral I/O You’ll then have to place the .img file on your SD card.
lets you control the current state of those LED, buttons, This process will vary for each operating system. This
and sensors programmatically or according to some tutorial will cover the process on Windows. You can find
user action, such as pressing a button. They also notify the instructions for Mac OSX and Linux here.
you about the state changes, so that you can tell the
Peripheral I/O to switch on the LED or what-have-you. Operating System Image Windows Installation

The Raspberry Pi 3 processor also supports Pulse Width Follow these steps in order:
Modulation (PWM). This API is utilized for interacting
with servo motors, DC motors, and lights that require a 1. Insert the SD card into your SD card reader. You can
use the SD card slot if you have one, or an SD adapter
proportional signal to provide fine-grained control over
in a USB port. Note the drive letter assigned to the
the output.
SD card. You can see the drive letter in the left hand
column of Windows Explorer, for example “F:”
Some quick trivia: The Pi in “Raspberry Pi” stands for
“Python,” due to the fact that the manufacturer originally

3
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

You are now ready to plug the card into your Raspberry Pi.
Connect your Raspberry Pi to your display via the HDMI cable,
to your network with an Ethernet cable, and to a power source
(such as your computer) with the micro USB type-B cable.

Once your Raspberry Pi has booted, you should see the


following welcome screen on your display:
At this point, you will be able to connect to your newly
flashed Android Things board and load apps onto it. This
is the topic of the next article.

Figure 2: Mounting the SD card


2. Download the Win32DiskImager utility from the
Sourceforge Project page as an installer file, and run it
to install the software. Figure 4: The Android Things welcome screen

3. Run the Win32DiskImager utility from your desktop or menu.


Coding in Android Things

To give you a taste for what Android Things code looks


like, here is a snippet that lists available peripherals. The
system service responsible for managing peripheral
connections is called PeripheralManagerService. You
can use this service to list the available ports for all
known peripheral types. For instance, the following code
outputs the list of available GPIO ports to logcat:

public class HomeActivity extends Activity {


Figure 3: Running the Win32DiskImager utility private static final String TAG = “HomeActivity”;
@Override
4. Select the image file you extracted earlier. protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
5. Select the drive letter of the SD card in the device box. Be
PeripheralManagerService service = new
careful to select the correct drive because choosing the
PeripheralManagerService();
wrong drive could destroy the data on your computer’s
Log.d(TAG, “Available GPIO: “ +
hard disk! (No stress.) If you are using an SD card slot in your
service.getGpioList());
computer and can’t see the drive in the Win32DiskImager
window, try using an external SD adapter. }
}
6. Click ‘Write’ and wait for the operation to complete. Conclusion
In the next tutorial, we’ll write a basic Android Things
7. Exit the imager and eject the SD card.
application that communicates with our board.

4
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
Building an Android Things Application
A ndroid Things is the new platform from Google for
creating Internet of Things (IoT) connected devices.
It’s an easy way to develop IoT applications using the
•• jumper wires

•• LED

•• button
skills that you have already acquired programming for the
Android OS. In the “Getting Started with Android Things •• a 10k Ω resistor (color bands brown, black, orange)
Development” tutorial, we learned how to set up the •• a 470 Ω resistor (color bands yellow, violet, brown)
Android Things OS and connect your device to a Raspberry
• HDMI, Ethernet, and micro USB type-B cables to
Pi 3 processor board and peripherals. In a follow up article,
connect to your your display, network, and power-
you’ll learn how build a simple application that controls
source (such as your computer), respectively
an LED on our board. In a future installment, you’ll learn
how to connect the LED to a button’s KeyUp and KeyDown Here’s the wiring diagram that shows how all of the
events. components fit together. Consult your kit details for
further instructions:
Equipment Checklist

Just as you wouldn’t climb Mount Everest without all of


the necessary gear, you can’t program for IoT devices
without some hardware. There’s a good chance that
emulators will spring up eventually, but it’s a little too
soon for that yet. Here’s what you’ll need:

• a flashed Raspberry Pi 3 board

• peripherals, including:

•• breadboard

•• resistor Figure 1: Circuit board diagram

5
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

Create an Empty Android Project

All of this coding with take place within Android Studio,


so be sure to launch it before proceeding any further.

1. The first order of business will be to create a new empty


project. Select File > New > New Project... to fire up
the Project Wizard.

2. On the New Project screen, give your project a name


and company domain; set the location; then, click Next.

Figure 3: Empty activity project

5. There is no need to Customize the Activity, so leave


that screen as is and press the Finish button to create
the new project.

Supporting an Android Things Application

You now have an Android project, but not an Android


Things project. Because Android Studio can be utilized for
any Android-based device, you will need to specify that
your application applies specifically to Android Things:
Figure 2: New project details
1. Open the build.gradle file under the app folder. Inside
3. Accept the defaults on the Target Android Devices the dependencies block, include the Android Things
screen and click Next. library:

4. On the Activity screen, make sure that the “Empty provided ‘com.google.android.things:
Activity” is selected; then, press Next. androidthings:0.3-devpreview’

6
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

2. Open the AndroidManifest.xml file. You will need to


declare that your app uses the Android Things library
by adding the following uses-library statement within
the application node:

<application
android:allowBackup=”true”
android:icon=”@mipmap/ic_launcher”
android:label=”@string/app_name”
android:roundIcon=”@mipmap/ic_launcher_round” Figure 4: The MainActivity class
android:supportsRtl=”true”
android:theme=”@style/AppTheme” >
2. Inside onCreate(), store a reference to the
PeripheralManagerService class in a local variable
<!-- add this line: -->
called service. It’s the object that will instantiate our
<uses-library android:name=
input and output connections.
“com.google.android.things”/>
<activity android:name=”.MainActivity”>
PeripheralManagerService service =
...
new PeripheralManagerService();

3. While still in the manifest file, add an intent-filter to your 3. You can use the PeripheralManagerService to fetch the
MainActivity node that tells your device to launch this name of each pin on your board. Earlier, you wired all
Activity on startup: of the components together to the board using specific
pins. To control the peripherals that are attached
<activity android:name=”.MainActivity”>
to these pins, you will need to know their names.
<intent-filter>
You can print a list of each component by using the
<action android:name= PeripheralManagerService like this:
“android.intent.action.MAIN” />
<category android:name= @Override protected void onCreate(Bundle
“android.intent.category.LAUNCHER” /> savedInstanceState) {
</intent-filter> super.onCreate(savedInstanceState);
<intent-filter> PeripheralManagerService service =
<action android:name= new PeripheralManagerService();
“android.intent.action.MAIN”/> Log.e(“AndroidThings”, “GPIOs: “ +
<category android:name= service.getGpioList() ); }
“android.intent.category.IOT_LAUNCHER”/>
<category android:name= That should print something like the following for
“android.intent.category.DEFAULT”/> Raspberry Pi:
</intent-filter>
</activity> E/AndroidThings: GPIOs: [BCM12, BCM13, BCM16, BCM17,
BCM18, BCM19, BCM20, BCM21, BCM22, BCM23, BCM24,
The MainActivity Class BCM25, BCM26, BCM27, BCM4, BCM5, BCM6]

Now that your app supports Android Things, it’s time to 4. As illustrated by the Raspberry Pi wiring diagram, the
turn your attention to coding the MainActivity. button connects to BCM21 and the LED to BCM6. For
now, you’ll define the BCM6 value as a String constant
1. Open MainActivity.java and locate the onCreate() at the top of our Activity:
event:
private final String PIN_LED = “BCM6”;

7
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

try {
5. Basic components, such as LEDs, can be accessed
using Android Thing’s Gpio object. At the top of the mLedGpio.close();

Activity, you’ll define a Gpio object and initialize it to } catch (IOException e) {

null. This will be used to reference our connection to } finally{


the LED in the app. mLedGpio = null;
}
private Gpio mLedGpio = null; }
}
6. Now, you need to initialize the mLedGpio variable in
onCreate(). This is accomplished by calling openGpio() The Final MainActivity Class
with the pin name—in other words, “BCM6.” You
also will need to declare the initialize state of the Here is what you’ve coded so far in the MainActivity class:
component, which in this case is DIRECTION_OUT_
INITIALLY_LOW (basically “off”). I/O setup calls must package com.htmlgoodies.robgravelle.
be wrapped within a try/catch block because they myfirstandroidthingsapp;
declare an IOException throws clause:
import android.app.Activity;
@Override protected void onCreate(Bundle
import android.os.Bundle;
savedInstanceState) {
super.onCreate(savedInstanceState);
import com.google.android.things.pio.Gpio;
import com.google.android.things.pio.
PeripheralManagerService service = new
PeripheralManagerService;
PeripheralManagerService();
import android.util.Log;
try {
Log.i(TAG, “Configuring GPIO pins”);
import java.io.IOException;
mLedGpio = service.openGpio(PIN_LED);
mLedGpio.setDirection(Gpio.DIRECTION_
public class MainActivity extends Activity {
OUT_INITIALLY_LOW);
private static final String PIN_LED = “BCM6”;
private static final String TAG =
} catch (IOException e){
“AndroidThings”;
Log.e(TAG, “Error configuring GPIO pins”, e);
}
private Gpio mLedGpio = null;
}

@Override
7. You still haven’t defined the TAG constant, so add it to
protected void onCreate(Bundle savedInstanceState) {
the top of the MainActivity class, under the PIN_LED:
super.onCreate(savedInstanceState);

private static final String TAG = “AndroidThings”;


PeripheralManagerService service =

8. During the onDestroy() event, you should close all new PeripheralManagerService();
connections and nullify any hardware references: try {
Log.i(TAG, “Configuring GPIO pins”);
@Override protected void onDestroy(){ mLedGpio = service.openGpio(PIN_LED);
super.onDestroy(); mLedGpio.setDirection(Gpio.DIRECTION_OUT_
INITIALLY_LOW);
if (mLedGpio != null) {

8
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

} catch (IOException e){


Conclusion
Log.e(TAG, “Error configuring GPIO pins”, e);
} Now that you have defined and set the LED reference,
} you still need to be able to change the state of the LED
between on and off. Fortunately, Google has created a
Override set of driver libraries that make it easy to use buttons and
protected void onDestroy(){ various other components. You’ll add the code to handle
super.onDestroy(); button events in the next article.

if (mLedGpio != null) {
try {
mLedGpio.close();
} catch (IOException e) {
} finally{
mLedGpio = null;
}
}
}
}

9
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
Handling Android Things Peripheral Events
A ndroid Things apps have to communicate with an
astounding array of peripheral devices, from buttons,
temperature readers, and speakers, to handheld GPSes.
modify or fork them to handle your specific hardware
implementation.

• Integration: Android often combines data from various


Google’s Peripheral Driver Library simplifies the integration
services together to enhance the information reported
of these hardware components into your Android Things
to apps or create new virtual data sets. User drivers
apps. Available on Github, it contains numerous drivers
(see below) can contribute to this process.
for popular peripherals for supported Android Things
hardware. In this tutorial, we’ll use the Peripheral Driver Drivers are categorized into two types: Peripheral I/O and
Library to connect an LED that we set up in “Building an User Drivers.
Android Things Application” via a button click.
Peripheral I/O APIs communicate with sensors and
About the Peripheral Driver Library actuators using industry standard protocols and
interfaces. These include:
Google’s goal in creating the Peripheral Driver Library
was to simplify the integration of various hardware • General Purpose Input/Output (GPIO): An API for
components into an Android Things app. Drivers expose simple sensors such as motion detectors, proximity
a high-level API that abstracts the communication logic detectors, and level switches that report their current
and state management of each peripheral. This approach state as a binary value—high or low.
offers a few benefits, such as:
• Pulse Width Modulation (PWM): An API for
• Portability: Application code can run on a variety of servo motors, DC motors, and lights that require a
different boards and configurations without additional proportional signal to provide fine-grained control over
abstractions for the device driver implementation. the output.

• Reuse: You can pull existing Android code snippets • Serial Communication: A set of APIs to transfer larger
and libraries into your application without the need to payloads of data between two or more smart devices
connected on the same local bus.

10
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

Log.e(TAG, “Error updating LED state”, e);


Android Things introduced the concept of a user driver
}
to allow app developers to register new device drivers
}
with the Android framework. User drivers are components
registered within apps that extend existing Android
framework services. They allow any application to inject Initializing the Driver
hardware events into the framework that other apps can
Before we can use the button driver, we first must add the
process using the standard Android APIs.
driver artifact dependency to our app-level build.gradle
Drivers can be registered with the UserDriverManager file:
with the registerMyCustomDriver() call:
compile ‘com.google.android.things.contrib:driver-
button:0.3’
private MyCustomDriver mDriver;

@Override
public void onCreate() {
super.onCreate();

mDriver = new MyCustomDriver();

UserDriverManager manager =
UserDriverManager.getManager();
manager.registerMyCustomDriver( mDriver ); }

Working with the Button Driver

For this tutorial, we’re going to work with the Button Figure 1: Showing the driver button dependency
Driver. Stored in the com.google.android.things.contrib.
driver.button package, the button driver supports GPIO
buttons. We’ll use it to listen for button clicks to toggle an We then need to declare a class level ButtonInputDriver
LED on and off. object variable within the MainActivity class for future
reference:
Toggling the LED State
public class MainActivity extends Activity {
Recall from the “Building an Android Things Application” private static final String TAG =
tutorial that we saved a reference to the LED in the “AndroidThings”;
mLedGpio variable. We can use the setValue(Boolean) private static final String PIN_LED = “BCM6”;
method on the GPIO to change a component’s state (in
this case, between on and off). Add the following function private Gpio mLedGpio = null;
to the MainActivity class: private ButtonInputDriver mButtonInputDriver = null;
// ...
// This function toggles the button on and off
private void setLedState(Boolean isOn) {
A good place to instantiate and register the
try {
ButtonInputDriver instance is within the try block inside
mLedGpio.setValue(isOn);
the Activity’s onCreate() handler, immediately after the
} catch (IOException e) {
initialization of the LED pin:

11
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

// Initialize and register the InputDriver that will } catch (IOException e) {


// emit SPACE key events on GPIO state changes. Log.e(TAG, “Error closing Button driver”, e);
mButtonInputDriver = new ButtonInputDriver( } finally{
BoardDefaults.getGPIOForButton(), mButtonInputDriver = null;
Button.LogicState.PRESSED_WHEN_LOW, }
KeyEvent.KEYCODE_SPACE); }
If all goes well, the LED should now light up when we
mButtonInputDriver.register(); press the button and turn off when we release it.

Notice that we didn’t need to define a constant for the To show how everything fits together, here is the full
button GPIO as we did for the LED pin. Instead, we use source code for the MainActivity class:
BoardDefaults.getGPIOForButton() to fetch it for us.
package com.htmlgoodies.robgravelle.

The ButtonInputDriver will send button press events to myfirstandroidthingsapp;

the onKeyDown() and onKeyUp() methods with the key


code that we specified at driver creation (we’re using the import android.app.Activity;

SPACE KEY), which can be overridden in our MainActivity import android.os.Bundle;

to change the state of the LED:


import com.google.android.things.contrib.driver.button.
@Override Button;
public boolean onKeyDown(int keyCode, KeyEvent event) { import com.google.android.things.contrib.driver
if (keyCode == KeyEvent.KEYCODE_SPACE) { .button.ButtonInputDriver;
setLEDState(true); import com.google.android.things.pio.Gpio;
return true; import com.google.android.things.pio.
} PeripheralManagerService;
import android.util.Log;
return super.onKeyDown(keyCode, event); } import android.view.KeyEvent;

@Override import java.io.IOException;


public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_SPACE) { public class MainActivity extends Activity {
setLEDState(false); private static final String TAG =
return true; “AndroidThings”;
} private static final String PIN_LED = “BCM6”;

return super.onKeyUp(keyCode, event); } private Gpio mLedGpio;


private ButtonInputDriver mButtonInputDriver;
Finally, we will need to unregister our ButtonInputDriver
and set it to null in onDestroy(), much like we did with the @Override
LED in the last tutorial: protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mButtonInputDriver != null) {
mButtonInputDriver.unregister(); PeripheralManagerService service = new
try { PeripheralManagerService();
mButtonInputDriver.close(); try {

12
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

Log.i(TAG, “Configuring GPIO pins”); @Override


mLedGpio = service.openGpio(PIN_LED); protected void onDestroy(){
mLedGpio.setDirection(Gpio.DIRECTION_OUT_ super.onDestroy();
INITIALLY_LOW);
if (mLedGpio != null) {
Log.i(TAG, “Registering button driver”); try {
// Initialize and register the InputDriver mLedGpio.close();
that will } catch (IOException e) {
// emit SPACE key events on GPIO state } finally{
changes. mLedGpio = null;
mButtonInputDriver = new ButtonInputDriver( }
BoardDefaults.getGPIOForButton(), }
Button.LogicState.PRESSED_WHEN_LOW,
KeyEvent.KEYCODE_SPACE); if (mButtonInputDriver != null) {
mButtonInputDriver.unregister();
mButtonInputDriver.register(); try {
mButtonInputDriver.close();
} catch (IOException e){ } catch (IOException e) {
Log.e(TAG, “Error configuring GPIO pins”, e); Log.e(TAG, “Error closing Button driver”,
} e);
} } finally{
mButtonInputDriver = null;
@Override }
public boolean onKeyDown(int keyCode, KeyEvent }
event) { }
if (keyCode == KeyEvent.KEYCODE_SPACE) {
setLEDState(true); // This function toggles the button on and off
return true; private void setLedState(boolean isOn) {
} try {
mLedGpio.setValue(isOn);
return super.onKeyDown(keyCode, event); } catch (IOException e) {
} Log.e(TAG, “Error updating LED state”, e);
}
@Override }
public boolean onKeyUp(int keyCode, KeyEvent event) }
{
if (keyCode == KeyEvent.KEYCODE_SPACE) { Conclusion
setLEDState(false);
return true; This tutorial provided just a taste of what the Android
} Things Peripheral Driver Library can do. In the next two
articles, we’ll explore more complex examples.
return super.onKeyUp(keyCode, event);
}

13
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
How to Run Google Assistant on Android Things Using
the Any Voice Kit
I n partnership with Google, AIY Projects recently
launched a Raspberry Pi-based Voice Kit that provides
an interface to Cloud services, such as the Cloud Speech
API and new Google Assistant SDK. On their part, Google
released a special Android Things Developer Preview 3.1
build for Raspberry Pi 3 to support the Voice Kit. Now,
developers can run Android Things on the Voice Kit with
full functionality, including integration with the Google
Assistant SDK. In this tutorial, we’ll learn how all of these
various components fit together by building the Google
Assistant API sample for Android Things.

What You’ll Need Figure 1: The finished kit

output, and a 40-pin GPIO connector for physical


Don’t be intimidated by the long list. Most items are
interfacing projects.
standard for Android Things development. The main
hardware item for this tutorial is the AIY Projects Voice Kit, • AIY Projects Voice Kit: The Voice Kit originally shipped
shown in Figure 1. out to all MagPi Magazine subscribers on May 4, 2017.
The parts list, assembly instructions, source code, as
• A flashed Raspberry Pi 3 B development board: well as suggested extensions are also available on AIY
Raspberry Pi 3 Model B is the latest iteration of the Projects Web site. The complete kit is (or should be
world’s most popular single-board computer. It shortly) also for sale at over 500 North American Barnes
provides a quad-core 64-bit ARM Cortex-A53 CPU & Noble stores, as well as UK retailers WH Smith, Tesco,
running at 1.2GHz, four USB 2.0 ports, wired and Sainsburys, and Asda.
wireless networking, HDMI and composite video

14
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

• Micro-USB power adapter: To power the Raspberry Pi 4. Select the “sample-googleassistant-master” directory
board. from the extracted zip file location:

• MicroSD card reader

• Ethernet cable

• Android Studio 3.0+: The Official IDE for Android,


Android Studio provides the fastest tools for building
apps on Android devices. Features include code
editing, debugging, performance tooling, a flexible
build system, and a build/deploy system.

• Google API Console Project with Google Assistant API


enabled.

Figure 2: Identifying the sample-googleassistant-master directory


Assembling and Connecting to the AIYProjects
Voice Kit
Code Walk-through
The AIYProjects Web site has detailed instructions for
Now that we have the project loaded into Android Studio,
assembling the Voice Kit, so I won’t go over that again here.
let’s take a look at some of the relevant source code.
The Android Things Launcher shows information about
Open the VoiceHatDriver.java file in the editor. It’s the
the board, including the IP address. Connect to this IP
class responsible for implementing and registering the
address using the Android Debug Bridge tool:
audio user drivers. Both the audio input and output drivers
$ adb connect <ip-address> implementations are private AudioInputDriver subclasses
connected to <ip-address>:5555 named AudioInputUserDriver and AudioOutputUserDriver,
respectively.
Raspberry Pi broadcasts the hostname “Android.local”
Public functions instantiate the classes and
over Multicast DNS. If your host platform supports MDNS,
pass them along to the UserDriverManager’s
you also can connect to the board by using the following
registerAudio[Input|Output]Driver method:
command:

private class AudioInputUserDriver extends


$ adb connect Android.local
AudioInputDriver {
// Implement driver...
See the Android Things Dev site for more information on
}
connecting to your board.

Download the Source Code public void registerAudioInputDriver() {


Log.d(TAG, “registering audio input driver”);
Here’s how to download and import the Google Assistant mAudioInputDriver = new AudioInputUserDriver();
API sample for Android Things into Android Studio: UserDriverManager.getManager().
registerAudioInputDriver(
1. Download the master.zip file from Github. mAudioInputDriver,
mAudioFormat,
2. Extract the downloaded zip file.
AudioDeviceInfo.TYPE_BUILTIN_MIC,

3. Open Android Studio and select Import project from BUFFER_SIZE

the menu. );
}

15
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

private class AudioOutputUserDriver extends


Responses from the Google Assistant API are received
AudioOutputDriver {
in the form of a StreamObserver of ConverseResponse
// Implement driver...
objects. Each ConverseResponse may contain exactly one
}
of these fields:

public void registerAudioOutputDriver() { • EventType with a conversation event


Log.d(TAG, “registering audio output driver”);
mAudioOutputDriver = new AudioOutputUserDriver(); • ConverseResult with structured data
UserDriverManager.getManager().
• AudioOut with the assistant audio data
registerAudioOutputDriver(
mAudioOutputDriver, • Error with a google.rpc.Status message that specifies
mAudioFormat, the error for the operation.
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
BUFFER_SIZE Each of these response types are handled by the onNext()
); method of the StreamObserver class by using a switch
} statement:

Audio data is read and written by using the native Android // Receive ConverseResponse stream.

Things PIO APIs over an I2S (Inter-Integrated Circuit) protocol. StreamObserver<ConverseResponse>


mAssistantResponseObserver =
The AssistantActivity class makes the converse gRPC new StreamObserver<ConverseResponse>() {
method call, which initiates or continues a conversation @Override
with the embedded Google Assistant service. Hence, public void onNext(ConverseResponse value) {
it sends one ConverseRequest message with a switch (value.getConverseResponseCase()) {
ConverseConfig object containing the initial audio case EVENT_TYPE:
configuration. Then, multiple ConverseRequest messages // Handle events.
are sent with the audio data of the user voice request: break;
case RESULT:
// Initial request with audio // Handle query result.
config mAssistantRequestObserver.onNext( case AUDIO_OUT:
ConverseRequest.newBuilder().setConfig( // Handle audio data of the assistant’s
ConverseConfig.newBuilder() answer.
.setAudioInConfig(ASSISTANT_AUDIO_REQUEST_ break;
CONFIG) case ERROR:
.setAudioOutConfig(ASSISTANT_AUDIO_RESPONSE_ // Handle the converse response error.
CONFIG) break;
.build() }
).build() }
); };
// Send audio commands/queries.
mAssistantRequestObserver.onNext( Conclusion
ConverseRequest.newBuilder()
.setAudioIn(ByteString.copyFrom(audioData)) In the next article, we’ll configure the Google API Console
.build() Project and learn more about the Google Assistant API.
);

16
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
Using the Google Any Voice Kit How to Run Google
Assistant on Android Things

I
# comment or remove this line:
n the “Run Google Assistant on Android Things using
# dtoverlay=pwm-2chan-with-clk,pin=18,func=2,pin2=13,fu
the Any Voice Kit” tutorial, we learned how to integrate
nc2=4
the AIY Projects Voice Kit with the Raspberry Pi 3 Model B
#
and imported the Google Assistant API sample for Android
# uncomment or add this line:
Things into Android Studio. In this final tutorial, we’ll
dtoverlay=generic-i2s
configure the Google API Project so that we can converse
with Google Assistant.
Configuring the Google API Project
Enabling I2S
To use Google Assistant, we need to create an account
Make sure you enable I2S by changing the following line and enable the Google Assistant API.
in config.txt on the first SD card partition. Otherwise,
the microphone will not work. Open the dev terminal In your browser, navigate to Google’s My Activity page.
and type “sudo leafpad /boot/config.txt” (using My Activity is a central place to view and manage
leafpad). Then, remove the “#” in front the the line activities such as searches you’ve done, Web sites you’ve
“dtoverlay=generic-i2s” and insert a “#” in front of the visited, and videos you’ve watched. When you use certain
“dtoverlay=pwm-2chan-with-clk,pin=18,func=2,pin2=13,fu Google services—like Search, YouTube, or Chrome—your
nc2=4” line, as shown in the following code snippet: activity can be saved as data to your account. My Activity
helps make your experience on Google faster and more
useful. The kinds of activities that show up in My Activity
depend on which Google products you use and which
Activity controls are turned on.

17
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

Click the “Activity controls” link in the left-hand pane:

Figure 3: The “Create Project” button


Enable the Google Assistant API on the project you
Figure 1: Selecting the “Activity controls” link selected.

That will bring you to the Activity controls page. There,


enable the following Activity controls in the Google
Account you plan to use with the Assistant by dragging
the sliders from left (off) to right (on):

• Web & App Activity

• Device Information

• Voice & Audio Activity


Figure 4: Enabling the Google Assistant API

On the Google Assistant API details page, click the


Enable button:

Figure 2: The Activity controls slider Figure 5: Ready to click the Enable button

Go to the Google Cloud Platform Projects page. Create The next step is to Create an OAuth Client ID. From the
a new project, or feel free to use an existing one if you’ve Cloud Console, click the Credentials link on the left.
already created one.

18
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

On the OAuth consent screen tab, give the product a


name (don’t use “Google” in the name) and a description.

Figure 8: Closing the dialog

Click the “arrow” button at the far right of screen for the
client ID to download the client secret JSON file. It will be
named something like “client_secret_[long number].json”.

Installing the google-auth-lib Command Line Tool

Open a terminal and install the google-auth-lib command


line tool:

Figure 6: Naming and describing the product $ pip install google-auth-oauthlib[tool] --user

Once saved, the site should immediately bring you to the Navigate to your top-level project directory.
Credentials page. There, open the Create Credentials
dropdown and select “OAuth client ID” from the list: Use the google-oauthlib-tool command line tool to
grant the permission to use the Assistant API to your
application and create a new credentials.json file in your
app resource directory where “path/to/client_secret_
NNNN.json” is the path of the JSON file you downloaded:

$ cd <project-directory-name>
$ google-oauthlib-tool
--client-secrets path/to/client_secret_NNNN.json \
--credentials app/src/main/res/raw/credentials.json \
--scope https://www.googleapis.com/auth/
assistant-sdk-prototype \
--save

Figure 7: Opening the Create Credentials dropdown Running the Demo

Select the Other radio button and give the client ID a It’s time for the moment of truth.
name, such as “Android Things AIY Voice Kit Client.”
Perform the following steps from within Android Studio:
Click the Create button. A dialog box appears; it shows
1. Deploy the app to the device by selecting Run -> Run
you a client ID and secret. There’s no need to remember
‘app’ from the menu.
or save this, so you can close the dialog:

19
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.
GE T TING S TART ED WIT H ANDROID T HINGS DE VELOPMEN T

2. Select the Android Monitor tab (typically at the bottom • The Google Assistant answer should play back the
of the window) to see the logcat output inside Android following on the speaker:
Studio.
“The forecast for today is twenty degrees Celsius, mainly
You’ll know that the project has successfully launched sunny skies with a ten percent chance of showers late in
on the device once you can see the following startup the afternoon.”
message in the log:
Conclusion
... D AssistantActivity: Starting Assistant demo
In this article, we configured the Google API Project so
To ask a question: that we can interact with Google Assistant using the AIY
Projects Voice Kit. For more information and detailed
• Press a button to start recording your request; for instructions, be sure to visit the Google Codelabs
instance, “What is the weather like today?” Release the Android Things Assistant tutorial and the Google
button when finished talking. Assistant SDK page.

20
Back to Contents Getting Started with Android Things Development © 2017 QuinStreet, Inc.

You might also like