本人使用环境
- 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) 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();
@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);
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) {
}
};
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权限【传送门】