本人使用环境
- CH340转接头
- Android5.1,RK3188
- Android6.0,RK3288
关于CH34官方的jar包与使用存在的问题(官方地址)
- 最大的问题是无法修改串口波特率,一直以19200运行,但我的传感器为9600,理论上应该可以修改,可是就连官方的APK都无法修改,我只好另寻他发
最终解决方案
- 使用GitHub:https://github.com/mik3y/usb-serial-for-android
更加简便的新方案
- https://blog.csdn.net/qq_36881363/article/details/114639066
初始化
- 在你的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
中补全以下代码
<activityandroid:name="..."...><intent-filter><action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /></intent-filter><meta-dataandroid:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"android:resource="@xml/device_filter" />
</activity>
使用简介
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
List<UsbSerialDriver> usbSerialDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);
List<UsbSerialPort> usbSerialPorts = new ArrayList<>();
for (UsbSerialDriver driver : usbSerialDrivers) {usbSerialPorts.addAll(driver.getPorts());
}
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)) {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);
}
public class USBReadService extends Service {private final static String TAG = "USBReadService";SerialInputOutputManager mSerialIoManager;ExecutorService mExecutor = Executors.newSingleThreadExecutor();@Overridepublic 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@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic 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() {@Overridepublic 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;}}@Overridepublic void onDestroy() {unregisterReceiver(mUsbReceiver);closePort();stopIoManager();mExecutor.shutdown();super.onDestroy();}
}
Intent intent = new Intent(this, USBReadService.class);
startService(intent);
public static SerialInputOutputManager.Listener mListener = new SerialInputOutputManager.Listener() {@Overridepublic void onRunError(Exception e) {Log.d(TAG, "Runner stopped.");}@RequiresApi(api = Build.VERSION_CODES.N)@Overridepublic void onNewData(byte[] 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");}
}
static final int USB_VENDOR_ID = 1027;
static final int USB_PRODUCT_ID = 24577; 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权限【传送门】