Android Things — Getting to Blinky

https://developer.android.com/things/index.html

Android Things brings Android and the mobile development ecosystem to IoT devices. It’s currently in developer preview 4, and has support for a variety of platforms, such as the Raspberry Pi, Intel Edison/Joule, and the NXP pico. You can learn more on the official site, but in essence, a developer can now use the same Android tools and APIs on IoT devices, including access to Google services, such as Google Drive/Search/Maps/Fit/Firebase/etc.

Android Tings platform architecture

Having zero Android development experience, this caught my interest and I figured I’d give it a go to see what it takes to get to the “Hello World” of hardware: a blinking LED.


Hardware

Android Things currently supports the aforementioned platforms. Naturally, I went with an Intel Edison that I have lying around (many of you may also have one, if you’ve attended one of the many hackathons in the past year :) If you have another supported platform, you could skip the setup section below and follow https://developer.android.com/things/hardware/developer-kits.html instead.

Follow the assembly guide found here https://software.intel.com/en-us/node/628221

Software Setup

We’ll need to download/install a couple of things to get started:

  1. Intel Flash Tool Lite (For updating the firmware on the Intel Edison)
  2. Android Things System Image (Android Things System Image for your board)
  3. Android Studio (Our IDE and tools for development)

The first thing you need to do is to install Android Studio and update to the latest SDK/tools. You’ll need to use these tools later for updating your board and deploying your application. After installing, make sure you have adb and fastboot in your command prompt.

Once that’s ready, download the Intel Flash Tool Lite along with the Android Things System Image. You can follow this guide here for details on how to update the firmware and install Android Things. The flashall.sh script mentioned in the guide didn’t work for me, so here’s a summary of the steps I took to get the board up and running:

  1. Run the Intel Flash Tool Lite to update the firmware, it should take about 30 seconds, with the board booting into FASTBOOT MODE if it was successful. You can monitor this from putty or screen terminal.
  2. Once booted into FASTBOOT MODE, run the fastboot tool in a command prompt of your host computer to install the image:
$ fastboot \
flash gpt partition-table.img \
flash u-boot u-boot-edison.bin \
flash boot_a boot.img \
flash boot_b boot.img \
flash system_a system.img \
flash system_b system.img \
flash gapps_a gapps.img \
flash gapps_b gapps.img \
flash oem_a oem.img \
flash oem_b oem.img \
set_active a \
reboot

3. Let your device reboot and wait for the adb shell:

$ adb wait-for-device
$ adb shell
edison:/$

…and you’re done! You now have Android Things running on your board!

You could also connect your board to Wi-Fi (we won’t need to for blinking an LED, but you’ll probably need connectivity for future projects)

edison: am startservice \
-n com.google.wifisetup/.WifiSetupService \
-a WifiSetupService.Connect \
-e ssid <SSID-name> \
-e passphrase <SSID-password>

Wait a few seconds then try pinging an IP e.g. 8.8.8.8 to make sure it works.

Creating your Android Things app

Follow this guide for creating an Android Things app. The steps are essentially the same as creating a regular Android app, but since I have zero prior experience, I followed this guide for creating my first Android project. You’ll need to target Android 7.0 (API 24) and make sure the SDK tools are up to date. Once the project has been created, you’ll need to modify the build.gradle and AndroidManifext.xml files to configure itself as an Android Things app:

build.gradle

dependencies {
...
provided 'com.google.android.things:androidthings:0.4-devpreview'
}

AndroidManifest.xml

<application
android:label="@string/app_name">
<uses-library android:name="com.google.android.things"/>
<activity android:name=".HomeActivity">
<!-- Launch activity as default from Android Studio -->
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

<!-- Launch activity automatically on boot -->
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.IOT_LAUNCHER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>

Build and run your project, it should succeed but it won’t be doing much at this point…

Interacting with Peripherals

The cool thing about Android Things (ha) is that developers are now able to interact with hardware peripherals in their application. Through the PeripheralManagerService APIs, you could interact with your device’s GPIO, PWM, I2C, SPI, I2S, and UART, allowing you to communicate with any sensor/actuator using these standard protocols.

Example of connecting sensors and displays

In addition to the peripheral APIs, Android Things also has the concept of User-Space Drivers; these drivers are essentially abstractions so you don’t have to worry about the hardware implementation and board configurations when interacting with a peripheral device. You could easily drop in a GPS/Temperature Sensor/Audio Output/OLED Screen/HID driver and use it right away, without worrying about the sensor protocol and any low-level peripheral IO APIs. Check out the peripheral driver library to see what’s already supported and how to add your own.

For now, we’re going to start thee basic Peripheral I/O APIs. Add the following code to your HomeActivity.java to get a list of available GPIOs on your board (Note: in Android Studio, press Alt+Enter for quick fix, it will import the missing dependencies)

public class HomeActivity extends Activity {
private static final String TAG = "HomeActivity";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

PeripheralManagerService service = new PeripheralManagerService();
Log.d(TAG, "Available GPIO: " + service.getGpioList());
}
}

Build and run, open up the logcat window and you should see a list of GPIOs:

Blinking an LED

Finally! So after setting up your board and installing all the software bits, the last step is to run the code for blinking an LED. You could setup your board like the diagram below, or simple use the on-board LED; both the on-board LED and the external LED are connected to GPIO pin 13:

There’s an on-board LED connected to pin 13, so you don’t need to if you don’t have one

Edit your HomeActivity.java with the following code:

public class HomeActivity extends Activity {
private static final String TAG = "HomeActivity";
private static final int INTERVAL_BETWEEN_BLINKS_MS = 1000;
private static final String LED_PIN_NAME = "IO13";

private Handler mHandler = new Handler();

private Gpio mLedGpio;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

PeripheralManagerService service = new PeripheralManagerService();
Log.d(TAG, "Available GPIO: " + service.getGpioList());

try{
mLedGpio = service.openGpio(LED_PIN_NAME);
mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
mHandler.post(mBlinkRunnable);

}catch(IOException e){
Log.e(TAG, "Error on peripheral", e);
}

}

@Override
protected void onDestroy() {
super.onDestroy();

// Step 4. Remove handler events on close.
mHandler.removeCallbacks(mBlinkRunnable);

// Step 5. Close the resource.
if (mLedGpio != null) {
try {
mLedGpio.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
}

private Runnable mBlinkRunnable = new Runnable() {
@Override
public void run() {
// Exit if the GPIO is already closed
if (mLedGpio == null) {
return;
}

try {
// Step 3. Toggle the LED state
mLedGpio.setValue(!mLedGpio.getValue());

// Step 4. Schedule another event after delay.
mHandler.postDelayed(mBlinkRunnable, INTERVAL_BETWEEN_BLINKS_MS);
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
};
}

Here’s what’s happening: We’ve created an instance of Gpio, set it to pin 13 using the PeripheralManagerService, set it to output and off initially with DIRECTION_OUT_INITIALLY_LOW, then using the setValue method to turn it on/off.

That’s it! Congratulations on blinking an LED on Android Things!

If you don’t want to type out these code snippets, you can just head over to https://developer.android.com/things/sdk/samples.html to download the complete, ready to run project. It’s all on GitHub and there you could find a lot of additional code samples as well.


Though still in developer preview, I had a great experience with getting started on Android Things and it was a lot of fun. Feel free to reach out if you have any questions or feedback :)

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.