本文由
玉剛說寫做平臺
提供寫做贊助java原做者:
AndroFarmer
android版權聲明:本文版權歸微信公衆號
玉剛說
全部,未經許可,不得以任何形式轉載git
Android things(後面正文內容簡稱ats)是一個物聯網平臺,他基於Android,並作了至關多的改造以適合在一些低配置的物聯網設備上運行,同時它又是安卓,由於其保留了絕大部分Android framework的功能。所以藉助ats平臺咱們不須要了解嵌入式(準確的說仍是須要了解一些的)相關的知識就能夠開發出一系列智能硬件產品。github
要說明這個問題,咱們不如從反面說明,ats不能作什麼。
先看張ats的框架圖:
shell
因爲android studio 並未有提供ats的模擬器,因此咱們必需要有一個能刷ats系統的硬件(好比樹莓派)才行,同時爲了還須要一些傳感器、電阻、電子按鈕、麪包板、led燈等一些列配套外設,由於iot(物聯網)的開發不少時候都是對硬件的操做,有了這些外設才能更好的去實驗一些demo。
下面貼出我購買的硬件全家桶套裝: api
ats的開發不少時候都是操做硬件,因此咱們就有必要去研究,如何去操做外設設備,一個很重要的方法就是經過外設接口去操做。 看下圖:
bash
總線,總線,就是總讓你陷進去微信
樹莓派支持的總線類型: GPIO,I2C,I2S,SPI,PWM,UART網絡
關於總線我也不是專業的。以個人理解就是爲了控制不一樣的硬件設備,而對電信號作不一樣的處理而劃分的標準。這裏咱們先混個臉熟,後面用的最多的是GPIO,也就是以名稱BCM開通的針腳,後面咱們會經過名稱去控制這個針腳上的設備。 關於總線詳細的介紹,你們能夠參考下這篇文章: https://blog.csdn.net/haima1998/article/details/18729929app
關於這方面的介紹,網上仍是挺多的,我搜了一下最不缺的就是這類文章,因此這裏就不作詳細介紹了,簡單介紹下 步驟:
因爲物聯網設配的特殊性,咱們沒有像安卓同樣的觸摸屏和按鍵等外設來操做設備,因此咱們須要經過以下兩種方式去鏈接設備。
1.經過usb轉ttl設備直接鏈接
具體如何操做,能夠自行百度2.經過局域網鏈接(推薦方式) 先讓ats設備鏈接到路由器,這裏推薦鏈接顯示器鼠標鍵盤可視化操做鏈接網絡等操做,鏈接上顯示器以下圖:
經過這些命令咱們能夠更好的管理和使用ats
這是一個操做LED讓其閃爍的demo, 咱們經過這個demo來介紹基本的操做硬件的方法 先看下最終效果:
硬件搭建步驟:
更直觀一點的參考以下官方圖片:
這裏須要着重說明是:Ground爲地線,用來模擬零電壓線,GPIO總線端口能夠根據所加的電阻以及LED選擇不一樣的電壓,我這裏選擇的是電壓3.3v名爲BCM2的端口public class LightActivity extends Activity {
Handler mHandler;
PeripheralManager mPeripheralManager;
Gpio mLightGpio;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_light);
mHandler = new Handler();
mPeripheralManager = PeripheralManager.getInstance();
try {
mLightGpio = mPeripheralManager.openGpio("BCM2");
mLightGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
mHandler.post(mBlinkRunnable);
} catch (IOException e) {
e.printStackTrace();
}
}
private Runnable mBlinkRunnable = new Runnable() {
@Override
public void run() {
try {
if (mLightGpio == null)
return;
mLightGpio.setValue(!mLightGpio.getValue());
mHandler.postDelayed(mBlinkRunnable, 1000);
} catch (IOException e) {
}
}
};
@Override
protected void onDestroy() {
super.onDestroy();
if (mLightGpio != null) {
try {
mLightGpio.close();
mLightGpio = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
複製代碼
代碼很少,就全貼上去了,下面咱們分析下代碼。
mPeripheralManager=PeripheralManager.getInstance();
mLightGpio= mPeripheralManager.openGpio("BCM2");
複製代碼
咱們經過PeripheralManager單例後調用openGpio方法,傳入的參數爲GPIO端口對應的名稱,這樣就拿到這個端口控制對象Gpio的一個實例mLightGpio。
mLightGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_HIGH);
複製代碼
這句話代碼有兩個做用:1.設置電平方向爲輸出方向;2設置初始電平爲高電平並當即激活。 這句代碼執行後,LED會變爲常亮狀態。 咱們還能夠經過如下三行代碼實現跟上面一句一樣的效果:
//設置電平方向爲輸出方向,設置初始電平爲低電平並當即激活
mLightGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
//設置激活狀態爲高電平
mLightGpio.setActiveType(Gpio.ACTIVE_HIGH)
//進行激活
mLightGpio.setValue(true);
複製代碼
在mBlinkRunnable中經過 mLightGpio.setValue(!mLightGpio.getValue()) 來循環改變電平的激活狀態來實現LED的閃爍,至此LED就能夠blingbling的閃了。
最後看下ats項目和標準安卓有和區別 主要區別有兩點:
<uses-permission android:name="com.google.android.things.permission.USE_PERIPHERAL_IO"/>
<uses-permission android:name="com.google.android.things.permission.MANAGE_INPUT_DRIVERS" />
複製代碼
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
複製代碼
所謂用戶驅動就是ats容許你把相應的硬件的電信號轉化成系統事件,好比按鈕的點按事件註冊成系統的鍵盤按鍵事件,溫度感應器的電信號註冊成系統已存在的感應器事件,這樣各個組件均可以很方便的使用標準的framework api去操做硬件了。
本例展示的內容是把按鈕的點按事件電信號註冊成鍵盤的key事件,這樣按鈕就變成一個鍵盤了,能夠點擊和長按。註冊成系統事件後能夠在應用程序的各個組件中進行使用了。 演示效果:
硬件安裝圖:
看下代碼:
package com.androfarmer.button;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.view.KeyEvent;
import com.google.android.things.pio.Gpio;
import com.google.android.things.pio.GpioCallback;
import com.google.android.things.pio.PeripheralManager;
import com.google.android.things.userdriver.UserDriverManager;
import com.google.android.things.userdriver.input.InputDriver;
import com.google.android.things.userdriver.input.InputDriverEvent;
import java.io.IOException;
public class KeyCodeDriverService extends Service {
private InputDriver mDriver;
private Gpio mButtonGpio;
private static final int KEY_CODE = KeyEvent.KEYCODE_A;
@Override
public void onCreate() {
super.onCreate();
//建立輸入驅動,並設置驅動的基本信息
mDriver = new InputDriver.Builder()
.setName("Button2Keyboard")
.setSupportedKeys(new int[]{KEY_CODE})
.build();
// 經過 UserDriverManager註冊上面建立的驅動
UserDriverManager manager = UserDriverManager.getInstance();
manager.registerInputDriver(mDriver);
PeripheralManager peripheralManager = PeripheralManager.getInstance();
try {
mButtonGpio = peripheralManager.openGpio("BCM21");
//設置電平方向爲輸入
mButtonGpio.setDirection(Gpio.DIRECTION_IN);
//設置激活類型
mButtonGpio.setActiveType(Gpio.ACTIVE_LOW);
//設置監聽事件爲:電平中斷變化事件,Gpio.EDGE_BOTH
//意味着電平從低到高中斷以及從高到低中斷都會觸發回調
mButtonGpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
//設置電平變化的監聽器
mButtonGpio.registerGpioCallback(new GpioCallback() {
@Override
public boolean onGpioEdge(Gpio gpio) {
try {
Log.d("-------------button",gpio.getValue()+"");
boolean pressed=gpio.getValue();
InputDriverEvent event = new InputDriverEvent();
event.setKeyPressed(KEY_CODE, pressed);
mDriver.emit(event);
} catch (IOException e) {
e.printStackTrace();
}
//返回true表明一直監聽,false表明監聽一次
return true;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
//接觸註冊
UserDriverManager manager = UserDriverManager.getInstance();
manager.unregisterInputDriver(mDriver);
//關閉gpio端口
try {
mButtonGpio.close();
mButtonGpio = null;
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
複製代碼
代碼的註釋寫的已經很詳細了,就不過多解釋了。 這裏簡要介紹下步驟
主要分爲四類:
ats的不少場景咱們能夠像開發app同樣,對於作過android開發的同窗們來講這很easy,可是用戶驅動這個概念咱們可能第一次據說。ats的設計是模塊化的,一個ats硬件板只會包含基礎的硬件模塊如:網絡模塊,cpu,內存等。咱們拿到這個運行ats系統的基礎板後,若是要開發成具體的物聯網產品,可能須要接外設傳感器去實現具體功能:好比溫度傳感器,煙霧報警器等。
市面上傳感器門類複雜,若是咱們開發時將業務邏輯與硬件傳感器的操做雜糅在一塊兒,很顯然這樣的話咱們的代碼很脆弱而且不具有可移植性,換個同類別的其餘型號傳感器就沒法使用了。所以用戶驅動的出現很好的解決了這個問題,無論外設硬件同類別的型號有多少種,咱們只須要寫相應的用戶驅動將其註冊成framework已經實現的傳感器事件,這樣業務邏輯只須要跟標準的framework api打交道,而不用管具體用了哪種傳感器。
附上一個開源項目,這裏面實現了不少市面上廣泛使用的硬件的用戶驅動 https://github.com/androidthings/contrib-drivers 有興趣的同窗能夠去研究下不一樣類型的用戶驅動是如何編寫
ps:本文不少內容和案例來自於官網,更多案例請查看 https://developer.android.com/samples/?technology=iot&language=java