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

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

 

初步尝试,利用串口接收

1.依赖接入:

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

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

    private SerialPort mSerialPort;
    protected OutputStream mOutputStream;
    private InputStream mInputStream;



private void init_readuserid() {
        try {
            mSerialPort = SerialPort
                    .newBuilder(new File("/dev/ttyS3"), 9600) // 串口地址地址,波特率
                    .dataBits(8) // 数据位,默认8;可选值为5~8
                    .parity(0) // 校验位;0:无校验位(NONE,默认);1:奇校验位(ODD);2:偶校验位(EVEN)
                    .stopBits(1) // 停止位,默认1;1:1位停止位;2:2位停止位
                    .build();
            mOutputStream = mSerialPort.getOutputStream();
            mInputStream = mSerialPort.getInputStream();
            //开启接收线程
            new ReadThread().start();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    private class ReadThread extends Thread {
        @Override
        public void run() {
            super.run();
            while (!isInterrupted()) {
                int size;
                try {
                    byte[] buffer = new byte[64];
                    if (mInputStream == null) {
                        Log.i(TAG, "run: 输入为空");
                        System.out.println("+strData+strData入为空");
                        return;
                    }
                    size = mInputStream.read(buffer);
                    if (size > 0) {
                        String strData = ByteUtil.byteToStr(buffer, size);
                        Log.i(TAG, "run: 输入的=" + strData);
                        System.out.println("run: 输入为=" + strData);
                        // onDataReceived(buffer, size);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    return;
                }
            }

        }
    }

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

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

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

    /**
     * 获得 usb 权限
     */
    private void openUsbDevice() {
        //before open usb device
        //should try to get usb permission
        tryGetUsbPermission();
    }

    UsbManager mUsbManager;
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

    private void tryGetUsbPermission() {
        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(mUsbPermissionActionReceiver, filter);

        PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

        //here do emulation to ask all connected usb device for permission
        for (final UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {
            //add some conditional check if necessary
            //if(isWeCaredUsbDevice(usbDevice)){
            if (mUsbManager.hasPermission(usbDevice)) {
                //if has already got permission, just goto connect it
                //that means: user has choose yes for your previously popup window asking for grant perssion for this usb device
                //and also choose option: not ask again
                afterGetUsbPermission(usbDevice);
            } else {
                //this line will let android popup window, ask user whether to allow this app to have permission to operate this usb device
                mUsbManager.requestPermission(usbDevice, mPermissionIntent);
            }
            //}
        }
    }


    private void afterGetUsbPermission(UsbDevice usbDevice) {
        //call method to set up device communication
        //Toast.makeText(this, String.valueOf("Got permission for usb device: " + usbDevice), Toast.LENGTH_LONG).show();
        //Toast.makeText(this, String.valueOf("Found USB device: VID=" + usbDevice.getVendorId() + " PID=" + usbDevice.getProductId()), Toast.LENGTH_LONG).show();

        doYourOpenUsbDevice(usbDevice);
    }

    private void doYourOpenUsbDevice(UsbDevice usbDevice) {
        //now follow line will NOT show: User has not given permission to device UsbDevice
        UsbDeviceConnection connection = mUsbManager.openDevice(usbDevice);
        //add your operation code here
    }

    private final BroadcastReceiver mUsbPermissionActionReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        //user choose YES for your previously popup window asking for grant perssion for this usb device
                        if (null != usbDevice) {
                            afterGetUsbPermission(usbDevice);
                        }
                    } else {
                        //user choose NO for your previously popup window asking for grant perssion for this usb device
                        Toast.makeText(context, String.valueOf("Permission denied for device" + usbDevice), Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    };

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

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

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

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

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

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

compileSdkVersion 29
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()); 

private SerialInputOutputManager mSerialIoManager;
private ExecutorService mExecutor;
private UsbSerialPort port;
private StringBuffer sBuffer;
        //usb-rs232
        // Find all available drivers from attached devices.
        //usb权限开启
        openUsbDevice();
      
        UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
        List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
        if (availableDrivers.isEmpty()) {
            return;
        }
        // Open a connection to the first available driver.
        UsbSerialDriver driver = availableDrivers.get(0);
        UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
        if (connection == null) {
            // You probably need to call UsbManager.requestPermission(driver.getDevice(), ..)
            return;
        }
        // Read some data! Most have just one port (port 0).
        port = driver.getPorts().get(0);
        try {
            port.open(connection);
            port.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

            byte buffer[] = new byte[16];
            int numBytesRead = port.read(buffer, 1000);
            Log.i(TAG, "Read= " + numBytesRead + " bytes.");
        } catch (IOException e) {
            // Deal with error.
        }

        sBuffer=new StringBuffer();
        mExecutor = Executors.newSingleThreadExecutor();
        mSerialIoManager = new SerialInputOutputManager(port, mListener);//添加监听
        // 在新的线程中监听串口的数据变化
        mExecutor.submit(mSerialIoManager);

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

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

 

    SerialInputOutputManager.Listener mListener = new SerialInputOutputManager.Listener() {
        @Override
        public void onRunError(Exception e) {
            Log.i(TAG, "Runner stopped.");
        }

        @Override
        public void onNewData(final byte[] data) {
            //TODO 新的数据
            String usbid2 = bytesToHexString(data);
            Log.i(TAG, "新的数据data4=" + usbid2);

            Message message=handler.obtainMessage();
            message.what=3;
            message.obj=usbid2;
            handler.sendMessage(message);

        }
    };

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

public static String bytesToHexString(byte[] bytes) {
        String result = "";
        for (int i = 0; i < bytes.length; i++) {
            String hexString = Integer.toHexString(bytes[i] & 0xFF);
            if (hexString.length() == 1) {
                hexString = '0' + hexString;
            }
            result += hexString.toUpperCase();
        }
        return result;
    }

  最后关闭 

  @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeCallbacksAndMessages(null);
       
        try {
            port.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

 

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

 

 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值