本人使用环境
- 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" />
<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" />
</resource>
<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>
使用
class TemperMoudle {
private final static String TAG = "MainActivity";
private static final int TEMPERATURE_USB_VENDOR_ID = 6790; //供应商id
private static final int TEMPERATURE_USB_PRODUCT_ID = 29987; //产品id
private Context context;
private List<UsbSerialDriver> usbSerialDrivers = null;
private List<UsbSerialPort> usbSerialPorts = new ArrayList<>();
private UsbSerialPort temperatureUsbPort = null;
private SerialInputOutputManager serialIoManager;
private SerialInputOutputManager.Listener serialListener;
private ExecutorService executor = Executors.newSingleThreadExecutor();
TemperMoudle(Context context) {
this.context = context;
}
/**
* 初始化,获取目标端口
*/
UsbSerialPort init(SerialInputOutputManager.Listener listener) {
this.serialListener = listener;
//获取全部设备
UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
if (usbManager != null) {
usbSerialDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);
}
//获取全部端口
if (usbSerialDrivers != null) {
for (UsbSerialDriver driver : usbSerialDrivers) {
usbSerialPorts.addAll(driver.getPorts());
}
}
//校验端口设备,获得目标端口
for (UsbSerialPort port : usbSerialPorts) {
UsbDevice device = port.getDriver().getDevice();
if (device.getVendorId() == TEMPERATURE_USB_VENDOR_ID && device.getProductId() == TEMPERATURE_USB_PRODUCT_ID) {
UsbDeviceConnection connection = usbManager.openDevice(device);
try {
temperatureUsbPort = port;
temperatureUsbPort.open(connection);
temperatureUsbPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
//我这里需要开启RTS,否则无法读取数据,但务必记得在temperatureUsbPort.close之前置位false,否则再次启动程序无法读取端口!
temperatureUsbPort.setRTS(true);
} catch (IOException e) {
Log.e(TAG, "打开端口失败");
try {
temperatureUsbPort.setRTS(false);
temperatureUsbPort.close();
} catch (IOException e2) {
e.printStackTrace();
}
}
}
}
return temperatureUsbPort;
}
/**
* 设置数据监听器
*
* @param listener 监听器
*/
void setSerialListener(SerialInputOutputManager.Listener listener) {
this.serialListener = listener;
}
private void startIoManager() {
if (temperatureUsbPort != null) {
serialIoManager = new SerialInputOutputManager(temperatureUsbPort, serialListener);
executor.submit(serialIoManager);
}
}
private void stopIoManager() {
if (serialIoManager != null) {
serialIoManager.stop();
serialIoManager = null;
}
}
/**
* 重新开启USB管理器
*/
void onDeviceStateChange() {
stopIoManager();
startIoManager();
}
void onPause() {
stopIoManager();
if (temperatureUsbPort != null) {
try {
temperatureUsbPort.setRTS(false);
temperatureUsbPort.close();
temperatureUsbPort = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
TemperMoudle temperMoudle;
UsbSerialPort temperUsbPort;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取温度传感器数据端口
temperMoudle = new TemperMoudle(this);
temperUsbPort = temperMoudle.init(temperListener);
//发送查询温度的指令
if (temperUsbPort != null) {
try {
temperUsbPort.write(Str16ToBytes("01 03 00 00 00 01 84 0A", " "), 200);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 监听USB端口数据
*/
SerialInputOutputManager.Listener temperListener = new SerialInputOutputManager.Listener() {
@Override
public void onNewData(byte[] data) {
String[] dataStrings = BytesToStrs16(data);
for (String dataString : dataStrings) {
Log.d(TAG, "dataString: " + dataString);
}
}
@Override
public void onRunError(Exception e) {
e.printStackTrace();
}
};
/**
* 用于检测usb插入状态的BroadcasReceiver
*/
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
Log.e(TAG, "设备移除");
temperMoudle.onPause();
finish();
}
}
};
@Override
protected void onResume() {
super.onResume();
IntentFilter usbFilter = new IntentFilter();
usbFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(usbReceiver, usbFilter);
temperMoudle.onDeviceStateChange();
}
@Override
protected void onPause() {
super.onPause();
temperMoudle.onPause();
unregisterReceiver(usbReceiver);
}
/**
* 16进制字符串转byte数组
*
* @param str 需要转换的字符串
* @param splitChare 中断间隔符
* @return 转换好的byte[]数组
*/
public byte[] Str16ToBytes(String str, String splitChare) {
String[] string = str.trim().split(splitChare);
byte[] bytes = new byte[string.length];
for (int i = 0; i < string.length; i++) {
bytes[i] = (byte) (Integer.parseInt(string[i], 16) & 0xff);
}
return bytes;
}
/**
* 十进制bytes转16进制strings
*
* @param bytes 十进制bytes
* @return 16进制strings
*/
public String[] BytesToStrs16(byte[] bytes) {
String[] strs = new String[bytes.length];
for (int i = 0; i < bytes.length; i++) {
strs[i] = Integer.toHexString(bytes[i] & 0xff);
}
return strs;
}