Android——USB转COM口(CH340)与传感器进行通讯

本人使用环境

  • CH340转接头
  • Android5.1,RK3188
  • Android6.0,RK3288

关于CH34官方的jar包与使用存在的问题(官方地址)

  • 最大的问题是无法修改串口波特率,一直以19200运行,但我的传感器为9600,理论上应该可以修改,可是就连官方的APK都无法修改,我只好另寻他发

最终解决方案

初始化

  • 在你的build.gradle(project)中添加
allprojects {
    
    
    repositories {
    
    
        ...
        maven {
    
     url 'https://jitpack.io' }
    }
}
  • 添加依赖
dependencies {
    
    
    implementation 'com.github.mik3y:usb-serial-for-android:2.2.2'
}
  • 添加权限
<uses-feature android:name="android.hardware.usb.host" />
  • res/xml/下添加 device_filter.xml,CH340官网的工程Demo内也有,这一步相当于加一个给过滤器用的资源列表,如果没有识别需求(比如插入自动获取权限等)可以不加。
<resource>
	<usb-device product-id="29987" vendor-id="6790" />
	<usb-device product-id="21795" vendor-id="6790" />
	<usb-device product-id="21778" vendor-id="6790" />
	
	//补充
	<usb-device vendor-id="1024" product-id="50010"/>
	<usb-device vendor-id="1024" product-id="24577"/>
	<usb-device vendor-id="6790" product-id="29987"/>
	<usb-device vendor-id="1027" product-id="24577"/>
</resource>
  • 如果想要在设备插入后便获取权限,则需要在AndroidManifest中补全以下代码
<activity
    android:name="..."
    ...>
    <intent-filter>
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
    </intent-filter>
    <meta-data
        android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
        android:resource="@xml/device_filter" />
</activity>

使用简介

  • 获取UsbManager
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
  • 获取设备端口
//获取所有端口-->usbSerialPorts
List<UsbSerialDriver> usbSerialDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);
List<UsbSerialPort> usbSerialPorts = new ArrayList<>();
for (UsbSerialDriver driver : usbSerialDrivers) {
    
    
    usbSerialPorts.addAll(driver.getPorts());
}
//扫描所有端口,找到自己需要的端口-->usbPort 
for (UsbSerialPort port : usbSerialPorts) {
    
    
    UsbDevice device = port.getDriver().getDevice();
    //ID值自行参考自己设备
    if (device.getVendorId() == USB_VENDOR_ID && device.getProductId() == USB_PRODUCT_ID) {
    
    
        usbPort = port;
    }
}
  • 检查权限和开启端口
if (usbManager.hasPermission(device)) {
    
    
    //有权限,开启端口
    UsbDeviceConnection connection = usbManager.openDevice(usbPort.getDriver().getDevice());
    if (connection == null) {
    
    
        Log.d(TAG, "open: connection == null");
        return;
    }
    try {
    
    
        usbPort.open(connection);
        usbPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
    } catch (IOException e) {
    
    
        closePort();
    } catch (RuntimeException e2) {
    
    
        e2.printStackTrace();
    }
} else {
    
    
    //无权限,弹出权限获取窗口并配置广播
    PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(DIALOG_USB_PERMISSION), 0);
    usbManager.requestPermission(device, usbPermissionIntent);
}

样例,涉及广播+无障碍自动获取USB权限的代码

  • 创建接口
interface USBReceiver {
    
    
    void receive(String s);
}
  • 创建单独的USB服务
public class USBReadService extends Service {
    
    
    private final static String TAG = "USBReadService";

    SerialInputOutputManager mSerialIoManager;
    ExecutorService          mExecutor = Executors.newSingleThreadExecutor();

    @Override
    public void onCreate() {
    
    
        super.onCreate();
        usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        IntentFilter usbDeviceStateFilter = new IntentFilter();
        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        usbDeviceStateFilter.addAction(DIALOG_USB_PERMISSION);
        registerReceiver(mUsbReceiver, usbDeviceStateFilter);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    
    
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
    
        refreshDevice();
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 刷新获取设备列表
     */
    public void refreshDevice() {
    
    
        //获取所有端口
        List<UsbSerialDriver> usbSerialDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);
        List<UsbSerialPort> usbSerialPorts = new ArrayList<>();
        for (UsbSerialDriver driver : usbSerialDrivers) {
    
    
            usbSerialPorts.addAll(driver.getPorts());
        }
        //扫描所有端口,找到自己需要的端口
        usbPort = null;
        for (UsbSerialPort port : usbSerialPorts) {
    
    
            UsbDevice device = port.getDriver().getDevice();
            if (device.getVendorId() == USB_VENDOR_ID && device.getProductId() == USB_PRODUCT_ID) {
    
    
                usbPort = port;
                //检查权限
                if (usbManager.hasPermission(device)) {
    
    
                    Log.d(TAG, "有权限");
                    open();
                } else {
    
    
                    Log.d(TAG, "没有权限");
                    //弹出权限窗口并配置广播
                    PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(DIALOG_USB_PERMISSION), 0);
                    usbManager.requestPermission(device, usbPermissionIntent);
                }
                break;
            }
        }
    }

    void open() {
    
    
        UsbDeviceConnection connection = usbManager.openDevice(usbPort.getDriver().getDevice());
        if (connection == null) {
    
    
            Log.d(TAG, "open: connection == null");
            return;
        }
        try {
    
    
            usbPort.open(connection);
            usbPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
        } catch (IOException e) {
    
    
            closePort();
        } catch (RuntimeException e2) {
    
    
            e2.printStackTrace();
        }

        onDeviceStateChange();
    }

    BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
    
            if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
    
    
                Log.d(TAG, "onReceive: USB插入");
                refreshDevice();
            }
            if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
    
    
                Log.d(TAG, "onReceive: USB拔出");
                refreshDevice();
            }
            if (DIALOG_USB_PERMISSION.equals(intent.getAction())) {
    
    
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
    
    
                    Log.d(TAG, "onReceive: 用户允许了弹窗的权限");
                    open();
                } else {
    
    
                    Log.d(TAG, "onReceive: 用户取消了弹窗的权限");
                }
            }
        }
    };

    private void stopIoManager() {
    
    
        if (mSerialIoManager != null) {
    
    
            mSerialIoManager.stop();
            mSerialIoManager = null;
        }
    }

    private void startIoManager() {
    
    
        if (usbPort != null) {
    
    
            mSerialIoManager = new SerialInputOutputManager(usbPort, mListener);
            mSerialIoManager.setReadTimeout(20);
            mExecutor.submit(mSerialIoManager);
        }
    }

    private void onDeviceStateChange() {
    
    
        stopIoManager();
        startIoManager();
    }

    private void closePort() {
    
    
        if (usbPort != null) {
    
    
            try {
    
    
                usbPort.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
            usbPort = null;
        }
    }

    @Override
    public void onDestroy() {
    
    
        unregisterReceiver(mUsbReceiver);
        closePort();
        stopIoManager();
        mExecutor.shutdown();
        super.onDestroy();
    }
}
  • 使用
Intent intent = new Intent(this, USBReadService.class);
startService(intent);

/**
 * USB监听
 */
public static SerialInputOutputManager.Listener mListener = new SerialInputOutputManager.Listener() {
    
    
    @Override
    public void onRunError(Exception e) {
    
    
        Log.d(TAG, "Runner stopped.");
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onNewData(byte[] data) {
    
    
     
    }
};

/**
 * USB输出
 *
 * @param data 输出的数据
 */
static void write(byte[] data) {
    
    
    if (usbPort != null) {
    
    
        try {
    
    
            usbPort.write(data, 200);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    } else {
    
    
        Log.d(TAG, "write: usbPort == null");
    }
}
  • 其他
//Z-TEK
static final int USB_VENDOR_ID  = 1027;     //供应商id
static final int USB_PRODUCT_ID = 24577;    //产品id

static UsbSerialPort   usbPort   = null;
static UsbManager      usbManager;
static ArrayList<Byte> usbBuffer = new ArrayList<>();

public static String DIALOG_USB_PERMISSION = "com.example.ysy200811_1scx.DIALOG_USB_PERMISSION";

附:自动获取USB权限【传送门

猜你喜欢

转载自blog.csdn.net/qq_36881363/article/details/104811643