WeChat number: public CodingAndroid CSDN:blog.csdn.net/xinpengfei5…

1. Background

Our company has developed an indoor unit tablet APP, which requires that the tablet can control the smart door lock and other smart devices. The smart door lock is not developed by our company and belongs to a cooperative relationship with our company.

2. Analysis and implementation ideas

  1. Intelligent door lock control is through the use of 433 radio (do not understand please Baidu) to communicate;
  2. The tablet cannot communicate with the intelligent door lock directly, but the manufacturer provides a 433 communication module (supporting serial port);
  3. The tablet (OTG) supports USB-to-serial module, so the whole process can go through, as shown in the following figure

3. Main code implementation

3.1 Initializing the USB-to-Serial Port Module

Since we choose CH340 module, we import THE JAR package of CH340 first, and then check whether the mobile phone/tablet supports USB HOST mode in the code. If so, we will initialize the related parameters of communication: baud rate, data bit, stop bit, etc. The specific parameters depend on the communication protocol between you. After initialization, we can open USB for communication, and after initialization, we need to open a data reading thread, so that we can process the data or corresponding response packet (commonly called ACK) once we receive it.

The code implementation for initializing and starting the data reading thread is posted below:

   /**
     * initialize ch340 parameters.
     *
     * @param context Application context.
     */
    public static void initCH340(Context context) {
        if (context == null) return;
        Context appContext = context.getApplicationContext();
        mUsbManager = (UsbManager) appContext.getSystemService(Context.USB_SERVICE);
        if(mUsbManager ! = null) { HashMap<String, UsbDevice> deviceHashMap = mUsbManager.getDeviceList();for (UsbDevice device : deviceHashMap.values()) {
                if (device.getProductId() == 29987 && device.getVendorId() == 6790) {
                    mUsbDevice = device;
                    if (mUsbManager.hasPermission(device)) {
                        loadDriver(appContext, mUsbManager);
                    } else {
                        if(listener ! = null) { listener.result(false); }}break; } } } } /** * load ch340 driver. * * @param appContext * @param usbManager */ public static void loadDriver(Context appContext, UsbManager usbManager) { driver = new CH34xUARTDriver(usbManager, appContext, ACTION_USB_PERMISSION); // Check whether the system supports USB HOSTif(! driver.UsbFeatureSupported()) { InLog.e(TAG,"Your mobile phone does not support USB HOST, please change other phones to try again!");
        } else {
            openCH340();
        }
    }

    /**
     * config and open ch340.
     */
    private static void openCH340() {
        int ret_val = driver.ResumeUsbList();
        InLog.d(TAG, ret_val + ""); The ResumeUsbList method is used to enumerate and open CH34X devicesif (ret_val == -1) {
            InLog.d(TAG, ret_val + "Failed to open device!");
            driver.CloseDevice();
        } else if (ret_val == 0) {
            if(! Driver.uartinit ()) {// Initialize the serial port device inlog. d(TAG, ret_val +)"Failed device initialization!");
                InLog.d(TAG, ret_val + "Failed to open device!");
                return;
            }
            InLog.d(TAG, ret_val + "Open device successfully!");
            if(! isOpenDeviceCH340) { isOpenDeviceCH340 =true; configParameters(); // Set ch340 parameters first}}else {
            InLog.d(TAG, "The phone couldn't find the device!"); }} /** * config ch340 parameters. */ private static voidconfigParameters() {
        if (driver.SetConfig(baudRate, dataBit, stopBit, parity, flowControl)) {
            InLog.d(TAG, Successful Serial port Settings!);
            if (readDataRunnable == null) {
                readDataRunnable = new ReadDataRunnable();
            }
            mThreadPool.execute(readDataRunnable);
        } else {
            InLog.d(TAG, "Serial port Settings failed!"); }}Copy the code

3.2 Sending and receiving data

Sending and receiving data are sent and processed in hexadecimal format, so we wrote a utility class to facilitate sending, as follows:

/** * Created by XPF on 2018/2/6: * Function: CH340Util public class CH340Util {/** * write datainCh340. * * @param byteArray byteArray * @returnReturns the result of the write, -1 indicates that the write failed! */ public static int writeData(@nonnull byte[] byteArray) {// Convert the received array to HexString String HexString = bytesToHexString(byteArray, byteArray.length); InLog.i("TAG"."WriteHexString===" + hexString);
        returnInitCH340.getDriver().WriteData(byteArray, byteArray.length); } /** * byte[] converts to hexString ** @param buffer data * @param size number of characters * @returnAfter return to convert hexadecimal String * / public static String bytesToHexString (byte [] buffer, final int size) { StringBuilder stringBuilder = new StringBuilder("");
        if (buffer == null || size <= 0) return null;
        for (int i = 0; i < size; i++) {
            String hex = Integer.toHexString(buffer[i] & 0xff);
            if (hex.length() < 2) stringBuilder.append(0);
            stringBuilder.append(hex);
        }
        returnstringBuilder.toString(); }}Copy the code

You can call writeData() when sending data, and the same is true for receiving data. Specific business and communication protocols and encryption rules need to be negotiated and formulated with the hardware provider. As it involves company secrets, I won’t explain them here. Just the basics of sending and receiving data.

4. Insert the module to automatically open the APP

We only need to receive this broadcast in the AndroidMenifest. XML file. When we enter the module, our APP will be started. In addition, not any USB device we insert will open our application, so we need to filter out the devices that are not useful to us, create an XML directory under RES, create a usb_filter. XML file, and configure the product-ID and vendor-ID of our USB device module. This value varies from module manufacturer to module manufacturer. There are two ways to obtain it: one is to enumerate USB devices in the code and print them out; the other is to open Logcat to observe and insert USB devices. You will find that the system will print information about the USB device.

Finally, don’t forget to add permissions:

	<uses-feature
        android:name="android.hardware.usb.host"
        android:required="true" />

    <uses-permission android:name="android.hardware.usb.host" />
Copy the code

Due to the lack of space, I will not elaborate on more details here. I have posted the core code and implementation. To view a more specific implementation, please download my demo:

Github.com/xinpengfei5…

If you have any questions or suggestions, feel free to post them on the public account “CodingAndroid”, Crab!

—————————— scan the above TWO-DIMENSIONAL code attention oh! ————————–