Android Things使用Android打开物联网的大门——Android Things开发

Android Things:用户驱动-输入

2017-05-01  本文已影响53人  1024工场

一、驱动介绍


输入用户驱动程序为应用程序提供接口,向Android的输入管道注入事件。有了这个API,应用程序可以使用Peripheral I/O模拟一个人机界面的设备(HID)或者连接外部硬件到输入系统。比如说,我们可以使用开关按钮GPIO的信号输入,通过输入驱动API模拟呈键盘上按键的输入事件,下面我们会具体演示如何实现。

二、使用步骤


实现输入用户驱动,有如下步骤:
1.创建驱动:使用InputDriver.Builder和源类型SOURCE_CLASS_BUTTON创建一个新的输入驱动实例。
2.注册驱动:使用UserDriverManager的registerInputDriver()方法注册这个驱动。

public class TouchpadDriverService extends Service {
    // Driver parameters
    private static final String DRIVER_NAME = "Touchpad";
    private static final int DRIVER_VERSION = 1;
    private InputDriver mDriver;
    @Override
    public void onCreate() {
        super.onCreate();
        mDriver = InputDriver.builder(InputDevice.SOURCE_TOUCHPAD)
                .setName(DRIVER_NAME)
                .setVersion(DRIVER_VERSION)
                .setAbsMax(MotionEvent.AXIS_X, 255)
                .setAbsMax(MotionEvent.AXIS_Y, 255)
                .build();
        UserDriverManager manager = UserDriverManager.getManager();
        manager.registerInputDriver(mDriver);
    }
}

3. 转换事件:当一个硬件事件发生,使用当前的事件代码和输入动作为每个状态改变构造一个新的KeyEvent。
4. 注入事件:使用输入驱动的emit()方法向这个驱动中注入事件。

private void triggerEvent(boolean pressed) {
     int action = pressed ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
     KeyEvent[] events = new KeyEvent[] {new KeyEvent(action, KEY_CODE)};
     if (!mDriver.emit(events)) {
            Log.w(TAG, "Unable to emit key event");
     }
}

5.处理事件:在前台Activity通过实现onKeyDown()、onKeyUp()和onGenericMotionEvent()方法来获取相关事件,并处理。

public class HomeActivity extends Activity {
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // Handle key pressed and repeated events
        return true;
    }
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        // Handle key released events
        return true;
    }
    @Override
    public boolean onGenericMotionEvent(MotionEvent event) {
        // Handle motion input events
        return true;
    }
}

6.注销驱动:当你不在需要关键事件的时候注销驱动。

public class TouchpadDriverService extends Service {
    @Override
    public void onDestroy() {
         super.onDestroy();
         UserDriverManager manager = UserDriverManager.getManager();
         manager.unregisterInputDriver(mDriver);
    }
}

三、案例展示


这里我们实现一个最简单的模拟键盘,通过两个开关按钮的GPIO信号输入,通过输入驱动API分别模拟键盘上a和b字母的输入。
1. 硬件准备

2. 电路搭建

电路图

3. 代码实现
InputDemo\app\src\main\java\com\chengxiang\inputdemo\KeyDriverService.java

public class KeyDriverService extends Service {
    private static final String TAG = KeyDriverService.class.getSimpleName();

    private static final String A_DRIVER_NAME = "Akey";
    private static final int A_DRIVER_VERSION = 1;
    private static final int A_KEY_CODE = KeyEvent.KEYCODE_A;

    private static final String B_DRIVER_NAME = "Bkey";
    private static final int B_DRIVER_VERSION = 1;
    private static final int B_KEY_CODE = KeyEvent.KEYCODE_B;

    private static final String A_GPIO_NAME = "BCM5";
    private static final String B_GPIO_NAME = "BCM6";

    private UserDriverManager mUserDriverManager;
    private InputDriver mADriver;
    private InputDriver mBDriver;

    private Gpio mAGpio;
    private Gpio mBGpio;

    private GpioCallback mGpioCallback = new GpioCallback() {
        @Override
        public boolean onGpioEdge(Gpio gpio) {
            Log.d(TAG, "onGpioEdge");
            try {
                //获取开关按键的信号输入后,转换成A和B按键的输入事件
                if (gpio == mAGpio) {
                    triggerEvent(mADriver, gpio.getValue(), A_KEY_CODE);
                } else if (gpio == mBGpio) {
                    triggerEvent(mBDriver, gpio.getValue(), B_KEY_CODE);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return true;
        }

        @Override
        public void onGpioError(Gpio gpio, int error) {
            Log.w(TAG, gpio + ": Error event " + error);
        }
    };

    public KeyDriverService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        PeripheralManagerService manager = new PeripheralManagerService();
        try {
            mAGpio = manager.openGpio(A_GPIO_NAME);
            mAGpio.setDirection(Gpio.DIRECTION_IN);
            mAGpio.setActiveType(Gpio.ACTIVE_LOW);
            mAGpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
            mAGpio.registerGpioCallback(mGpioCallback);

            mBGpio = manager.openGpio(B_GPIO_NAME);
            mBGpio.setDirection(Gpio.DIRECTION_IN);
            mBGpio.setActiveType(Gpio.ACTIVE_LOW);
            mBGpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
            mBGpio.registerGpioCallback(mGpioCallback);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //分别创建A字母按键和B字母按键输入驱动实例
        mADriver = InputDriver.builder(InputDevice.SOURCE_CLASS_BUTTON).setName(A_DRIVER_NAME)
                .setVersion(A_DRIVER_VERSION).setKeys(new int[]{A_KEY_CODE}).build();
        mBDriver = InputDriver.builder(InputDevice.SOURCE_CLASS_BUTTON).setName(B_DRIVER_NAME)
                .setVersion(B_DRIVER_VERSION).setKeys(new int[]{B_KEY_CODE}).build();
       
        //注册A字母按键和B字母按键输入驱动
        mUserDriverManager = UserDriverManager.getManager();
        mUserDriverManager.registerInputDriver(mADriver);
        mUserDriverManager.registerInputDriver(mBDriver);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mAGpio != null) {
            try {
                mAGpio.unregisterGpioCallback(mGpioCallback);
                mAGpio.close();
                mAGpio = null;
            } catch (IOException e) {
                Log.w(TAG, "Unable to close GPIO", e);
            }
        }

        if (mBGpio != null) {
            try {
                mBGpio.unregisterGpioCallback(mGpioCallback);
                mBGpio.close();
                mBGpio = null;
            } catch (IOException e) {
                Log.w(TAG, "Unable to close GPIO", e);
            }
        }
        
        //当你不在需要关键事件的时候注销驱动
        mUserDriverManager.unregisterInputDriver(mADriver);
        mUserDriverManager.unregisterInputDriver(mBDriver);
    }

    private void triggerEvent(InputDriver inputDriver, boolean pressed, int keyCode) {
       int action = pressed ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
        KeyEvent[] events = new KeyEvent[]{new KeyEvent(action, keyCode)};
        //使用emit()方法转换成Android事件
        if (!inputDriver.emit(events)) {
            Log.w(TAG, "Unable to emit key event");
        }
    }
}

InputDemo\app\src\main\java\com\chengxiang\inputdemo\MainActivity.java

public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();
    private EditText mEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mEditText = (EditText) findViewById(R.id.edittext);
        //这里我们将输入焦点放在输入框中,故按下开关按钮会输入A和B字母
        mEditText.requestFocus();
    }

    //在前台Activity通过实现onKeyDown()、onKeyUp()和onGenericMotionEvent()方法来获取相关事件
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        Log.d(TAG,"onKeyUp:"  + keyCode);
        return true;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.d(TAG,"onKeyDown:"  + keyCode);
        return true;
    }

    public void toNext(View view) {
        Intent intent = new Intent(this,NextActivity.class);
        startActivity(intent);
    }
}

4. 运行结果
点击开关按钮,在输入框中会输入对应的A和B字母。

搭建电路 按下按钮输入

1.抛弃各种找元器件的烦恼,来“1024工场”旗舰店,一次性买到你所想要的:树莓派套装—专为Android Things打造。

树莓派套装
电脑用户,点击如下链接进入淘宝宝贝页面:
https://item.taobao.com/item.htm?spm=686.1000925.0.0.3f11c9ed68fPu7&id=549263158263
手机用户,打开淘宝客户端扫描二维码:
宝贝二维码
2.完整和持续更新的《使用Android打开物联网开发大门——Andoid Thigns开发》文档,欢迎大家阅读!
https://www.kancloud.cn/workshop1024/android_things_develop/360773
这里写图片描述
3.新技术,新未来!欢迎大家关注“1024工场”微信服务号,时刻关注我们的最新的技术讯息。(甭客气!尽情的扫描或者长按!)
服务号
4.加入“Android Things开发”QQ讨论群,一起学习一起Hi。(甭客气!尽情的扫描或者长按!)
qq群
上一篇 下一篇

猜你喜欢

热点阅读