AndroidThingsでは、デバイスごとにつけているセンサーやGPS、周辺機器が異なるため、一部のAndroid Frameworkで利用できる機能がデフォルトでは使えなくなっています。
例えばGPSはRaspberry Piには乗っていないため、GPSに関連する機能はデフォルトでは使えません。
ただし、電子部品として追加する分にはGPS等をつけることは可能です。
この時、追加したGPSや温度センサー等をAndroid Frameworkで利用できるようにするのがUser Driverです。
※ドキュメントだと、User-Space Drivers、User Driversと若干表記ゆれがある気がします.
User Driverのメリット
主にUser Driverのメリットには以下があります。
- 移植性
- 再利用性
- 統合
色々メリットはありますが、単純に「様々な周辺機器ラップしてAndroid Framework上から触れたほうが、既存のコードやライブラリも使えるし、移植性も高いでしょ」という感じでイメージすればいいと思います。
User Driverの種類
主に3種類あります。
- GPS
- GPSです。AndroidのLocation Serviceと統合できます。
- HID - Human Interface Devices
- ユーザの入力を扱うDriverです。AndroidのKey EventsやMotion Events(Touchとか)を統合することが出来ます。
- 例えば物理ボタンとKey Eventsを紐付けたり出来ます。
- Sensor
- センサーです。 AndroidのSensorManagerと統合できます。
- PIOで追加した様々なセンサーをAndroid Framework上(SensorManager)経由で扱う事ができるようになります。
User Driverを試してみる
とりあえず一番簡単なボタンのUser Driverを試してみます。めんどくさいので公式のsample-buttonをそのまま使います。
ハードウェア構成
以下です。
コード
一応kotlinにして、いらないところやコメントを追加してあります。
package com.github.soundtricker.androidthings.samleuserdriver
import android.app.Activity
import android.os.Bundle
import java.io.IOException
import android.util.Log
import android.view.KeyEvent
import com.google.android.things.contrib.driver.button.Button
import com.google.android.things.contrib.driver.button.ButtonInputDriver
import com.google.android.things.pio.Gpio
import com.google.android.things.pio.PeripheralManagerService
class MainActivity : Activity() {
companion object {
private val TAG = MainActivity::class.java.simpleName
private val GPIO_BUTTON_PIN_NAME= "BCM21"
private val GPIO_LED_PIN_NAME = "BCM6"
}
private var mButtonInputDriver: ButtonInputDriver? = null
private var mLedGpio: Gpio? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setupButton()
setupLed()
}
override fun onDestroy() {
super.onDestroy()
destroyButton()
destroyLed()
}
private fun setupButton() {
try {
mButtonInputDriver = ButtonInputDriver(GPIO_BUTTON_PIN_NAME,
Button.LogicState.PRESSED_WHEN_LOW,
KeyEvent.KEYCODE_SPACE
)
mButtonInputDriver!!.register()
} catch (e: IOException) {
Log.e(TAG, "failed initialize button driver", e)
return
}
}
private fun setupLed() {
try {
val pioSerivce = PeripheralManagerService()
mLedGpio = pioSerivce.openGpio(GPIO_LED_PIN_NAME)
} catch (e: IOException) {
Log.e(TAG, "failed initialize led", e)
return
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_SPACE) {
// Turn on the LED
setLedValue(true)
return true
}
return super.onKeyDown(keyCode, event)
}
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_SPACE) {
// Turn off the LED
setLedValue(false)
return true
}
return super.onKeyUp(keyCode, event)
}
private fun setLedValue(value: Boolean) {
try {
mLedGpio!!.value = value
} catch (e: IOException) {
Log.e(TAG, "Error updating GPIO value", e)
}
}
private fun destroyButton() {
Log.i(TAG, "Closing button")
mButtonInputDriver?.unregister()
try {
mButtonInputDriver?.close()
} catch (e: IOException) {
Log.e(TAG, "Error closing Button driver", e)
} finally {
mButtonInputDriver = null
}
}
private fun destroyLed() {
try {
mLedGpio!!.close()
} catch (e: IOException) {
Log.e(TAG, "Error closing LED", e)
} finally {
mLedGpio = null
}
}}
上の
mButtonInputDriver = ButtonInputDriver(GPIO_BUTTON_PIN_NAME,
Button.LogicState.PRESSED_WHEN_LOW,
KeyEvent.KEYCODE_SPACE
)
mButtonInputDriver!!.register()
部分がAndroid FrameworkにUser Driverを登録している部分です。
Android FrameworkとしてUser Driverを登録することで以下のように物理Buttonの押し離しをKey Eventとして、扱う事ができるようになります。
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_SPACE) {
// Turn on the LED
setLedValue(true)
return true
}
return super.onKeyDown(keyCode, event)
}
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_SPACE) {
// Turn off the LED
setLedValue(false)
return true
}
return super.onKeyUp(keyCode, event)
}
なお、上記コードを動かすためには、AndroidManifest.xmlに以下を追加する必要があります。
<uses-permission android:name="com.google.android.things.permission.MANAGE_INPUT_DRIVERS" />
まとめ
User Driverによって、Androidらくしセンサーなどを扱えるのはAndroid Thingsのメリットだと思います。
多分