android - Android Kotlin 未从 USB FTDI 串行端口接收或读取数据
问题描述
我正在构建一个 Android 应用程序,它通过 USB 端口从另一个设备读取数据,正是这个 WaterRower 设备/机器,https: //www.waterrower.co.uk/waterrower-natural-rowing-machine ?gclid=Cj0KCQjw5auGBhDEARIsAFyNm9F2Q7Uq8tSHWTWgCelo4BgJUcK6c43_499CjVmOQSkgoI-E6zEjCU0aAiZSEAL.w_w
似乎它正在使用产品 id 10 和供应商 id 1240 的 FTDI 端口。我正在使用这个库进行串行端口通信,https://github.com/felHR85/UsbSerial。我可以打开端口。但是该应用程序没有从 WaterRower 机器接收或读取任何数据。
这是我的代码:
class NewDeviceListFragment: Fragment() {
private lateinit var listView: RecyclerView
private lateinit var listAdapter: DeviceListAdapter
private lateinit var listItems: ArrayList<UsbDevice>
private lateinit var emptyListMessage: TextView
private lateinit var emptyListMessageWrapper: LinearLayout
private lateinit var writeButton: AppCompatButton
private lateinit var readButton: AppCompatButton
private lateinit var showButton: AppCompatButton
private lateinit var usbManager: UsbManager
private lateinit var usbDevice: android.hardware.usb.UsbDevice
private lateinit var tvReadDataText: TextView
private lateinit var tvDriverDetails: TextView
private val ACTION_USB_PERMISSION = "com.example.myapplication.USB_PERMISSION"
private var readData: String = ""
private var readCallback: UsbSerialInterface.UsbReadCallback = object: UsbSerialInterface.UsbReadCallback {
override fun onReceivedData(arg0: ByteArray?) {
try {
var data: String? = null
try {
data = String(arg0 as ByteArray, Charset.forName("UTF-8"))
"$data/n"
//tvReadDataText.setText(tvReadDataText.text.toString() + "\n" + data)
readData = readData + data
} catch (e: UnsupportedEncodingException) {
e.printStackTrace()
}
} catch (e: Exception) {
Bugsnag.notify(RuntimeException(e.message))
}
}
}
private val usbReceiver = object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == ACTION_USB_PERMISSION) {
synchronized(this) {
val device: android.hardware.usb.UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
device?.apply {
//call method to set up device communication
}
} else {
}
}
}
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_device_list, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
writeButton = view.findViewById(R.id.write_data_button)
readButton = view.findViewById(R.id.read_data_button)
showButton = view.findViewById(R.id.show_data_button)
emptyListMessageWrapper = view.findViewById(R.id.device_list_empty_message_wrapper)
emptyListMessage = view.findViewById(R.id.empty_list_message)
listView = view.findViewById(R.id.list_view_device_list)
tvReadDataText = view.findViewById(R.id.tv_read_data_text)
tvDriverDetails = view.findViewById(R.id.tv_driver_details)
listItems = ArrayList()
setUpListView()
readButton.setOnClickListener {
readDataFromConnectedDevice()
}
showButton.setOnClickListener {
tvReadDataText.setText(readData)
}
}
private fun readDataFromConnectedDevice() {
var usbConnection = usbManager.openDevice(usbDevice)
var serial: UsbSerialDevice = UsbSerialDevice.createUsbSerialDevice(usbDevice, usbConnection)
if (serial.open()) {
readButton.setText("Port is now open")
// 9600 is the Android default and 19200 for RowBots. max 115,200
serial.setBaudRate(19200)
serial.setDataBits(UsbSerialInterface.DATA_BITS_8)
serial.setParity(UsbSerialInterface.PARITY_NONE)//FTPI change to parity odd
serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF)
serial.setDTR(true)
serial.setRTS(true)
serial.read(readCallback)
} else {
readButton.setText("Unable to open the port")
}
}
private fun setUpListView() {
listItems = getDeviceList()
listView.layoutManager = LinearLayoutManager(activity as Activity)
listAdapter = DeviceListAdapter(listItems)
listView.adapter = listAdapter
if (listItems.size < 1) {
showEmptyListMessage("No device found")
}
}
private fun getDeviceList(): ArrayList<UsbDevice> {
var deviceList: ArrayList<UsbDevice> = ArrayList()
// activity?.getSystemService(Context.USB_SERVICE) as UsbManager
usbManager = activity?.getSystemService(Context.USB_SERVICE) as UsbManager
for (device in usbManager.deviceList.values) {
deviceList.add(
UsbDevice(
id = device.deviceId.toString(),
name = device.deviceName + " : " + device.productName + " : " + device.manufacturerName,
model = "PID: ${device.productId} | VID: ${device.vendorId} | Interface: ${device.interfaceCount} (${device.getInterface(0).name})"
)
)
//https://www.allaboutcircuits.com/projects/communicate-with-your-arduino-through-android/
// here request the permission
try {
usbDevice = device
var pi = PendingIntent.getBroadcast(activity, 0, Intent(ACTION_USB_PERMISSION), 0)
val filter = IntentFilter(ACTION_USB_PERMISSION)
activity?.registerReceiver(usbReceiver, filter)
usbManager.requestPermission(usbDevice, pi)
} catch (e: Exception) {
}
}
if (usbManager.accessoryList != null) {
for (accessory in usbManager.accessoryList) {
deviceList.add(
UsbDevice(
id = accessory.serial.toString(),
name = accessory.description.toString(),
model = "accessory"
)
)
}
}
return deviceList
}
private fun showEmptyListMessage(message: String) {
listView.visibility = View.GONE
emptyListMessageWrapper.visibility = View.VISIBLE
emptyListMessage.setText(message)
}
}
它没有从 WaterRower 机器获取任何数据。
这是我的 device_filter.xml。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 0x0403 / 0x60??: FTDI -->
<usb-device vendor-id="1027" product-id="24577" /> <!-- 0x6001: FT232R -->
<usb-device vendor-id="1027" product-id="24592" /> <!-- 0x6010: FT2232H -->
<usb-device vendor-id="1027" product-id="24593" /> <!-- 0x6011: FT4232H -->
<usb-device vendor-id="1027" product-id="24596" /> <!-- 0x6014: FT232H -->
<usb-device vendor-id="1027" product-id="24597" /> <!-- 0x6015: FT230X, FT231X, FT234XD -->
<!-- 0x10C4 / 0xEA??: Silabs CP210x -->
<usb-device vendor-id="4292" product-id="60000" /> <!-- 0xea60: CP2102 and other CP210x single port devices -->
<usb-device vendor-id="4292" product-id="60016" /> <!-- 0xea70: CP2105 -->
<usb-device vendor-id="4292" product-id="60017" /> <!-- 0xea71: CP2108 -->
<!-- 0x067B / 0x23?3: Prolific PL2303x -->
<usb-device vendor-id="1659" product-id="8963" /> <!-- 0x2303: PL2303HX, HXD, TA, ... -->
<usb-device vendor-id="1659" product-id="9123" /> <!-- 0x23a3: PL2303GC -->
<usb-device vendor-id="1659" product-id="9139" /> <!-- 0x23b3: PL2303GB -->
<usb-device vendor-id="1659" product-id="9155" /> <!-- 0x23c3: PL2303GT -->
<usb-device vendor-id="1659" product-id="9171" /> <!-- 0x23d3: PL2303GL -->
<usb-device vendor-id="1659" product-id="9187" /> <!-- 0x23e3: PL2303GE -->
<usb-device vendor-id="1659" product-id="9203" /> <!-- 0x23f3: PL2303GS -->
<!-- 0x1a86 / 0x?523: Qinheng CH34x -->
<usb-device vendor-id="6790" product-id="21795" /> <!-- 0x5523: CH341A -->
<usb-device vendor-id="6790" product-id="29987" /> <!-- 0x7523: CH340 -->
<!-- CDC driver -->
<usb-device vendor-id="9025" /> <!-- 0x2341 / ......: Arduino (67 = 0x0043)-->
<usb-device vendor-id="5824" product-id="1155" /> <!-- 0x16C0 / 0x0483: Teensyduino -->
<usb-device vendor-id="1003" product-id="8260" /> <!-- 0x03EB / 0x2044: Atmel Lufa -->
<usb-device vendor-id="7855" product-id="4" /> <!-- 0x1eaf / 0x0004: Leaflabs Maple -->
<usb-device vendor-id="3368" product-id="516" /> <!-- 0x0d28 / 0x0204: ARM mbed -->
<usb-device vendor-id="1155" product-id="22336" /><!-- 0x0483 / 0x5740: ST CDC -->
<usb-device vendor-id="1240" product-id="10" /><!-- 0x0d8 / 0x000a WaterRower -->
</resources>
我的代码有什么问题,我该如何解决?
解决方案
推荐阅读
- angular - 从 Angular 5 中的 URL 获取数据
- angular - 将 Angular CLI 1.7.3 升级到 6.2.2 后的问题
- excel - 使用 WPF (OLEDB) 在 Excel 中保存序列号
- python - 保护用于签名 Chrome WebExtension 的私钥
- linux - bash - 基于进程条件的返回值
- python - 为 Django 中的多对多字段自定义模型序列化器
- apache-httpclient-4.x - Creating a Custom Apache HTTP Client Redirect policy
- vim - 如何从 fzf.vim 搜索中排除结果
- r - 仅向数据框 R 中的特定行添加前缀
- sql - 节点服务器不等待oracle db响应并重新执行请求方法