USB扫码获取数据流的实现方式

电汽锅USB扫码获取数据流的实现⽅式
硬件条件:
1. OTG接⼝转换器(或者⾃带usb接⼝的设备(⼤头))
2. USB扫码(⽀持USB虚拟串⼝)
3. 安卓设备
实现⽅式:
1. 串⼝⽅式
2. USB⽅式
使⽤场景:
汽车脚垫制造设备在扫码连接机器的时候,当扫码扫描到内容时,获取扫描到的内容。
解决的问题:
之前扫码使⽤的是USB模式(即扫描到的内容会直接输⼊到EditText之中,并且末尾会增加⼀个回车键),但是后来发现,当⼆维码包含中⽂的时候,中⽂不会输出进来,于是乎,使⽤以上两种⽅式实现。
实现思路:
连接扫码,因为数据肯定是以字节流的⽅式发送的,那么我们只需获取到输⼊的字节流,⾃⼰处理成需要的内容就可以了。
实现⽅式------串⼝⽅式:
需要经过以下⼏个步骤:
集成⾕歌原⽣serial_port包,参考该⽂章集成就可以了:
寻设备串⼝地址(这个咱们仅仅是为了获取串⼝地址,因为串⼝地址是固定的,所以这⾥可以不加在程序中,咱们⽬的是为了知道USB扫码的串⼝地址)
连接设备
获取数据流
步骤⼀:集成⾕歌原⽣serial_port包,这个⾃⼰看上⾯教程了。
步骤⼆:寻设备串⼝地址,在完成步骤⼀之后,会有⼀个SerialPortFinder的类,这个类的作⽤是寻咱们安卓设备上连接的串⼝设备(包括扫码),具体获取扫码串⼝地址的思路:获取未插⼊扫码时所有设备的串⼝地址------》获取插⼊扫码时所有设备的串⼝地址
-----》看看多出那个,多出的那个就是扫码的串⼝地址了,废话不多说,直接贴代码了:
case R.id.btn_print://获取所有串⼝设备地址,mFinder就是SerialPortFinder
StringBuffer stringBuffer = new StringBuffer();
for (String AllDevicesPath()) {
stringBuffer.append(str + "\n");
}
mTvMessage.String());
break;
步骤三:连接设备:
废不多讲,⾸先咱们连接到串⼝设备,如果你连接不上,那么就是步骤⼀有问题,请到步骤⼀那篇博客问问作者:
private String mSerialPath = "/dev/ttyUSB0" ;//物理串⼝地址,这个就是咱们步骤⼆到的地址了,这是我的设备的地址,你的⾃⼰去
private int baudrate = 9600;//波特率,这个是可以扫码⾃⼰设置的,看说明书
private SerialPort mSerialPort;
private InputStream mInputStream;
@Override
protected int getContentView() {
return R.layout.activity_test;
}
@Override
protected void initView() {
super.initView();
initSerialPort();
}
private void initSerialPort(){//连接串⼝设备,建议加try,硬件设备你永远不知道会为啥崩溃
try {
法律法规查询系统mSerialPort = new SerialPort(new File(mSerialPath),baudrate);
mInputStream = InputStream();
ReadThread thread = new ReadThread();//这是读取数据流的线程,代码在下⽅贴出
thread.start();//启动数据流读取线程
} catch (Exception e) {
e.printStackTrace();
}
}
步骤四:获取数据流,这时候步骤三,我们开启了⼀个线程读取扫码的数据流,这时候我写了⼀个死循环,轮询扫码发送的内容,线程代码如下
private InputStream mInputStream;
/**
* 读串⼝线程
*/
private class ReadThread extends Thread {//这是我的内部类,我代码习惯不好,别瞎鸡⼉抄
@Override
public void run() {
super.run();
while ((!Thread.currentThread().isInterrupted())) {
final int size;
try {
if (mInputStream == null)
return;
final byte[] buffer = new byte[512];
size = ad(buffer);//这就是扫描到的内容了
if (size > 0) {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
ToastUtils.makeText(TestActivity.this,new String(buffer,"GB2312"));//此处我设置的编码是GB2312,这个可以看说明书,可以设置的                                } catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
}
Thread.sleep(300);//你⾃⼰可以设置睡眠时间,这个睡眠时间可以会影响识别速度,那么就可以叫⽤户加钱,你懂我意思吧。
} catch (Exception e) {
//如果抛出异常则再次设置中断请求
Thread.currentThread().interrupt();
return;
}
}
}
}
嗯,到了这⼀步,⼤功告成了。
注意:串⼝⽅式实现的话兼容性不好,因为遇到部分安卓设备直接阉割了这部分功能,所以我才会研究USB⽅式的。
实现⽅式------USB⽅式:
该种⽅式好处在于不需要集成serial_port包,但是⾥⾯⼀些类理解⽐较灵性,USB⽅式需要经过以下⼏个步骤:
寻需要连接的devices设备
连接设备
获取数据流
步骤⼀:寻需要连接的devices设备,这⾥的话有两种场景
1.USB扫码⼀直插在安卓设备上,我们需要在程序启动的时候⾃动到并且连接
2.USB扫码在热拔插的情况下,我们需要在插⼊的时候连接
第⼀种的话我是直接写了⼀个⽅法,在程序启动的时候检查时候插⼊需要⽀持的设备类型,如果有,那么直接连接,判断⽅法是通过设备的pid和vid对⽐进⾏判断,pid和vid获取⽅式⾃⼰百度,或者把扫码插在电脑上,在设备管理可以看到,我通过findDevices⽅法到需要连接的扫码设备。
贴代码:
private UsbManager mManager;
//查已连接的设备
UsbDevice findDevices() {
if (null == mManager) {
return null;
}
HashMap<String, UsbDevice> mMap = DeviceList();
for (UsbDevice device : mMap.values()) {
if (BaseScanner.isS5920(device) || BaseScanner.isS5600(device)) {//判断设备是否⽀持的类型
return device;
}
}
return null;
}
这是baseScanner,这个类名我觉得不够准确,它是⽤来记录需要⽀持的设备的信息的,包含设备的判断⽅法:
public class BaseScanner{
private static final int scanner5600_pid = 4456;
private static final int scanner5600_vid = 866;
private static final int scanner5920_pid = 9527;
y型钢
private static final int scanner5920_vid = 549;
public static boolean isS5600(UsbDevice usbDevice){//是不是s5600扫码
ProductId() == scanner5600_pid && VendorId() == scanner5600_vid;
}
public static boolean isS5920(UsbDevice usbDevice){//是不是s5920
ProductId() == scanner5920_pid && VendorId() == scanner5920_vid;
}
}
第⼆种USB扫码热拔插连接⽅式,这时候我们采⽤的是⼴播监听的⽅式,因为设备拨叉都会有⼴播发送,这条⼴播包含的信息包含⼀个USBDevices对象(也就是扫码),我们需要动态注册拔,插两条⼴播,静态注册不⽣效,代码如下:
//这是⼴播类,因为我的扫描是写在⼀个service中,所以把连接的设备交给service处理就可以
public class USBBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = Action();
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = ParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
// call your method that cleans up and closes communication with the device
Toast.makeText(context, "拔出", Toast.LENGTH_LONG).show();
}
}else if(UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)){//设备插⼊
UsbDevice device = ParcelableExtra(UsbManager.EXTRA_DEVICE);//获取插⼊的设备            Intent intent1 = new Intent(context,ScannerService.class);
肝素钠提取技术
Bundle bundle = new Bundle();
bundle.putParcelable("device",device);
intent1.putExtra("data",bundle);//将设备包⼊intent中,交给service处理
context.startService(intent1);
Toast.makeText(context, "插⼊", Toast.LENGTH_LONG).show();
}
}
}
我是在程序启动的时候就注册了这个⼴播如下:
pgd678public class MyApplication extends Application {
private USBBroadcastReceiver mUsbReceiver;
@Override
public void onCreate() {
registBroadCast();
}
@Override
public void onTerminate() {
unregisterReceiver(mUsbReceiver);
}
private void registBroadCast(){//注册USB插拔⼴播
mUsbReceiver = new USBBroadcastReceiver();
IntentFilter usbDeviceStateFilter = new IntentFilter();
usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);//插⼊设备状态        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);//拔出设备状态        registerReceiver(mUsbReceiver, usbDeviceStateFilter);
}
}
步骤⼆,连接设备,这边我把所有都写注释⾥⾯:

本文发布于:2024-09-21 01:19:50,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/168332.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:设备   扫码   连接   需要   获取   步骤
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议