前言

接触到的扫描设备分为三类:1)-usb或其它方式转串口,常规的打开读取串口即可;2)-usb模拟键盘输入模式,这种模式底层不是串口;3)原生串口模式,最简单,但这种接口普通手机没有。

本文只介绍第二种USB键入模式,通过USB设备查找、匹配、打开、数据读这个流程,可以先于并阻止安卓系统获得内容,就是说如果是后台进程这样读取后,安卓输入框中不会显示扫描到的内容

设备特点

USB接入方式、即插即用不需要驱动、可以在任意输入框内扫描并“输入”字符串、最后回车。例如,打开一个文本编辑器并处于活动状态,刷卡后可以看到就像键盘输入了一样,得到10位长度的卡号、回车。

就是说这种设备的接入一般是不需要编程的,但是问题就在于它输出的内容也无法控制,就像是用户在通过一个键盘输入。

拦截这种设备需求的产生

如果你想在“用户输入”的内容上做一些处理怎么办?要么是响应键盘输入事件,要么是像本文一样直接拦截USB数据流。

先看一下运行效果

(注意:这里有个USB安全提示,一般设备都是无法去除的,在订制机或者拥有系统签名的情况下才能去除)

流程核心代码:

1,获得USB管理器:

        usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);if (usbManager == null) {this.mainHandler.obtainMessage(MainHandler.WHAT_SHOW_MESSAGE, "无法获得USB服务").sendToTarget();return false;}

2,匹配特定的设备:

        //获得所有USB设备HashMap<String, UsbDevice> usbDeviceMap = usbManager.getDeviceList();if (usbDeviceMap.size() == 0) {this.mainHandler.obtainMessage(MainHandler.WHAT_SHOW_MESSAGE, "找不到USB设备").sendToTarget();return false;}for (final UsbDevice device : usbDeviceMap.values()) {Log.d(tag, "USB:pid=" + device.getProductId() + " vid=" + device.getVendorId());if (USB_DEV_PID == device.getProductId() && USB_DEV_VID == device.getVendorId()) {this.mainHandler.obtainMessage(MainHandler.WHAT_SHOW_MESSAGE, "已找到USB读卡器").sendToTarget();targetUsb = device;break;}}

3,打开USB连接

                usbDeviceConnection = usbManager.openDevice(targetUsb);if (usbDeviceConnection == null) {mainHandler.obtainMessage(MainHandler.WHAT_USB_ERROR, "打开USB设备失败").sendToTarget();return;}UsbInterface usbInterface = targetUsb.getInterface(0);if (!usbDeviceConnection.claimInterface(usbInterface, true)) {mainHandler.obtainMessage(MainHandler.WHAT_USB_ERROR, "不是已知协议的USB设备,无法使用").sendToTarget();return;}

4,开始读取

                ArrayList<Byte> listBytes = new ArrayList<>();byte[] buffer = new byte[maxPackageSize];UsbEndpoint inEndpoint = usbInterface.getEndpoint(0);mainHandler.obtainMessage(MainHandler.WHAT_READING, "读取准备就绪,请刷卡").sendToTarget();deviceReading = true;while (!Thread.interrupted()) {int ret = usbDeviceConnection.bulkTransfer(inEndpoint, buffer, buffer.length, 200);if (ret > 0) {byte[] reab = new byte[ret];System.arraycopy(buffer, 0, reab, 0, ret);//Log.d(tag, "读取到:" + bytesToHexString(reab));//字节流断句for (byte ab : reab) {if (ab == (byte) 0x28) {if (listBytes.size() > 0) {Byte[] lineBytes = listBytes.toArray(new Byte[0]);getCarCodeBytes(ArrayUtils.toPrimitive(lineBytes));listBytes.clear();}} else if (ab != (byte) 0x00) {listBytes.add(ab);}}}}

5,解析字节原理

读取到的字节为USB-键值,对照表如下(设备不会输出其它值,故只列出相关部分):

1E Keyboard 1
1F Keyboard 2
20 Keyboard 3
21 Keyboard 4
22 Keyboard 5
23 Keyboard 6
24 Keyboard 7
25 Keyboard 8
26 Keyboard 9
27 Keyboard 0

6,解析方法:

private void decode(byte[] bytes) {//转换时,可以直接一一对照,我这里用简单的减法StringBuilder intString = new StringBuilder();for (byte ab : bytes) {//按字节循环//如果0x27,由于它的10进制是39,减去29是10,所以单独处理if (ab == (byte) 0x27) intString.append(0);//其它都是化为10进制后减去起始值29得到对应值else intString.append(ByteTools.byteToInt(ab) - 29);}String hex = Long.toHexString(Long.parseLong(intString.toString()));//TODO 获得字符串后继续其它业务
}

硬件及安卓源码

完整项目下载见我的资源《《USB读卡器安卓源码》》。

测试需要设备

1,读卡器可以到TB搜索USB读卡器,或者直接扫描我图片里的二维码,找类似的就行,只要是这种方式的都一样。

2,公头小口转母口大口的USB,TYPE-c或者MicroUsb的就看测试用的手机了。

文章写的有点糙,因为是两个版本的原因,改来改去都不满意,最后直接上全部代码,Android Studio项目整体压缩的,直接打开就行了。

注意,使用USB设备时如果没有系统权限,需要申请USB使用权限。

安卓源码:拦截USB-HID协议内容(模拟键盘输入方式的读卡器)相关推荐

  1. USB HID 协议

    USB HID 协议入门 转载请注明来源:cuixiaolei的技术博客 USB HID设备类的应用场合 USB HID类是USB设备的一个标准设备类,包括的设备非常多.HID类设备定义它属于人机交互 ...

  2. 安卓源码AOSP下载使用的正确姿势

    安卓源码AOSP下载使用的正确姿势 从同步源码到编译完成,整个过程应至少准备200G空间. 编译时需要的内存数与编译线程数相关,博主实测比较极限的配置是4核8G,超过这个范围将触发swap交换导致编译 ...

  3. 【源码篇】安卓源码解析(持续总结)

    前言 在Linux中,一切皆为文件.安卓底层也是基于Linux开发的. 在我们了解源码目录的时候,我们要先知道这些源码的后缀名代表的是什么文件,什么意思,才能更好的去了解其中的原理. 文章目录 前言 ...

  4. windows编译安卓源码记录

    环境 Windows10 + vmware17 + ubuntu22 ubuntu环境设置 装完ubuntu系统后拖拽复制文件进去验证vmtools功能情况,如果vmtools异常很麻烦,试了n多方法 ...

  5. 安卓源码(一)下载与同步

    推荐系统:基于Debian8的Linux发行版,ubuntu16.04,(因为安卓源码实在ubuntu下编译的,redhat系没有) 我使用的系统:Deepin15.3(ubuntu是debian8 ...

  6. 安卓与单片机进行usb hid通信

    安卓USB_HID通信文档 因为一直在研究stm32,需要用到usb hid通信,就研究了安卓与stm32进行usb hid通信,目前已经能进行正常通信,我这里只跟大家说一下通信时需要注意的问题. u ...

  7. 直播源码中有哪些网络协议需要注意?

    在当今的直播平台中,对直播源码越来越注重.那么直播源码中有哪些网络协议需要注意的呢? 1.TCP:TCP为点对点的协议,虽然能保证了数据传输的可靠性,但是对服务器资源耗费较大,在数据流大的场合难以保证 ...

  8. 安卓编译安装python_安卓源码编译环境搭建

    本编译环境以 Ubuntu 14.04 系统为例 修改软件源(可选) 安装相关依赖 安装Android编译工具JDK 一. 修改软件源(可选) : sudo gedit /etc/apt/source ...

  9. mac下编译安卓源码

    资源 Mac OS10.12 编译Android源码8.1 aosp编译-需翻墙 Mac下编译安卓源码 手把手教你在Mac OS下载.编译及导入Android源码 步骤 准备 磁盘空间大于180G 安 ...

最新文章

  1. C++ 中 inline 用法概述
  2. 基于springboot实现的仓储管理系统
  3. linux - word frequency
  4. jzoj6065-[NOI2019模拟2019.3.18]One?One!【FFT】
  5. UIKit应用 - Swift 版本: 3.让UITableViewCell的背景色渐变
  6. js php 中文乱码怎么解决_php中文乱码怎么解决
  7. Java IO类库之CharArrayWriter
  8. 【堆】这是要搞事情啊——取出
  9. linux ssh 推送文件_通过SSH实现Windows与linux之间传输文件
  10. Node.js跨域请求解决方案
  11. HP 8770W windows10 1803 安装 HP 3D DriveGuard
  12. 2021年华为Java面经,顺利收获Offer
  13. java+mysq 基于jsp825幼儿园管理系统(java,web)
  14. 某种家庭式光伏发电系统设计
  15. 一文彻底搞懂加密、数字签名和数字证书,看不懂你打我!
  16. 局域网之间两台计算机同屏,spacedesk解决两台电脑同屏的问题
  17. 人工智能技术应用的领域主要有哪些?
  18. excel 筛选 粘贴_在筛选的Excel列表中粘贴快捷方式
  19. Gerrit 2.11.5 发布,代码评审工具
  20. Xilinx的FPGA手册中关于如何Booting RFSoCsZynq

热门文章

  1. 千匠星云数字化解决方案介绍 | 品牌官网数字化升级解决方案
  2. 【B站商品搜索】快速了解平台商品需求,全方位解读爆款商品数据!
  3. 学校老师可以批量查询学生考试成绩
  4. Camera保存的图片在Gallery2中找不到
  5. 联想指纹识别程序报错处理
  6. 如何提高企业的培训效果
  7. 嵌入式分享合集123
  8. Android安全开发之浅谈加密算法的坑
  9. PS显示不能完成请求,因为没有足够内存(RAM)
  10. 解决Linux关机重启连不上网的异常