当前位置:   article > 正文

Android usb-serial-for-android驱动库 实现(读卡器rs232串口转usb)插入开发板读取数据

usb-serial-for-android

刚开始接到这个这个任务的时候,看了一下这款读卡器设备的参数(res232协议读卡器技术参数)

 

初步尝试,利用串口接收

1.依赖接入:

  1. //串口检测
  2. implementation 'com.github.licheedev:Android-SerialPort-API:2.0.0'

2.设置串口参数,打开串口接收:

  1. private SerialPort mSerialPort;
  2. protected OutputStream mOutputStream;
  3. private InputStream mInputStream;
  4. private void init_readuserid() {
  5. try {
  6. mSerialPort = SerialPort
  7. .newBuilder(new File("/dev/ttyS3"), 9600) // 串口地址地址,波特率
  8. .dataBits(8) // 数据位,默认8;可选值为5~8
  9. .parity(0) // 校验位;0:无校验位(NONE,默认);1:奇校验位(ODD);2:偶校验位(EVEN)
  10. .stopBits(1) // 停止位,默认1;1:1位停止位;2:2位停止位
  11. .build();
  12. mOutputStream = mSerialPort.getOutputStream();
  13. mInputStream = mSerialPort.getInputStream();
  14. //开启接收线程
  15. new ReadThread().start();
  16. } catch (SecurityException e) {
  17. e.printStackTrace();
  18. } catch (IOException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. private class ReadThread extends Thread {
  23. @Override
  24. public void run() {
  25. super.run();
  26. while (!isInterrupted()) {
  27. int size;
  28. try {
  29. byte[] buffer = new byte[64];
  30. if (mInputStream == null) {
  31. Log.i(TAG, "run: 输入为空");
  32. System.out.println("+strData+strData入为空");
  33. return;
  34. }
  35. size = mInputStream.read(buffer);
  36. if (size > 0) {
  37. String strData = ByteUtil.byteToStr(buffer, size);
  38. Log.i(TAG, "run: 输入的=" + strData);
  39. System.out.println("run: 输入为=" + strData);
  40. // onDataReceived(buffer, size);
  41. }
  42. } catch (IOException e) {
  43. e.printStackTrace();
  44. return;
  45. }
  46. }
  47. }
  48. }

到这里,不管我这边怎么用卡片去刷,数据是始终反馈,一开始找了很多方式来接收串口的测试方法,都不行,刚开始,还以为是usb 权限问题,我这边把文件清单添加了usb权限:

  1. <!--USB权限-->
  2. <uses-feature android:name="android.hardware.usb.host" />

调用: openUsbDevice() ,来检测usb 权限问题;

  1. /**
  2. * 获得 usb 权限
  3. */
  4. private void openUsbDevice() {
  5. //before open usb device
  6. //should try to get usb permission
  7. tryGetUsbPermission();
  8. }
  9. UsbManager mUsbManager;
  10. private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
  11. private void tryGetUsbPermission() {
  12. mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
  13. IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
  14. registerReceiver(mUsbPermissionActionReceiver, filter);
  15. PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
  16. //here do emulation to ask all connected usb device for permission
  17. for (final UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {
  18. //add some conditional check if necessary
  19. //if(isWeCaredUsbDevice(usbDevice)){
  20. if (mUsbManager.hasPermission(usbDevice)) {
  21. //if has already got permission, just goto connect it
  22. //that means: user has choose yes for your previously popup window asking for grant perssion for this usb device
  23. //and also choose option: not ask again
  24. afterGetUsbPermission(usbDevice);
  25. } else {
  26. //this line will let android popup window, ask user whether to allow this app to have permission to operate this usb device
  27. mUsbManager.requestPermission(usbDevice, mPermissionIntent);
  28. }
  29. //}
  30. }
  31. }
  32. private void afterGetUsbPermission(UsbDevice usbDevice) {
  33. //call method to set up device communication
  34. //Toast.makeText(this, String.valueOf("Got permission for usb device: " + usbDevice), Toast.LENGTH_LONG).show();
  35. //Toast.makeText(this, String.valueOf("Found USB device: VID=" + usbDevice.getVendorId() + " PID=" + usbDevice.getProductId()), Toast.LENGTH_LONG).show();
  36. doYourOpenUsbDevice(usbDevice);
  37. }
  38. private void doYourOpenUsbDevice(UsbDevice usbDevice) {
  39. //now follow line will NOT show: User has not given permission to device UsbDevice
  40. UsbDeviceConnection connection = mUsbManager.openDevice(usbDevice);
  41. //add your operation code here
  42. }
  43. private final BroadcastReceiver mUsbPermissionActionReceiver = new BroadcastReceiver() {
  44. public void onReceive(Context context, Intent intent) {
  45. String action = intent.getAction();
  46. if (ACTION_USB_PERMISSION.equals(action)) {
  47. synchronized (this) {
  48. UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
  49. if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
  50. //user choose YES for your previously popup window asking for grant perssion for this usb device
  51. if (null != usbDevice) {
  52. afterGetUsbPermission(usbDevice);
  53. }
  54. } else {
  55. //user choose NO for your previously popup window asking for grant perssion for this usb device
  56. Toast.makeText(context, String.valueOf("Permission denied for device" + usbDevice), Toast.LENGTH_LONG).show();
  57. }
  58. }
  59. }
  60. }
  61. };

还是没有数据接收到,我这边找了很多的usb调试工具,最多都只是检测能否正常打开指定的usb 串口名有没有权限,能正常打开也是收不到任何的数据,我就想,这样的方式是不行的,然后我这边找到一个强大的测试串口工具,这边做一下分享推荐

https://blog.csdn.net/xlazydog/article/details/99458381

我这边就下载了这位大佬写的测试串口调试工具,没想到,我这边可以正常读取到卡片数据回来,然后就改成了他推荐的一个开源的Android 驱动库:

https://github.com/mik3y/usb-serial-for-android

接下来就是,第二次测试,用这个驱动库来测试行不行了:

我这边as工具用的版本是(androidx):

  1. compileSdkVersion 29
  2. buildToolsVersion "29.0.2"

 

直接用依赖到我的项目是,报错的,集成不进去:

implementation 'com.github.mik3y:usb-serial-for-android:Tag'

只能去下载他提供的android测试模块了,再手动导进去了:

https://blog.csdn.net/helloworld19870427/article/details/93221649(参考手动导入过程)

这边就不做分享导入的过程了。直接上码:

1.还是坚持usb权限问题,不然的话,就算可以找到设备,也有可能打开失败(connection null),用 //usb权限开启
   openUsbDevice() 是可以避免失败的问题。

  UsbDeviceConnection connection = manager.openDevice(driver.getDevice()); 

  1. private SerialInputOutputManager mSerialIoManager;
  2. private ExecutorService mExecutor;
  3. private UsbSerialPort port;
  4. private StringBuffer sBuffer;
  1. //usb-rs232
  2. // Find all available drivers from attached devices.
  3. //usb权限开启
  4. openUsbDevice();
  5. UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
  6. List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
  7. if (availableDrivers.isEmpty()) {
  8. return;
  9. }
  10. // Open a connection to the first available driver.
  11. UsbSerialDriver driver = availableDrivers.get(0);
  12. UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
  13. if (connection == null) {
  14. // You probably need to call UsbManager.requestPermission(driver.getDevice(), ..)
  15. return;
  16. }
  17. // Read some data! Most have just one port (port 0).
  18. port = driver.getPorts().get(0);
  19. try {
  20. port.open(connection);
  21. port.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
  22. byte buffer[] = new byte[16];
  23. int numBytesRead = port.read(buffer, 1000);
  24. Log.i(TAG, "Read= " + numBytesRead + " bytes.");
  25. } catch (IOException e) {
  26. // Deal with error.
  27. }
  28. sBuffer=new StringBuffer();
  29. mExecutor = Executors.newSingleThreadExecutor();
  30. mSerialIoManager = new SerialInputOutputManager(port, mListener);//添加监听
  31. // 在新的线程中监听串口的数据变化
  32. mExecutor.submit(mSerialIoManager);

 收到读卡器返回的字节数据,这里有个问题是,这个依赖库的问题,他不是一次性完整的返回一整串数据,他的文档有使用说明是这样说的; 

https://github.com/mik3y/usb-serial-for-android/wiki/Troubleshooting

 

  1. SerialInputOutputManager.Listener mListener = new SerialInputOutputManager.Listener() {
  2. @Override
  3. public void onRunError(Exception e) {
  4. Log.i(TAG, "Runner stopped.");
  5. }
  6. @Override
  7. public void onNewData(final byte[] data) {
  8. //TODO 新的数据
  9. String usbid2 = bytesToHexString(data);
  10. Log.i(TAG, "新的数据data4=" + usbid2);
  11. Message message=handler.obtainMessage();
  12. message.what=3;
  13. message.obj=usbid2;
  14. handler.sendMessage(message);
  15. }
  16. };

我这边就处理方式也是死规定的,如果你那边的数据不一可以参考我下面的数据,处理方式(把字节数据 转 字符串拼接,每次的字符串的长度去清空,再次方便接收保存数据):

  1. public static String bytesToHexString(byte[] bytes) {
  2. String result = "";
  3. for (int i = 0; i < bytes.length; i++) {
  4. String hexString = Integer.toHexString(bytes[i] & 0xFF);
  5. if (hexString.length() == 1) {
  6. hexString = '0' + hexString;
  7. }
  8. result += hexString.toUpperCase();
  9. }
  10. return result;
  11. }

  最后关闭 

  1. @Override
  2. protected void onDestroy() {
  3. super.onDestroy();
  4. handler.removeCallbacksAndMessages(null);
  5. try {
  6. port.close();
  7. } catch (IOException e) {
  8. e.printStackTrace();
  9. }
  10. }

 

 

      到这里就基本实现了一个读卡器正常接收卡片的信息,做个简单的记录,简单集成usb-serial-for-android驱动库,就测试好了,当然我这边是用的一个设备来测试,如果多个设备接收,我这边暂时没有实现,但关键是找到设备数,找到设备名,来相互确认名字,暂时是这样的思路,里面的文章还是有很多方式没有一一列举出来,可以自己尝试,如果你有更好的看法和实现方式,可以底部评论留下思路,可以一起交流学习。

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/211575
推荐阅读
相关标签
  

闽ICP备14008679号