Android Things:用户驱动-输入驱动
一、驱动介绍
输入用户驱动程序为应用程序提供接口,向Android的输入管道注入事件。有了这个API,应用程序可以使用Peripheral I/O模拟一个人机界面的设备(HID)或者连接外部硬件到输入系统。比如说,我们可以使用开关按钮GPIO的信号输入,通过输入驱动API模拟呈键盘上按键的输入事件,下面我们会具体演示如何实现。
二、使用步骤
实现输入用户驱动,有如下步骤:
1.创建驱动:使用InputDriver.Builder和源类型SOURCE_CLASS_BUTTON创建一个新的输入驱动实例。
2.注册驱动:使用UserDriverManager的registerInputDriver()方法注册这个驱动。
public class TouchpadDriverService extends Service {// Driver parametersprivate static final String DRIVER_NAME = "Touchpad";private static final int DRIVER_VERSION = 1;private InputDriver mDriver;@Overridepublic 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 {@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {// Handle key pressed and repeated eventsreturn true;}@Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) {// Handle key released eventsreturn true;}@Overridepublic boolean onGenericMotionEvent(MotionEvent event) {// Handle motion input eventsreturn true;}
}
6.注销驱动:当你不在需要关键事件的时候注销驱动。
public class TouchpadDriverService extends Service {@Overridepublic void onDestroy() {super.onDestroy();UserDriverManager manager = UserDriverManager.getManager();manager.unregisterInputDriver(mDriver);}
}
三、案例展示
这里我们实现一个最简单的模拟键盘,通过两个开关按钮的GPIO信号输入,通过输入驱动API分别模拟键盘上a和b字母的输入。
1.硬件准备:
树莓派3开发板 1块
面包板 1块
按钮开关 2个
电阻 2个
杜邦线(母对公,公对公) 若干
广告时间咯:如果你还没有自己的开发板和元器件,到我们的“1024工场微店”来逛逛一逛吧(文章底部二维码),这里能一次性有买到你想要的!
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() {@Overridepublic 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;}@Overridepublic void onGpioError(Gpio gpio, int error) {Log.w(TAG, gpio + ": Error event " + error);}};public KeyDriverService() {}@Overridepublic 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);}@Overridepublic IBinder onBind(Intent intent) {// TODO: Return the communication channel to the service.throw new UnsupportedOperationException("Not yet implemented");}@Overridepublic 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;@Overrideprotected 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()方法来获取相关事件@Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) {Log.d(TAG,"onKeyUp:" + keyCode);return true;}@Overridepublic 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);}
}
代码库:https://github.com/ThingsDeveloper/inputdemo
4.运行结果:
点击开关按钮,在输入框中会输入对应的A和B字母。
电脑用户,点击如下链接进入淘宝宝贝页面:
https://item.taobao.com/item.htm?spm=686.1000925.0.0.3f11c9ed68fPu7&id=549263158263
手机用户,打开淘宝客户端扫描二维码:
https://www.kancloud.cn/workshop1024/android_things_develop/360773
Android Things:用户驱动-输入驱动相关推荐
- Linux按键输入实验(体验一下输入驱动,实际开发使用input子系统处理)
目录 Linux下按键驱动原理(使用原子操作) 硬件原理图分析 实验程序编写 修改设备树文件 按键驱动程序编写 编写测试APP(循环读取按键值) 运行测试 编译驱动程序和测试APP 运行测试(whil ...
- Android 平台电容式触摸屏的驱动基本原理
Android 平台电容式触摸屏的驱动基本原理 Android 平台电容式触摸屏硬件基本原理 Linux 与 Android 的多点触摸协议 Linux输入子系统:事件的编码 转载于:https:// ...
- Android深度探索--HAL与驱动开发----第五章读书笔记
第五章主要学习了搭建S3C6410开发板的测试环境.首先要了解到S3C6410是一款低功耗.高性价比的RISC处理器它是基于ARMI1内核,广泛应用于移动电话和通用处理等领域. 开发板从技术上说与我们 ...
- Android系统 linux内核按键驱动开发
Android系统 linux内核按键驱动开发 前言 刚入门的小白,在csdn的帮助下完成了第一个按键驱动,特写此文记录学习并分享给有需要的人. 1.修改设备树.dts 我是用的开发板是rp-rk32 ...
- Android MTK LCM Driver 屏驱动
Android MTK LCM Driver 屏驱动 ---- 屏驱动小结 手机驱动调试第一就是LCM,也就是我们说的LCD屏,因此要求驱动第一时间将确认和点亮.此篇就简单描述了在MTK 6765(A ...
- Android系统韦根调试从驱动到应用(二)
Android系统韦根调试从驱动到应用 软件开发平台:android P 源码. 硬件开发平台:nxp imx8m mini开发板. 本文记录在nxp 8m mini 硬件平台, androidP 源 ...
- android向windows推送驱动,Windows上安装完美的Android手机驱动
无论什么Android手机,若想和电脑进行连接,都必须在电脑上面安装Android手机的USB连接驱动,这个过程非常简单,以下是相关的流程: 眼尖的可以看到这个驱动是Desire的,其实驱动是通用的, ...
- android edittext输入邮箱,[Android教程]EditText怎样限制用户的输入?数字/字母/邮箱
有输入必有验证.为了防止用户随便输入确保提交数据的合法性,程序不得不在文本输入框(EditText)中增加限制或验证. 关于输入类型有数字.字母.邮箱.电话等形式,这些具体得根据业务来.那么Andro ...
- linux平台驱动运行空间,UIO(linux Userspace I/O子系统)用户空间设备驱动I/O技术介绍...
UIO(linux Userspace I/O子系统)用户空间设备驱动I/O技术介绍(由搜集整理) UIO(Userspace I/O)是运行在用户空间的I/O技术.Linux系统中一般的驱动设备都是 ...
最新文章
- 语义分割--DeconvNet--Learning Deconvolution Network for Semantic Segmentation
- vue 打包体积过大 实现懒加载 ????
- kafka抑制启动时的log INFO为WARN级别
- C# 对接微信支付时生成符合 RFC3339 标准的日期时间字符串
- Java 身份证工具类
- Python HTTP库:requests快速入门
- 用数组建立二叉树(LeetCode二叉树测试)
- 阿里P8架构师谈:如何搭建亿级并发系统的性能指标体系
- C#——SqlParameter的使用方法及注意事项
- 解决ubuntu与virtualbox共享文件夹访问权限问题
- Windows程序设计-位图和位块传输
- 绕过tp路由器管理密码_TP-Link路由器登录密码怎么重置【详细介绍】
- 暴力破解压缩包原理及方法
- BeyondCompare的三种破解方法
- UVM jelly_bean
- linux 把进程调到前台,【如何将后台运行的程序转到前台来?】
- 基于Hashids的高效游戏礼包兑换码系统完整设计
- 只要有心,学好Linux并非难事
- MATLAB绘制正弦函数与余弦函数的线性组合曲线
- 使用do-while结构计算常数e的值。
热门文章
- 安装Python 出现0x80072f7d错误的解决办法
- 比较容易考前计算机好的985大学,容易考的985有哪些?附性价比高的985大学排名...
- 024空格沙悟净死亡
- How to deploy the apk file on your Android Phon...
- SQLSERVER 多表联合查询(join)
- mysql多表联合查询练习题
- waterdrop(token方式)连接星环科技云平台tdc(kerberos认证)
- Android 利用系统下载管理器下载apk
- Linux——Linux驱动之设备树下platform总线驱动编写实战(手把手教你设备树下platform总线利用GPIO控制蜂鸣器完整实现过程)
- WindowManager