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

news/2024/10/18 23:25:50/

本人使用环境

  • 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 = (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();@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);/*** USB监听*/
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) {}
};/*** 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;    //产品idstatic 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权限【传送门】


http://www.ppmy.cn/news/182528.html

相关文章

Appium初始化流程分析

Appium初始化流程分析 通过Appium桌面端日志分析Appium初始化流程&#xff1a; 主要的工作是通过adb完成的(这里分析adb初始化流程) 1.寻找已连接的Android设备 [ADB] Trying to find a connected android device2.获取设备的信息&#xff1a;设备版本、根据设备版本匹配sdk版…

appium工作原理详讲

appium简介 appium是一个移动端自动化框架&#xff0c;它采用C/S的设计模式&#xff0c;支持多类开发语言&#xff08;java python js c#…&#xff09;、支持多平台(ios android)&#xff0c;支持跨平台使用(windows linux)。它适用于原生或混合移动应用&#xff1b; appium…

通过手机USB控制外部设备的实例

手机本身就是一台功能强大的计算机&#xff0c;通过其USB接口可以方便地控制外部设备&#xff0c;前提是外部设备也要有USB接口。 本实例用到一个四路USB智能继电器接口模块&#xff0c;价格便宜&#xff0c;网上可以买到&#xff0c;型号是LCUS-4 型四路USB继电器模块智能控制…

2021年全球电气设备外壳收入大约6790百万美元,预计2028年达到9418.2百万美元

本文研究全球市场、主要地区和主要国家电气设备外壳的销量、销售收入等&#xff0c;同时也重点分析全球范围内主要厂商&#xff08;品牌&#xff09;竞争态势&#xff0c;电气设备外壳销量、价格、收入和市场份额等。 针对过去五年&#xff08;2017-2021&#xff09;年的历史情…

厂商主推芯片:中微SC8F6790和泰芯TX8C1260的对比,及使用感受。

中微的SC8F6790和泰芯的TX8C1260脚位都兼容市面上主流芯片STM8S003。相对于STM8S003&#xff0c;中微的和泰芯的芯片都为国产芯片&#xff0c;供货稳定&#xff0c;价格有优势&#xff0c;而且价格相对平稳&#xff0c;都已经大批量出货&#xff0c;芯片工作稳定性有保证。 S…

云服务器CPU内存/带宽配置怎么选择?

云服务器配置怎么选择&#xff1f;个人如何选择&#xff1f;企业怎么选择云服务器配置&#xff1f;腾讯云服务器CPU内存、带宽和系统盘怎么选择合适&#xff1f;个人用户可以选择轻量应用服务器&#xff0c;企业用户可以选择云服务器CVM&#xff0c;企业用户可以选择标准型S5云…

生成全球唯一性的标识符uuid.uuid4

UUID&#xff08;通用唯一标识符&#xff09;是一种用于标识信息的标准化方法&#xff0c;它可以保证在全球范围内的唯一性。这是因为UUID的生成算法是基于时间戳、硬件地址、随机数等多个因素的组合&#xff0c;这些因素的组合可以保证生成的UUID在全球范围内的唯一性。 具体…

IEEE2023春季课程笔记

一、MOOC培训课件链接如下&#xff1a; 主题一&#xff08;a&#xff09;课件下载&#xff1a; https://workdrive.zohopublic.com.cn/external/a3c3f69729a83daa50aa28e086572ba759fffcb2acbaec84377e0b9181a25015 主题一&#xff08;b&#xff09;课件下载&#xff1a; https…