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 を生成します。
UserDriverManager の registerInputDriver() で 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_librarycontrib-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 件のコメント:
コメントを投稿