Android Things-物联网开发

Android Things正式接替Brillo亮相,名称的改变带来了什么新的内容,广大Android开发者如何进入这一新的领域,通过本文,你不仅会了解Android Things的来龙去脉,也会直接通过代码来体验开发带给你的魅力。

Android Everywhere

一张Google IO 2015上的旧图,清晰的展示了Android的历史和未来。


Android Things-物联网开发_第1张图片

Android

Android Things-物联网开发_第2张图片

处于中心的Android Mobile,已经占据了全球手机市场绝大多数份额,几十亿部Android手机,构成了Android生态系统最坚实的基础。

Android TV

Android Things-物联网开发_第3张图片

随着着电视大屏发展的脚步,Android TV也成了所有电视盒子和智能电视的不二之选,主要归功于Android硬件系统的开放、庞大的开发者群体、完整的工具链。如果说手机端还有iOS将近20%的份额,在TV端,目测tvOS不到2%,Android TV也就代表了整个智能电视,国内更是100%的Android TV,Apple TV没有国行版本。

Android Wear

Android Things-物联网开发_第4张图片

让你的应用跑在手表上,同样使用熟悉的开发工具,主要是面向海外的应用,由于国内Android Mobile严重分裂,而Android Wear需要依赖手机的支持。

Android Auto

Android Things-物联网开发_第5张图片

针对汽车的使用场景进行优化,有了Android Auto就不用上车后就是找电源线,然后开导航,再把手机放到各种架子上,而是直接把Android Mobile放到原生底座上,直接使用语音和易操作的中控大屏。

Android Chromebook

Android Things-物联网开发_第6张图片

从 Chrome 操作系统版本 M53 开始,可以直接使用Chromebook中的Google Play Store下载和使用Android应用,现在使用的Google Chrome版本是55,那么绝大多数已有Chromebook都已经支持Android应用,新的Chromebook自然都会支持。
针对 Chromebook 优化应用
支持Android应用的Chromebook列表
Android和Chrome两大系统的合并,除了带来了Android丰富的应用以外,对于用户最大的好处就是自动更新了,Chrome自动下载更新,下次重新打开/启动时自动应用更新,从Android Nougat开始,Android系统也将使用这种更新机制。
根据IDC报告,Chromebook在2016年第一季度的出货量已经在美国市场超越了Mac,特别是由于教育市场的大量需求。
这里,还要注意,Chromebook使用的Chrome OS和Google Chrome高度共享代码,既然Android应用可以在Chromebook上运行,当未来在Mac/Windows/Linux上可以时,你也不要感到惊讶。

Android Things

终于到了今天的主角登场,Android Things!先看外表。


Android Things-物联网开发_第7张图片

再看内部核心硬件。


Android Things-物联网开发_第8张图片

它的愿景就是将无数的的设备连接起来,Android Things作为物联网的大脑,使用公开协议Weave与广大的传感器/外部设备进行对话。
不像Android其它系统,Android Things大多数情况下只在后台以服务方式运行,没有显示屏,默默的与打印机、门锁、烤箱、灯泡、插座这些设备一起提供服务。

Android Things全解析

Android Things架构

先看Brillo和Android Things的架构图进行对比。
这是Brillo,


Android Things-物联网开发_第9张图片

这是Android Things,


Android Things-物联网开发_第10张图片

可以很清楚的看出来:

  • Brillo使用C/C++基于NDK进行开发,Android Things通过Java API面向广大的Android和Java开发者,就算是新手,Android的也是极易上手的。各位苦于嵌入式开发各种工具坑的福音到了,对于性能和底层要求高的部分仍然可以用NDK编写,在Android Studio里调试NDK代码也和Java代码一样的简单。
  • Android Studio,Android SDK,Play service和Firebase,这些工具和Service形成了完整易用的工具链。
  • Android Things出生最晚,更新条件也是最好的,直接使用Android Nougat的自动后台更新机制,最大限度的提高系统的安全性。

广泛的硬件平台支持

现在支持以下3款硬件
Intel Edison
开发版中的贵族。

Android Things-物联网开发_第11张图片

NXP Pico
中规中矩的中间阶层。
Android Things-物联网开发_第12张图片

Raspberry Pi 3
少了草根精英树莓派怎么行。

Android Things-物联网开发_第13张图片

Hello Android Things

买到的开发版都是没有装操作系统系统的,第一步先把Android Things刷到板子里。

Flash image(刷机)

官方刷机教程
以Intel Edison为例:
0.Android SDK Platform Tools 25.0.3以上,fastboot工具添加到PATH环境变量中,以便从任意目录运行。
1.下载后打Intel Flash Tool,加打开下载好的对应刷机包。

Android Things-物联网开发_第14张图片

  1. 使用USB线链接Edison,如果Edison没有显示,换USB口和线试试。


    Android Things-物联网开发_第15张图片
  2. Start to Flash(开始刷机)


    Android Things-物联网开发_第16张图片

4.使用Fastboot刷入系统镜像,此时需要几十秒,光System.img就有500多M。


Android Things-物联网开发_第17张图片

Android Things-物联网开发_第18张图片

5.刷入Google Service镜像。


Android Things-物联网开发_第19张图片

6.刷入OEM镜像。
Android Things-物联网开发_第20张图片

7.重启
fastboot reboot

8.验证系统状态。


Android Things-物联网开发_第21张图片

如果出现以下Error,把Intel Flash Tool关掉,重新连接下USB。

List of devices attached
adb server version (35) doesn't match this client (36); killing...
adb E 69469 2714428 usb_osx.cpp:327] Could not open interface: e00002c5
adb E 69469 2714428 usb_osx.cpp:289] Could not find device interface
error: could not install *smartsocket* listener: Address already in use
ADB server didn't ACK
* failed to start daemon *
error: cannot connect to daemon

Connecting WIFI(联网)

依然是熟悉的adb命令和服务启动参数

$ adb shell am startservice \
    -n com.google.wifisetup/.WifiSetupService \
    -a WifiSetupService.Connect \
    -e ssid SSID \
    -e passphrase password

用logcat查看网络状态

$ adb logcat -d | grep Wifi
...
V WifiWatcher: Network state changed to CONNECTED
V WifiWatcher: SSID changed: ...
I WifiConfigurator: Successfully connected to ...

Ping检测

$ adb shell ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114) 56(84) bytes of data.
64 bytes from 114.114.114.114: icmp_seq=1 ttl=57 time=6.67 ms
64 bytes from 114.114.114.114: icmp_seq=2 ttl=57 time=55.5 ms
64 bytes from 114.114.114.114: icmp_seq=3 ttl=57 time=23.0 ms
64 bytes from 114.114.114.114: icmp_seq=4 ttl=57 time=245 ms

Hello Android Things项目

Android Studio中新建项目

Android Things-物联网开发_第22张图片

Android Things-物联网开发_第23张图片

在build.gralde中添加依赖com.google.android.things:androidthings

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.geekdev.alpha.androidthings"
        minSdkVersion 24
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    provided 'com.google.android.things:androidthings:0.1-devpreview'
    compile 'com.google.android.things.contrib:driver-button:0.1'
    compile 'com.android.support:appcompat-v7:25.1.0'
    testCompile 'junit:junit:4.12'
}

此处依赖方式是provided,让Android Things使用系统中的库。

添加activity

添加一个主activity并配置AndroidManifest.xml





    

    
        
            
            
        

        
            
            
            
        
    

    

在Activity中输出Hello Android Things

public class MainActivity extends Activity {

  private static final String TAG = MainActivity.class.getSimpleName();

  @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(TAG, "Hello Android Things!");
  }
}

运行输出

直接Command+R,可以在logcat窗口中看到结果了。


Android Things-物联网开发_第24张图片

Peripheral I/O

不满足于Hello Android Things,继续来使用Android Things对外设进行操作。
使用Button driver对LED灯进行开关操作。

package com.geekdev.alpha.androidthings;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Button;

import com.google.android.things.contrib.driver.button.ButtonInputDriver;
import com.google.android.things.pio.Gpio;
import com.google.android.things.pio.PeripheralManagerService;

import java.io.IOException;

/**
 * Created by Alpha.
 * 

 * Example of using Button driver for toggling a LED.
 * 


 * This activity initialize an InputDriver to emit key events when the button GPIO pin state change
 * and flip the state of the LED GPIO pin.
 * 


 * You need to connect an LED and a push button switch to pins specified in {@link BoardDefaults}
 * according to the schematic provided above.
 */


public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();


    private Gpio mLedGpio;
    private ButtonInputDriver mButtonInputDriver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "Hello Android Things!");
        Log.i(TAG, "Starting ButtonActivity");

        PeripheralManagerService pioService = new PeripheralManagerService();
        try {
            Log.i(TAG, "Configuring GPIO pins");
            mLedGpio = pioService.openGpio(BoardDefaults.getGPIOForLED());
            mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

            Log.i(TAG, "Registering button driver");
            // Initialize and register the InputDriver that will emit SPACE key events
            // on GPIO state changes.
            mButtonInputDriver = new ButtonInputDriver(
                    BoardDefaults.getGPIOForButton(),
                    Button.LogicState.PRESSED_WHEN_LOW,
                    KeyEvent.KEYCODE_SPACE);
            mButtonInputDriver.register();
        } catch (IOException e) {
            Log.e(TAG, "Error configuring GPIO pins", e);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_SPACE) {
            // Turn on the LED
            setLedValue(true);
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_SPACE) {
            // Turn off the LED
            setLedValue(false);
            return true;
        }

        return super.onKeyUp(keyCode, event);
    }

    /**
     * Update the value of the LED output.
     */
    private void setLedValue(boolean value) {
        try {
            mLedGpio.setValue(value);
        } catch (IOException e) {
            Log.e(TAG, "Error updating GPIO value", e);
        }
    }

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

        if (mButtonInputDriver != null) {
            mButtonInputDriver.unregister();
            try {
                mButtonInputDriver.close();
            } catch (IOException e) {
                Log.e(TAG, "Error closing Button driver", e);
            } finally {
                mButtonInputDriver = null;
            }
        }

        if (mLedGpio != null) {
            try {
                mLedGpio.close();
            } catch (IOException e) {
                Log.e(TAG, "Error closing LED GPIO", e);
            } finally {
                mLedGpio = null;
            }
            mLedGpio = null;
        }
    }
}

添加一个开发板的处理工具类BoardDefaults.java

package com.geekdev.alpha.androidthings;

import android.os.Build;

import com.google.android.things.pio.PeripheralManagerService;

import java.util.List;

/**
 * Created by Alpha.
 */


public class BoardDefaults {
    private static final String DEVICE_EDISON_ARDUINO = "edison_arduino";
    private static final String DEVICE_EDISON = "edison";
    private static final String DEVICE_RPI3 = "rpi3";
    private static final String DEVICE_NXP = "imx6ul";
    private static String sBoardVariant = "";

    /**
     * Return the GPIO pin that the LED is connected on.
     * For example, on Intel Edison Arduino breakout, pin "IO13" is connected to an onboard LED
     * that turns on when the GPIO pin is HIGH, and off when low.
     */
    public static String getGPIOForLED() {
        switch (getBoardVariant()) {
            case DEVICE_EDISON_ARDUINO:
                return "IO13";
            case DEVICE_EDISON:
                return "GP45";
            case DEVICE_RPI3:
                return "BCM6";
            case DEVICE_NXP:
                return "GPIO4_IO21";
            default:
                throw new IllegalStateException("Unknown Build.DEVICE " + Build.DEVICE);
        }
    }

    /**
     * Return the GPIO pin that the Button is connected on.
     */
    public static String getGPIOForButton() {
        switch (getBoardVariant()) {
            case DEVICE_EDISON_ARDUINO:
                return "IO12";
            case DEVICE_EDISON:
                return "GP44";
            case DEVICE_RPI3:
                return "BCM21";
            case DEVICE_NXP:
                return "GPIO4_IO20";
            default:
                throw new IllegalStateException("Unknown Build.DEVICE " + Build.DEVICE);
        }
    }

    private static String getBoardVariant() {
        if (!sBoardVariant.isEmpty()) {
            return sBoardVariant;
        }
        sBoardVariant = Build.DEVICE;
        // For the edison check the pin prefix
        // to always return Edison Breakout pin name when applicable.
        if (sBoardVariant.equals(DEVICE_EDISON)) {
            PeripheralManagerService pioService = new PeripheralManagerService();
            List gpioList = pioService.getGpioList();
            if (gpioList.size() != 0) {
                String pin = gpioList.get(0);
                if (pin.startsWith("IO")) {
                    sBoardVariant = DEVICE_EDISON_ARDUINO;
                }
            }
        }
        return sBoardVariant;
    }
}

运行到如下的Raspberry Pi 3中,使用按钮来控制LED灯。


Android Things-物联网开发_第25张图片

Code

所有示例项目代码可有Github中找到.

更多

到这里,你已经了解Android Things的历史,特点和开发。更多关于Google技术的内容,欢迎加入G tech online meetup微信群进行交流。


Android Things-物联网开发_第26张图片

你可能感兴趣的:(Android Things-物联网开发)