2017年11月19日日曜日

Android Things をやってみよう - InputDriver 編

User-Space Drivers : input

InputDriver を使うと、タッチイベントやキーイベントをシステムに流すことができます。

これにより、例えば GPIO から入力があったときに Space キーや Enter キーなどの KeyEvent を流すことで、KeyEvent を処理する機能やライブラリをそのまま流用できます。

InputDriver を使うときは com.google.android.things.permission.MANAGE_INPUT_DRIVERS パーミッションが必要です。 <uses-permission android:name="com.google.android.things.permission.MANAGE_INPUT_DRIVERS" />

InputDriver.Builder を使って InputDriver を生成します。

UserDriverManagerregisterInputDriver() で InputDriver を登録し、最後に unregisterInputDriver() で登録を解除します。

InputDriver にキーイベントを流すときは InputDrivder.emit() に KeyEvent を渡します。 class InputDriverActivity : Activity() { private var gpio: Gpio? = null private var inputDriver: InputDriver? = null private val callback: GpioCallback = object : GpioCallback() { override fun onGpioEdge(gpio: Gpio): Boolean { val action = if (gpio.value) KeyEvent.ACTION_DOWN else KeyEvent.ACTION_UP // ドライバーに Enter キーイベントを流す inputDriver?.emit(arrayOf(KeyEvent(action, KeyEvent.KEYCODE_ENTER))) return true } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val pioService = PeripheralManagerService() try { gpio = pioService.openGpio("GPIO_174").apply { setDirection(Gpio.DIRECTION_IN) setEdgeTriggerType(Gpio.EDGE_BOTH) setActiveType(Gpio.ACTIVE_LOW) registerGpioCallback(callback) } } catch (e: IOException) { Log.e(TAG, "Error initializing GPIO", e) } // Enter キーをサポートするドライバーを用意 inputDriver = InputDriver.Builder(InputDevice.SOURCE_CLASS_BUTTON) .setName("Button") .setVersion(1) .setKeys(intArrayOf(KeyEvent.KEYCODE_ENTER)) .build() // ドライバーを登録 UserDriverManager.getManager().registerInputDriver(inputDriver) } override fun onDestroy() { if (inputDriver != null) { // ドライバーの登録を解除 UserDriverManager.getManager().unregisterInputDriver(inputDriver) inputDriver = null } gpio?.unregisterGpioCallback(callback) try { gpio?.close() } catch (e: IOException) { Log.e(TAG, "Error closing GPIO", e) } super.onDestroy() } override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { Log.d(TAG, "onKeyDown : $keyCode") if (keyCode == KeyEvent.KEYCODE_ENTER) { return true } return super.onKeyDown(keyCode, event) } override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { Log.d(TAG, "onKeyUp : $keyCode") if (keyCode == KeyEvent.KEYCODE_ENTER) { return true } return super.onKeyUp(keyCode, event) } companion object { private const val TAG = "InputDriverActivity" } }

contrib-drivers

https://developer.android.com/things/training/first-device/drivers.html#initialize_the_driver_library

contrib-drivers の button にある ButtonInputDriver を利用すると、GPIO の入力を簡単に KeyEvent に割り当てられます。 implementation 'com.google.android.things.contrib:driver-button:0.3' class ButtonInputDriverActivity : Activity() { private var inputDriver: ButtonInputDriver? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) inputDriver = ButtonInputDriver("GPIO_174", Button.LogicState.PRESSED_WHEN_LOW, KeyEvent.KEYCODE_ENTER) } override fun onDestroy() { inputDriver?.unregister() try { inputDriver?.close() } catch (e: IOException) { Log.e(TAG, "Error closing GPIO", e) } super.onDestroy() } override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { Log.d(TAG, "onKeyDown : $keyCode") if (keyCode == KeyEvent.KEYCODE_ENTER) { return true } return super.onKeyDown(keyCode, event) } override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { Log.d(TAG, "onKeyUp : $keyCode") if (keyCode == KeyEvent.KEYCODE_ENTER) { return true } return super.onKeyUp(keyCode, event) } companion object { private const val TAG = "ButtonInputDriverActivity" } }

0 件のコメント:

コメントを投稿