Input

输入

Input user drivers provide an interface for apps to inject events into Android’s input pipeline. With this API, apps can emulate a Human Interface Device (HID) or connect external hardware to the input system using Peripheral I/O.

输入用户驱动为应用提供向 Android 的输入管道 注入事件的功能。有了这些 API 后, 应用可以模拟人体接口设备 (HID) 或使用 Peripheral I/O 连接外部硬件到系统的输入中。

Key Events

按键事件


Key events indicate a momentary press and release of an input switch. They are generally used for generic button input (e.g. volume keys, media playback keys) and the keys of a keyboard. Android represents each event as a KeyEvent instance.

按键事件即一个输入开关被短暂按下并释放的过程。这种事件一般代表常见的按钮输入(例如,音量键盘,媒体重播键)以及键盘的按键输入。Android 将每个事件表示为 KeyEvent 实例。

  1. Create a new driver instance using the InputDriver.Builder and the source type SOURCE_CLASS_BUTTON.

    使用 InputDriver.Builder 创建一个新的驱动实例,并将源类型声明为 SOURCE_CLASS_BUTTON

  2. Register the driver with the UserDriverManager.

    使用 UserDriverManager 注册该驱动实例。

  1. import com.google.android.things.userdriver.InputDriver;
  2. import com.google.android.things.userdriver.UserDriverManager;
  3. public class ButtonDriverService extends Service {
  4. // Driver parameters
  5. private static final String DRIVER_NAME = "EscapeButton";
  6. private static final int DRIVER_VERSION = 1;
  7. // Key code for driver to emulate
  8. private static final int KEY_CODE = KeyEvent.KEYCODE_ESCAPE;
  9. private InputDriver mDriver;
  10. @Override
  11. public void onCreate() {
  12. super.onCreate();
  13. // Create a new driver instance
  14. mDriver = InputDriver.builder(InputDevice.SOURCE_CLASS_BUTTON).setName(DRIVER_NAME).setVersion(DRIVER_VERSION).setKeys(new int[] {KEY_CODE}).build();
  15. // Register with the framework
  16. UserDriverManager manager = UserDriverManager.getManager();
  17. manager.registerInputDriver(mDriver);
  18. }
  19. @Override
  20. public IBinder onBind(Intent intent) {
  21. return null;
  22. }
  23. }
  1. When a hardware event occurs, construct a new KeyEvent for each state chnage with the current key code and input action.

    当硬件事件发生时,使用当前的键值和输入动作为每个状态改变构建一个新的 KeyEvent

  2. Inject the events into the driver with the emit() method.

    使用 emit() 方法将这个事件注入到驱动中。

  1. public class ButtonDriverService extends Service {
  2. // A state change has occurred
  3. private void triggerEvent(boolean pressed) {
  4. int action = pressed ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
  5. KeyEvent[] events = new KeyEvent[] {new KeyEvent(action, KEY_CODE)};
  6. if (!mDriver.emit(events)) {
  7. Log.w(TAG, "Unable to emit key event");
  8. }
  9. }
  10. }
  1. Unregister the driver when key events are not longer required.

    当按键事件不再需要时,取消注册该驱动。

  1. public class ButtonDriverService extends Service {
  2. @Override
  3. public void onDestroy() {
  4. super.onDestroy();
  5. UserDriverManager manager = UserDriverManager.getManager();
  6. manager.unregisterInputDriver(mDriver);
  7. }
  8. }

Motion Events

运动事件


Input drivers can also emit motion events to connect a pointing device to the framework, such as a touchpad or mouse. These devices report an absolute position value as an x/y coordinate. Each event include an optional pressed state to indicate if the event represents a “tap” or “click” event at that location.

输入驱动还能产生运动事件用来配合连接一个指向性设备到 framework 中,例如触控板或鼠标。这些设备以 x/y 坐标系的形式上报它们的绝对位置。每个事件还包含一个可选的按压状态,用以表明在那个位置时设备是否处于“按压”或“点击”状态。

Note: You must report all coordinates as positive integer values.

注意: 您上报的坐标必须是正整数值。

  1. Create a new driver instance using the InputDriver.Builder and the source type SOURCE_TOUCHPAD.

    使用 InputDriver.Builder 创建一个新的驱动实例,并将源类型声明为 SOURCE_TOUCHPAD

  2. Register the driver with the UserDriverManager.

    使用 UserDriverManager 注册该驱动实例。

  1. import com.google.android.things.userdriver.InputDriver;
  2. public class TouchpadDriverService extends Service {
  3. // Driver parameters
  4. private static final String DRIVER_NAME = "Touchpad";
  5. private static final int DRIVER_VERSION = 1;
  6. private InputDriver mDriver;
  7. @Override
  8. public void onCreate() {
  9. super.onCreate();
  10. mDriver = InputDriver.builder(InputDevice.SOURCE_TOUCHPAD).setName(DRIVER_NAME).setVersion(DRIVER_VERSION).setAbsMax(MotionEvent.AXIS_X, 255).setAbsMax(MotionEvent.AXIS_Y, 255).build();
  11. UserDriverManager manager = UserDriverManager.getManager();
  12. manager.registerInputDriver(mDriver);
  13. }
  14. @Override
  15. public IBinder onBind(Intent intent) {
  16. return null;
  17. }
  18. }
  1. When a hardware event occurs, inject the new coordinates into the driver with the emit() method.

    当硬件事件发生时,使用 emit() 方法将新坐标注入到驱动中。

  1. public class TouchpadDriverService extends Service {
  2. // A state change has occurred
  3. private void triggerEvent(int x, int y, boolean pressed) {
  4. if (!mDriver.emit(x, y, pressed)) {
  5. Log.w(TAG, "Unable to emit motion event");
  6. }
  7. }
  8. }
  1. Unregister the driver when pointer events are not longer required.

    当不在需要指针事件时,取消注册该驱动。

  1. public class TouchpadDriverService extends Service {
  2. @Override
  3. public void onDestroy() {
  4. super.onDestroy();
  5. UserDriverManager manager = UserDriverManager.getManager();
  6. manager.unregisterInputDriver(mDriver);
  7. }
  8. }

Handling Input Events

处理输入事件


Android delivers input events to the foreground activity through various callback methods. Your app receives key events through the onKeyDown() and onKeyUp() methods, and all other input events through the onGenericMotionEvent() method.

Android 通过多种回调方法传递输入事件给前台活动。您的应用通过使用 onKeyDown()onKeyUp() 方法接收按键事件,以及通过 onGenericMotionEvent() 方法接收所有其它输入事件。

  1. public class HomeActivity extends Activity {
  2. @Override
  3. public boolean onKeyDown(int keyCode, KeyEvent event) {
  4. // Handle key pressed and repeated events
  5. return true;
  6. }
  7. @Override
  8. public boolean onKeyUp(int keyCode, KeyEvent event) {
  9. // Handle key released events
  10. return true;
  11. }
  12. @Override
  13. public boolean onGenericMotionEvent(MotionEvent event) {
  14. // Handle motion input events
  15. return true;
  16. }
  17. }

See Handling Controller Actions for more details on how Android handles input events from external source devices.

查阅处理控制器的行为 来获取更多有关 Android 如何处理从外部设备源中获取输入事件的详细信息。

Adding the required permission

添加必需权限


Add the required permission for the user driver to your app’s manifest file:

在您应用的清单文件中添加用户驱动所需的权限:

  1. <uses-permission android:name="com.google.android.things.permission.MANAGE_INPUT_DRIVERS" />