Android硬件通信之 USBManager通信
一 简介
1.1 USB是一种常见的设备端接口,在PC端,移动端等上面应用非常的广泛,这就涉及到USB设备与主机端的通信。下面就讲下Android设备上的USB通信流程。
1.2 在android提供了USBManager接口来管理USB设备,USBManager类是Android系统管理USB设备与操作的核心组件,涉及设备识别、权限请求、数据传输、事件监听等。通过USBManager,开发者可以实现设备模式切换、USB权限管理、配置选择、自定义USB驱动程序开发以及支持MIDI和音频设备的管理。
二 USBManager通信流程
2.1 添加USB权限和特性声明
<uses-permission android:name="android.permission.USB_PERMISSION" />
<uses-feature android:name="android.hardware.usb.host" />
2.2 初始化USB通信
//设备管理器
private UsbManager usbManager;
//连接的设备
private UsbDevice currentDevice = null;
//连接状态类
private UsbDeviceConnection connection;
//USB连接接口
private UsbInterface usbInterface;
//请求权限
private String ACTION_USB_PERMISSION = "com.your.package.USB_PERMISSION";
private BroadcastReceiver mUsbBroadcast;
/**
* USB请求权限
*/
private class UsbBroadcast extends BroadcastReceiver {
public void onReceive(Context paramAnonymousContext, Intent paramAnonymousIntent) {
try {
String action = paramAnonymousIntent.getAction();
// 判断广播类型
if (ACTION_USB_PERMISSION.equals(action)) {
try {
// 如果用户同意,则对读写器进行操作
connectDevice();
} catch (Exception e) {
disconnectDevice();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.3 注册USB广播接收器
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(usbReceiver, filter);
2.4 搜索USB设备
/**
* 获取Usb列表
* @return
*/
public List<UsbDevice> getUsbPrinters() {
List<UsbDevice> usbDevices = new ArrayList<>();
usbManager = (UsbManager) App.getContext().getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
if (isCscidDevice(device)) {
usbDevices.add(device);
}
}
return usbDevices;
}
/**
* 判断UsbDevice 是否为读卡器类型设备
* @param device
* @return true:读卡器设备
*/
public boolean isCscidDevice(UsbDevice device) {
if (device == null) {
return false;
}
if (device.getInterfaceCount() == 0) {
return false;
}
for (int i = 0; i < device.getInterfaceCount(); i++) {
android.hardware.usb.UsbInterface usbInterface = device.getInterface(i);
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
int productId = device.getProductId();
int vendorId = device.getVendorId();
if (productId == 10203 && vendorId == 5824) {
return true;
}
}
}
return false;
}
2.5 请求权限,并连接设备
/**
* 连接设备
*/
public void connectDevice() {
try {
//权限请求
/*
* 在使用USB读写器设备前,应用必须获得权限。
* 为了确切地获得权限,首先需要创建一个广播接收器。在调用requestPermission()这个方法时从得到的广播中监听这个意图。
* 通过调用requestPermission()这个方法为用户跳出一个是否连接该设备的对话框。
*/
if (mUsbBroadcast == null) {
mUsbBroadcast = new UsbBroadcast();
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
App.getContext().registerReceiver(mUsbBroadcast, filter);
}
//获取全部设备
if (currentDevice == null) {
List<UsbDevice> usbDeviceList = getUsbPrinters();
if (usbDeviceList.size() > 0) {
currentDevice = usbDeviceList.get(0);
}
}
if (currentDevice != null) {
// 检查设备是否具有所需的权限
if (usbManager.hasPermission(currentDevice)) {
// 打开设备并进行通信
if (connection == null) {
connection = usbManager.openDevice(currentDevice);
}
if (connection != null) {
// 获取接口并配置
if (usbInterface == null) {
usbInterface = currentDevice.getInterface(0);
}
connection.claimInterface(usbInterface, true);
// 你可以在这里与设备进行通信
//readDataFromDevice();
Log.d(TAG, "连接到设备: " + currentDevice.getDeviceName());
} else {
Log.e(TAG, "无法打开设备: " + currentDevice.getDeviceName());
}
} else {
// 如果没有则请求权限
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(JuAiApp.getContext(), 0,
new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE);
usbManager.requestPermission(currentDevice, mPermissionIntent);
}
}
} catch (Exception r) {
r.printStackTrace();
}
}
2.6 发送数据,先获取UsbEndpoint输出流端点
/**
* 发送数据
*
* @param message
*/
UsbEndpoint endpointOut = null;
private void sendDataToDevice(String message) {
// 获取输出端点
if (endpointOut == null) {
for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
UsbEndpoint endpoint = usbInterface.getEndpoint(i);
if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK &&
endpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
endpointOut = endpoint; // 获取输出端点
break;
}
}
}
if (endpointOut == null || connection == null) {
Log.e(TAG, "输出端点或连接未初始化");
return;
}
byte[] buffer = message.getBytes(); // 将要发送的字符串转换为字节数组
int bytesSent = connection.bulkTransfer(endpointOut, buffer, buffer.length, 1000); // 1秒超时
if (bytesSent < 0) {
Log.e(TAG, "发送数据失败");
} else {
Log.d(TAG, "成功发送数据: " + message);
}
}
2.7 读取数据,先获取输入流端点
/**
* 读取数据
*/
UsbEndpoint endpointIn = null;
private static final int BUFFER_SIZE = 1024; // 定义读取的缓冲区大小
private void readDataFromDevice() {
if (endpointIn == null) {
// 获取输入端点
for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
UsbEndpoint endpoint = usbInterface.getEndpoint(i);
Log.e(TAG, "readDataFromDevice: " + endpoint.getType());
Log.e(TAG, "getDirection: " + endpoint.getDirection());
if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_INT &&
endpoint.getDirection() == UsbConstants.USB_DIR_IN) {
endpointIn = endpoint; // 获取输入端点
break;
}
}
}
if (endpointIn == null || connection == null) {
Log.e(TAG, "输入端点或连接未初始化");
return;
}
byte[] buffer = new byte[BUFFER_SIZE]; // 创建缓冲区
// 循环读取数据
Thread readThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
int bytesRead = connection.bulkTransfer(endpointIn, buffer, buffer.length, 1000); // 1秒超时
if (bytesRead > 0) {
// 处理读取到的数据
String data = new String(buffer, 0, bytesRead); // 将字节数组转换为字符串
Log.d(TAG, "读取数据: " + data);
} else if (bytesRead == 0) {
Log.d(TAG, "没有更多数据可读");
break;
} else {
Log.e(TAG, "读取数据失败: " + bytesRead);
break;
}
}
}
});
readThread.start(); // 启动读取线程
}
2.8 断开USB设备并关闭资源
/**
* 断开设备
*/
public void disconnectDevice() {
try {
if (usbManager != null && currentDevice != null && usbInterface != null) {
// 获取之前连接的接口
// 释放接口
connection.releaseInterface(usbInterface);
// 关闭连接
connection.close();
// 清空连接
connection = null;
usbInterface = null;
//读取置空
endpointIn = null;
//写入置空
endpointOut = null;
//设备置空
currentDevice = null;
if (mUsbBroadcast != null) {
App.getContext().unregisterReceiver(mUsbBroadcast);
}
Log.d(TAG, "设备已断开: ");
}
} catch (Exception e) {
e.printStackTrace();
}
}
三 USB协议相关概念
3.1 USB常见类型,用于判断是哪种USB设备
//获取设备类型
for (int i = 0; i < device.getInterfaceCount(); i++) {
android.hardware.usb.UsbInterface usbInterface = device.getInterface(i);
/**
* 设备类 ID 设备类名称 描述
* 0x01 Audio 音频设备,如 USB 音频接口。
* 0x02 Communications 通信设备,如调制解调器和网络适配器。
* 0x03 HID (Human Interface Device) 人机接口设备,通常指键盘、鼠标等。
* 0x05 Physical Interface Device 物理接口设备,通常用于各种控制设备。
* 0x06 Image 图像设备,如 USB 摄像头和扫描仪。
* 0x07 Printer 打印机设备。
* 0x08 Mass Storage 大容量存储设备,如 USB 闪存驱动器和外部硬盘。
* 0x09 Hub USB 集线器。
* 0x0A CDC (Communications Device Class) 通信设备类,常用于调制解调器和串行口。
* 0x0B Smart ICCard 智能卡读卡器。
* 0x0D Content Security Device 内容保护设备,用于安全性应用。
* 0x0E Video 视频设备,如视频采集卡。
* 0xEF Miscellaneous 其他不属于上述类别的设备。
* 0xFF Vendor Specific 厂商自定义设备,通常特定于某个硬件厂商的设备。
* @param deviceClass
* @param deviceSubclass
* @param deviceProtocol
* @return
*/
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
int productId = device.getProductId();
int vendorId = device.getVendorId();
if (productId == 10203 && vendorId == 5824) {
return true;
}
}
}
ID | 设备类名称 | 描述 | |
0x01 | Audio | 音频设备,如 USB 音频接口。 | |
0x02 | Communications | 通信设备,如调制解调器和网络适配器。 | |
0x03 | HID(Human Interface Device) | 人机接口设备,通常指键盘、鼠标等。 | |
0x05 | Physical Interface Device | 物理接口设备,通常用于各种控制设备。 | |
0x06 | Image | 图像设备,如 USB 摄像头和扫描仪。 | |
0x07 | Printer | 打印机设备。 | |
0x08 | Mass | 大容量存储设备,如 USB 闪存驱动器和外部硬盘。 | |
0x09 | Hub USB | 集线器。 | |
0x0A | CDC | 通信设备类,常用于调制解调器和串行口。 | |
0x0B | Smart ICCard | 智能卡读卡器。 | |
0x0D | Content Security Device | 内容保护设备,用于安全性应用。 | |
0x0E | Video | 视频设备,如视频采集卡。 | |
0x0F | Miscellaneous | 其他不属于上述类别的设备。 | |
0x0F | Vendor Specific | 厂商自定义设备,通常特定于某个硬件厂商的设 |
3.2 设备信息参数
//获取设备类型
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
//产品ID
int productId = device.getProductId();
//厂商ID
int vendorId = device.getVendorId();
if (productId == 10203 && vendorId == 5824) {
return true;
}
}
* DeviceName=/dev/bus/usb/005/007 USB端口名字 * ProductName=null 产品名字 * DeviceId=5007(0x138F) 设备ID * VendorId=5824(0x16C0) 厂商ID * ProductId=10203(0x27DB) 产品ID * DeviceClass=0 设备分类 * device Class 为0------------- * Interface.describeContents()=0 接口描述 * Interface.getEndpointCount()=2 接口端点数量 * Interface.getId()=0 ID接口 * Interface.getInterfaceClass()=3 接口数量 * anInterface.getInterfaceProtocol()=0 接口协议数量 * anInterface.getInterfaceSubclass()=0 * device Class 为0------end-------
四 示例代码
public class USBManagerUtils {
private static final String TAG = "USBManagerUtils";
private static USBManagerUtils mInstance;
public static USBManagerUtils getInstance() {
if (mInstance == null) {
synchronized (USBManagerUtils.class) {
if (mInstance == null) {
mInstance = new USBManagerUtils();
}
}
}
return mInstance;
}
//设备管理器
private UsbManager usbManager;
//连接的设备
private UsbDevice currentDevice = null;
//连接状态类
private UsbDeviceConnection connection;
//USB连接接口
private UsbInterface usbInterface;
//请求权限
private String ACTION_USB_PERMISSION = "com.your.package.USB_PERMISSION";
private BroadcastReceiver mUsbBroadcast;
/**
* USB请求权限
*/
private class UsbBroadcast extends BroadcastReceiver {
public void onReceive(Context paramAnonymousContext, Intent paramAnonymousIntent) {
try {
String action = paramAnonymousIntent.getAction();
// 判断广播类型
if (ACTION_USB_PERMISSION.equals(action)) {
try {
// 如果用户同意,则对读写器进行操作
connectDevice();
} catch (Exception e) {
disconnectDevice();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 获取Usb 打印机列表
* get USB printer list
*
* @return
*/
public List<UsbDevice> getUsbPrinters() {
List<UsbDevice> usbDevices = new ArrayList<>();
usbManager = (UsbManager) App.getContext().getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
if (isCscidDevice(device)) {
usbDevices.add(device);
}
}
return usbDevices;
}
/**
* 判断UsbDevice 是否为读卡器类型设备
* check a UsbDevice
* DeviceName=/dev/bus/usb/005/007
* ProductName=null
* DeviceId=5007(0x138F)
* VendorId=5824(0x16C0)
* ProductId=10203(0x27DB)
* DeviceClass=0
* device Class 为0-------------
* Interface.describeContents()=0
* Interface.getEndpointCount()=2
* Interface.getId()=0
* Interface.getInterfaceClass()=3
* anInterface.getInterfaceProtocol()=0
* anInterface.getInterfaceSubclass()=0
* device Class 为0------end-------
*
* @param device
* @return true:读卡器设备
* 对于同一型号的USB产品,其 vendorId 和 productId 通常是一致的,因为它们来自同一个制造商且属于同一产品系列。例如,如果一个制造商生产了一个特定的USB闪存驱动器型号,那么该型号的所有设备都会共享相同的 vendorId 和 productId。
*/
public boolean isCscidDevice(UsbDevice device) {
if (device == null) {
return false;
}
if (device.getInterfaceCount() == 0) {
return false;
}
for (int i = 0; i < device.getInterfaceCount(); i++) {
android.hardware.usb.UsbInterface usbInterface = device.getInterface(i);
/**
* 设备类 ID 设备类名称 描述
* 0x01 Audio 音频设备,如 USB 音频接口。
* 0x02 Communications 通信设备,如调制解调器和网络适配器。
* 0x03 HID (Human Interface Device) 人机接口设备,通常指键盘、鼠标等。
* 0x05 Physical Interface Device 物理接口设备,通常用于各种控制设备。
* 0x06 Image 图像设备,如 USB 摄像头和扫描仪。
* 0x07 Printer 打印机设备。
* 0x08 Mass Storage 大容量存储设备,如 USB 闪存驱动器和外部硬盘。
* 0x09 Hub USB 集线器。
* 0x0A CDC (Communications Device Class) 通信设备类,常用于调制解调器和串行口。
* 0x0B Smart ICCard 智能卡读卡器。
* 0x0D Content Security Device 内容保护设备,用于安全性应用。
* 0x0E Video 视频设备,如视频采集卡。
* 0xEF Miscellaneous 其他不属于上述类别的设备。
* 0xFF Vendor Specific 厂商自定义设备,通常特定于某个硬件厂商的设备。
* @param deviceClass
* @param deviceSubclass
* @param deviceProtocol
* @return
*/
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
int productId = device.getProductId();
int vendorId = device.getVendorId();
if (productId == 10203 && vendorId == 5824) {
return true;
}
}
}
return false;
}
/**
* 连接设备
*/
public void connectDevice() {
try {
//权限请求
/*
* 在使用USB读写器设备前,应用必须获得权限。
* 为了确切地获得权限,首先需要创建一个广播接收器。在调用requestPermission()这个方法时从得到的广播中监听这个意图。
* 通过调用requestPermission()这个方法为用户跳出一个是否连接该设备的对话框。
*/
if (mUsbBroadcast == null) {
mUsbBroadcast = new UsbBroadcast();
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
App.getContext().registerReceiver(mUsbBroadcast, filter);
}
//获取全部设备
if (currentDevice == null) {
List<UsbDevice> usbDeviceList = getUsbPrinters();
if (usbDeviceList.size() > 0) {
currentDevice = usbDeviceList.get(0);
}
}
if (currentDevice != null) {
// 检查设备是否具有所需的权限
if (usbManager.hasPermission(currentDevice)) {
// 打开设备并进行通信
if (connection == null) {
connection = usbManager.openDevice(currentDevice);
}
if (connection != null) {
// 获取接口并配置
if (usbInterface == null) {
usbInterface = currentDevice.getInterface(0);
}
connection.claimInterface(usbInterface, true);
// 你可以在这里与设备进行通信
//readDataFromDevice();
Log.d(TAG, "连接到设备: " + currentDevice.getDeviceName());
} else {
Log.e(TAG, "无法打开设备: " + currentDevice.getDeviceName());
}
} else {
// 如果没有则请求权限
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(App.getContext(), 0,
new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE);
usbManager.requestPermission(currentDevice, mPermissionIntent);
}
}
} catch (Exception r) {
r.printStackTrace();
}
}
/**
* 发送数据
*
* @param message
*/
UsbEndpoint endpointOut = null;
private void sendDataToDevice(String message) {
// 获取输出端点
if (endpointOut == null) {
for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
UsbEndpoint endpoint = usbInterface.getEndpoint(i);
if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK &&
endpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
endpointOut = endpoint; // 获取输出端点
break;
}
}
}
if (endpointOut == null || connection == null) {
Log.e(TAG, "输出端点或连接未初始化");
return;
}
byte[] buffer = message.getBytes(); // 将要发送的字符串转换为字节数组
int bytesSent = connection.bulkTransfer(endpointOut, buffer, buffer.length, 1000); // 1秒超时
if (bytesSent < 0) {
Log.e(TAG, "发送数据失败");
} else {
Log.d(TAG, "成功发送数据: " + message);
}
}
/**
* 读取数据
*/
UsbEndpoint endpointIn = null;
private static final int BUFFER_SIZE = 1024; // 定义读取的缓冲区大小
private void readDataFromDevice() {
if (endpointIn == null) {
// 获取输入端点
for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
UsbEndpoint endpoint = usbInterface.getEndpoint(i);
Log.e(TAG, "readDataFromDevice: " + endpoint.getType());
Log.e(TAG, "getDirection: " + endpoint.getDirection());
if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_INT &&
endpoint.getDirection() == UsbConstants.USB_DIR_IN) {
endpointIn = endpoint; // 获取输入端点
break;
}
}
}
if (endpointIn == null || connection == null) {
Log.e(TAG, "输入端点或连接未初始化");
return;
}
byte[] buffer = new byte[BUFFER_SIZE]; // 创建缓冲区
// 循环读取数据
Thread readThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
int bytesRead = connection.bulkTransfer(endpointIn, buffer, buffer.length, 1000); // 1秒超时
if (bytesRead > 0) {
// 处理读取到的数据
String data = new String(buffer, 0, bytesRead); // 将字节数组转换为字符串
Log.d(TAG, "读取数据: " + data);
} else if (bytesRead == 0) {
Log.d(TAG, "没有更多数据可读");
break;
} else {
Log.e(TAG, "读取数据失败: " + bytesRead);
break;
}
}
}
});
readThread.start(); // 启动读取线程
}
/**
* 断开设备
*/
public void disconnectDevice() {
try {
if (usbManager != null && currentDevice != null && usbInterface != null) {
// 获取之前连接的接口
// 释放接口
connection.releaseInterface(usbInterface);
// 关闭连接
connection.close();
// 清空连接
connection = null;
usbInterface = null;
//读取置空
endpointIn = null;
//写入置空
endpointOut = null;
//设备置空
currentDevice = null;
if (mUsbBroadcast != null) {
App.getContext().unregisterReceiver(mUsbBroadcast);
}
Log.d(TAG, "设备已断开: ");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
五 注意事项
5.1 对于同一型号的USB产品,其 vendorId 和 productId 通常是一致的,因为它们来自同一个制造商且属于同一产品系列。例如,如果一个制造商生产了一个特定的USB闪存驱动器型号,那么该型号的所有设备都会共享相同的 vendorId 和 productId。
5.2 扫码枪usb插拔时,会造成Activity重新加载,说明对Activity生命周期有影响,需要处理一下。
可在Activity配置
android:configChanges="orientation|keyboard|keyboardHidden"
六 使用场景举例-扫码枪设备
6.1 Android端获取扫码枪数据一般有如下三种获取方式
- USB键盘模式,自感模式(出厂默认):大多数扫码枪是模拟键盘进行输入(不支持包含有汉字的二维码),大多数时候需要使用带焦点的 EditText 接收其扫描的信息。设置一个带焦点的EditText进行接收,此方式容易漏读扩展的ASCII码数据,除非二维码是标准的ASCII码(1-128)。由于扫码枪会将扫描出来的内容转化为键盘事件,对应的就是Android中的KeyEvent事件,所以我们只需要在我们的activity中重写dispatchKeyEvent方法,即可获取相应事件。
- 通过 USB COM连接扫码:发送扫码开关指令进行扫码,即基于Usb相关类控制扫码开关
- USB串口自感模式:即串口连接(当扫码枪使用 USB 通讯接口,但主机应用程序是采用串口通讯方式接收数据),客户端只负责监听读取数据,无须控制扫码枪指令,需要依赖usb串口传输数据的第三方库:https://github.com/mik3y/usb-serial-for-android
6.2 USB键盘模式使用
/**
* usb键盘模式扫码示例,无需EditText接收
*/
public class ScannerUsbKeyboardActivity extends AppCompatActivity {
UsbKeyboardAutoScan usbKeyboardAutoScan;
EditText et_barcode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scanner_usb_keyboard_activity);
et_barcode = findViewById(R.id.et_barcode);
usbKeyboardAutoScan = new UsbKeyboardAutoScan();
usbKeyboardAutoScan.setOnScanListener(new OnScanListener() {
@Override
public void onScanSuccess(String barcode) {
//扫码接收
et_barcode.setText(barcode);
}
});
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (usbKeyboardAutoScan.isIntercept()
&& event.getKeyCode() != KeyEvent.KEYCODE_BACK) {//不处理返回键
usbKeyboardAutoScan.analysisKeyEvent(event);
return true;//防止输入框接收事件
}
return super.dispatchKeyEvent(event);
}
@Override
protected void onDestroy() {
super.onDestroy();
usbKeyboardAutoScan.cancel();
}
}
6.3 USB串口自感模式使用
/**
* 基于usb扫码
*/
public class ScannerUsbActivity extends AppCompatActivity {
BaseUsbScan usbScan;
EditText et_barcode;
UsbConfig usbConfig = new UsbConfig();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scanner_usb_activity);
et_barcode = findViewById(R.id.et_barcode);
usbConfig.setProductId(1233);
usbConfig.setVendorId(1234);
// usbScan = new UsbCmdScan(this); //通过usb连接扫码, 发送命令扫码
UsbConfig.SerialPortConfig serialPortConfig = new UsbConfig.SerialPortConfig();
usbConfig.setSerialPortConfig(serialPortConfig);
usbScan = new UsbComAutoScan(this);//通过usb转串口,自感模式,推荐
usbScan.setOnScanListener(new OnScanListener() {
@Override
public void onScanSuccess(String barcode) {
}
});
}
public void listUsbDevice(View view) {
//找到设备插入的usb孔对应UsbDevice
List<UsbDevice> usbDevices = usbScan.getUsbDevices(this);
for (UsbDevice device : usbDevices) {
et_barcode.setText(et_barcode.getText() + "\n" + device.getDeviceName() + ",vendorID:" + device.getVendorId() + ",ProductId:" + device.getProductId());
}
}
public void openUsbScan(View view) {
int ret = usbScan.openScan(usbConfig);
if (ret != 0) {
showMsg("打开usb扫码失败,ret" + ret);
} else {
showMsg("打开usb扫码成功");
}
}
private void showMsg(String s) {
et_barcode.setText(s);
}
public void closeUsbScan(View view) {
usbScan.closeScan();
}
public void loopScan(View view) {
usbScan.startReading();
}
public void stopLoopScan(View view) {
usbScan.stopReading();
}
@Override
protected void onDestroy() {
super.onDestroy();
usbScan.closeScan();
}
}