feat(ch934x_serial): 添加串口写入功能的端口索引参数
- write方法新增可选的serialPortIndex参数,支持直接写入指定端口 - 传入端口索引时不会改变当前活跃端口,保持原有活跃端口行为 - 添加对负数端口索引的验证处理,直接返回零避免异常 - 更新文档说明多端口并发客户端应使用显式端口写入方式 - 增加相关单元测试覆盖新参数的各种使用场景 - 同步更新Android原生层实现以支持端口索引传递
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
## 1.0.1
|
||||||
|
|
||||||
|
- `write` 新增可选 `serialPortIndex` 参数;传入时直接写入指定端口且不修改当前活跃端口,省略时保持原有活跃端口行为。
|
||||||
|
|
||||||
## 1.0.0
|
## 1.0.0
|
||||||
|
|
||||||
- 重构插件代码,完整对接 CH934X Android SDK 文档中定义的全部接口:
|
- 重构插件代码,完整对接 CH934X Android SDK 文档中定义的全部接口:
|
||||||
|
|||||||
@@ -584,9 +584,14 @@ public class Ch934xSerialPlugin implements FlutterPlugin, MethodCallHandler, Act
|
|||||||
if (data == null || data.length == 0) {
|
if (data == null || data.length == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Integer portIndex = call.argument("serialPortIndex");
|
||||||
|
int idx = portIndex != null ? portIndex : activeSerialNumber;
|
||||||
|
if (idx < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return CH934XManager.getInstance().writeData(
|
return CH934XManager.getInstance().writeData(
|
||||||
activeDevice, activeSerialNumber, data, data.length, 2000);
|
activeDevice, idx, data, data.length, 2000);
|
||||||
} catch (ChipException e) {
|
} catch (ChipException e) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,11 +161,14 @@ await plugin.closePort();
|
|||||||
### 3.3 串口读写
|
### 3.3 串口读写
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
// 写入
|
// 写入当前活跃端口(向后兼容)
|
||||||
final bytes = Uint8List.fromList([0x01, 0x02, 0x03]);
|
final bytes = Uint8List.fromList([0x01, 0x02, 0x03]);
|
||||||
final written = await plugin.write(bytes);
|
final written = await plugin.write(bytes);
|
||||||
debugPrint('写入字节数: $written');
|
debugPrint('写入字节数: $written');
|
||||||
|
|
||||||
|
// 写入指定端口,不改变当前活跃端口;多端口客户端应使用此形式。
|
||||||
|
final portWritten = await plugin.write(bytes, serialPortIndex: 2);
|
||||||
|
|
||||||
// 读取(单次)
|
// 读取(单次)
|
||||||
final recv = await plugin.read(1024);
|
final recv = await plugin.read(1024);
|
||||||
if (recv.isEmpty) debugPrint('暂无数据');
|
if (recv.isEmpty) debugPrint('暂无数据');
|
||||||
@@ -182,13 +185,13 @@ await sub.cancel();
|
|||||||
- `length <= 0` 时**不会调用原生层**,直接返回空数组。
|
- `length <= 0` 时**不会调用原生层**,直接返回空数组。
|
||||||
- SDK 的 `readData` 会返回内部缓冲的所有数据,插件按
|
- SDK 的 `readData` 会返回内部缓冲的所有数据,插件按
|
||||||
`min(data.length, length)` 截断后回传。
|
`min(data.length, length)` 截断后回传。
|
||||||
- `write(data)` 返回实际写入字节数,失败时为 0。
|
- `write(data, serialPortIndex: n)` 返回实际写入字节数;传入端口时直接写入该端口且不改变当前活跃端口,失败时为 0。省略 `serialPortIndex` 时保持原有的当前活跃端口行为。
|
||||||
- `dataStream` 默认 `chunkSize = 1024`、`interval = 20ms`,内部
|
- `dataStream` 默认 `chunkSize = 1024`、`interval = 20ms`,内部
|
||||||
持续以 [interval] 为周期反复调用 `read`;当底层无数据时返回
|
持续以 [interval] 为周期反复调用 `read`;当底层无数据时返回
|
||||||
空缓冲区,消费者可据此判定。`chunkSize <= 0` 会抛
|
空缓冲区,消费者可据此判定。`chunkSize <= 0` 会抛
|
||||||
`ArgumentError`。
|
`ArgumentError`。
|
||||||
- 业务方在 widget dispose 时记得 `cancel` 订阅并 `closePort`。
|
- 业务方在 widget dispose 时记得 `cancel` 订阅并 `closePort`。
|
||||||
- `read`/`write` 都针对**当前活跃串口**;切换串口用 `setActivePort`。
|
- `read` 默认针对当前活跃串口,也可传入显式端口;`write` 省略 `serialPortIndex` 时针对当前活跃串口,传入时直接写入指定端口。多端口并发客户端应使用显式端口写入,避免通过 `setActivePort` 共享切换端口。
|
||||||
|
|
||||||
### 3.4 GPIO 接口
|
### 3.4 GPIO 接口
|
||||||
|
|
||||||
|
|||||||
+35
-35
@@ -6,7 +6,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
|
sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.13.1"
|
version: "2.13.1"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
@@ -14,7 +14,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.2"
|
||||||
ch934x_serial:
|
ch934x_serial:
|
||||||
@@ -23,13 +23,13 @@ packages:
|
|||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "1.0.0"
|
version: "1.0.1"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.1"
|
||||||
clock:
|
clock:
|
||||||
@@ -37,7 +37,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.2"
|
version: "1.1.2"
|
||||||
collection:
|
collection:
|
||||||
@@ -45,7 +45,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.19.1"
|
version: "1.19.1"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
@@ -53,7 +53,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd"
|
sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.9"
|
version: "1.0.9"
|
||||||
fake_async:
|
fake_async:
|
||||||
@@ -61,7 +61,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.3"
|
version: "1.3.3"
|
||||||
file:
|
file:
|
||||||
@@ -69,7 +69,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
flutter:
|
flutter:
|
||||||
@@ -87,7 +87,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
|
sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.0"
|
version: "6.0.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -110,7 +110,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.0.2"
|
version: "11.0.2"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
@@ -118,7 +118,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.10"
|
version: "3.0.10"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
@@ -126,7 +126,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "3.0.2"
|
||||||
lints:
|
lints:
|
||||||
@@ -134,7 +134,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df"
|
sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.0"
|
version: "6.1.0"
|
||||||
matcher:
|
matcher:
|
||||||
@@ -142,7 +142,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.19"
|
version: "0.12.19"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
@@ -150,23 +150,23 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.0"
|
version: "0.13.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.17.0"
|
version: "1.18.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
platform:
|
platform:
|
||||||
@@ -174,7 +174,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.6"
|
version: "3.1.6"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
@@ -182,7 +182,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
process:
|
process:
|
||||||
@@ -190,7 +190,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: process
|
name: process
|
||||||
sha256: c6248e4526673988586e8c00bb22a49210c258dc91df5227d5da9748ecf79744
|
sha256: c6248e4526673988586e8c00bb22a49210c258dc91df5227d5da9748ecf79744
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.5"
|
version: "5.0.5"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
@@ -203,7 +203,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
|
sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.2"
|
version: "1.10.2"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
@@ -211,7 +211,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.12.1"
|
version: "1.12.1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
@@ -219,7 +219,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
@@ -227,7 +227,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.1"
|
||||||
sync_http:
|
sync_http:
|
||||||
@@ -235,7 +235,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: sync_http
|
name: sync_http
|
||||||
sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
|
sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.1"
|
version: "0.3.1"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
@@ -243,23 +243,23 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.2"
|
version: "1.2.2"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
|
sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.10"
|
version: "0.7.11"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.2.0"
|
||||||
vm_service:
|
vm_service:
|
||||||
@@ -267,7 +267,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
|
sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.2.0"
|
version: "15.2.0"
|
||||||
webdriver:
|
webdriver:
|
||||||
@@ -275,7 +275,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: webdriver
|
name: webdriver
|
||||||
sha256: "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade"
|
sha256: "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
|
|||||||
+11
-13
@@ -29,16 +29,14 @@ class Ch934xSerial {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
/// 获取所有已连接的 CH934X 设备信息。
|
/// 获取所有已连接的 CH934X 设备信息。
|
||||||
Future<List<Ch934xDeviceInfo>> getDeviceList() =>
|
Future<List<Ch934xDeviceInfo>> getDeviceList() => _platform.getDeviceList();
|
||||||
_platform.getDeviceList();
|
|
||||||
|
|
||||||
/// 获取指定设备序列号;非 CH934X 设备时返回 null。
|
/// 获取指定设备序列号;非 CH934X 设备时返回 null。
|
||||||
Future<String?> getSerialNumber(int deviceId) =>
|
Future<String?> getSerialNumber(int deviceId) =>
|
||||||
_platform.getSerialNumber(deviceId);
|
_platform.getSerialNumber(deviceId);
|
||||||
|
|
||||||
/// 获取指定设备类型,取值见 [Ch934xDeviceType]。
|
/// 获取指定设备类型,取值见 [Ch934xDeviceType]。
|
||||||
Future<int> getDeviceType(int deviceId) =>
|
Future<int> getDeviceType(int deviceId) => _platform.getDeviceType(deviceId);
|
||||||
_platform.getDeviceType(deviceId);
|
|
||||||
|
|
||||||
/// 获取指定设备的串口列表。
|
/// 获取指定设备的串口列表。
|
||||||
Future<List<Ch934xSerialPortInfo>> getSerialPortList(
|
Future<List<Ch934xSerialPortInfo>> getSerialPortList(
|
||||||
@@ -85,7 +83,11 @@ class Ch934xSerial {
|
|||||||
Future<Uint8List> read(int length) => _platform.read(length);
|
Future<Uint8List> read(int length) => _platform.read(length);
|
||||||
|
|
||||||
/// 写入数据,返回实际写入的字节数。
|
/// 写入数据,返回实际写入的字节数。
|
||||||
Future<int> write(Uint8List data) => _platform.write(data);
|
///
|
||||||
|
/// [serialPortIndex] 为空时沿用当前活跃串口;传入时直接写入指定端口,
|
||||||
|
/// 不会改变当前活跃串口。
|
||||||
|
Future<int> write(Uint8List data, {int? serialPortIndex}) =>
|
||||||
|
_platform.write(data, serialPortIndex: serialPortIndex);
|
||||||
|
|
||||||
/// 构造一个持续从串口拉取数据的 `Stream<Uint8List>`。
|
/// 构造一个持续从串口拉取数据的 `Stream<Uint8List>`。
|
||||||
///
|
///
|
||||||
@@ -180,12 +182,10 @@ class Ch934xSerial {
|
|||||||
Future<int> getCurrentMode() => _platform.getCurrentMode();
|
Future<int> getCurrentMode() => _platform.getCurrentMode();
|
||||||
|
|
||||||
/// 获取 GPIO 数量。
|
/// 获取 GPIO 数量。
|
||||||
Future<int> getGpiocount(int deviceId) =>
|
Future<int> getGpiocount(int deviceId) => _platform.getGpiocount(deviceId);
|
||||||
_platform.getGpiocount(deviceId);
|
|
||||||
|
|
||||||
/// 获取 GPIO 组数。
|
/// 获取 GPIO 组数。
|
||||||
Future<int> getGpiogroup(int deviceId) =>
|
Future<int> getGpiogroup(int deviceId) => _platform.getGpiogroup(deviceId);
|
||||||
_platform.getGpiogroup(deviceId);
|
|
||||||
|
|
||||||
/// 使能 GPIO。
|
/// 使能 GPIO。
|
||||||
Future<bool> enableGpio({
|
Future<bool> enableGpio({
|
||||||
@@ -222,12 +222,10 @@ class Ch934xSerial {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// 查询设备是否已打开。
|
/// 查询设备是否已打开。
|
||||||
Future<bool> isConnected(int deviceId) =>
|
Future<bool> isConnected(int deviceId) => _platform.isConnected(deviceId);
|
||||||
_platform.isConnected(deviceId);
|
|
||||||
|
|
||||||
/// 获取当前已打开的设备 ID 列表。
|
/// 获取当前已打开的设备 ID 列表。
|
||||||
Future<List<int>> getConnectedDevices() =>
|
Future<List<int>> getConnectedDevices() => _platform.getConnectedDevices();
|
||||||
_platform.getConnectedDevices();
|
|
||||||
|
|
||||||
/// 配置当前活跃串口的参数。
|
/// 配置当前活跃串口的参数。
|
||||||
Future<bool> setSerialParameter({
|
Future<bool> setSerialParameter({
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ import 'src/models/models.dart';
|
|||||||
class MethodChannelCh934xSerial extends Ch934xSerialPlatform {
|
class MethodChannelCh934xSerial extends Ch934xSerialPlatform {
|
||||||
/// 测试时可被替换的 MethodChannel。
|
/// 测试时可被替换的 MethodChannel。
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
final MethodChannel methodChannel =
|
final MethodChannel methodChannel = const MethodChannel('ch934x_serial');
|
||||||
const MethodChannel('ch934x_serial');
|
|
||||||
|
|
||||||
/// 通知 Dart 侧的异常事件流,用于支持 `setExceptionCallback`。
|
/// 通知 Dart 侧的异常事件流,用于支持 `setExceptionCallback`。
|
||||||
final StreamController<Ch934xException> _exceptionController =
|
final StreamController<Ch934xException> _exceptionController =
|
||||||
@@ -39,7 +38,8 @@ class MethodChannelCh934xSerial extends Ch934xSerialPlatform {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Ch934xDeviceInfo>> getDeviceList() async {
|
Future<List<Ch934xDeviceInfo>> getDeviceList() async {
|
||||||
final raw = await methodChannel.invokeMethod<List<dynamic>>('getDeviceList');
|
final raw =
|
||||||
|
await methodChannel.invokeMethod<List<dynamic>>('getDeviceList');
|
||||||
if (raw == null) {
|
if (raw == null) {
|
||||||
return const <Ch934xDeviceInfo>[];
|
return const <Ch934xDeviceInfo>[];
|
||||||
}
|
}
|
||||||
@@ -137,14 +137,15 @@ class MethodChannelCh934xSerial extends Ch934xSerialPlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> write(Uint8List data) async {
|
Future<int> write(Uint8List data, {int? serialPortIndex}) async {
|
||||||
if (data.isEmpty) {
|
if (data.isEmpty || (serialPortIndex != null && serialPortIndex < 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
final result = await methodChannel.invokeMethod<int>(
|
final args = <String, Object>{'data': data};
|
||||||
'write',
|
if (serialPortIndex != null) {
|
||||||
<String, Object>{'data': data},
|
args['serialPortIndex'] = serialPortIndex;
|
||||||
);
|
}
|
||||||
|
final result = await methodChannel.invokeMethod<int>('write', args);
|
||||||
return result ?? 0;
|
return result ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +226,8 @@ class MethodChannelCh934xSerial extends Ch934xSerialPlatform {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> getCurrentMode() {
|
Future<int> getCurrentMode() {
|
||||||
return methodChannel.invokeMethod<int>('getCurrentMode')
|
return methodChannel
|
||||||
|
.invokeMethod<int>('getCurrentMode')
|
||||||
.then((v) => v ?? -1);
|
.then((v) => v ?? -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +303,8 @@ class MethodChannelCh934xSerial extends Ch934xSerialPlatform {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<int>> getConnectedDevices() async {
|
Future<List<int>> getConnectedDevices() async {
|
||||||
final raw = await methodChannel.invokeMethod<List<dynamic>>('getConnectedDevices');
|
final raw =
|
||||||
|
await methodChannel.invokeMethod<List<dynamic>>('getConnectedDevices');
|
||||||
if (raw == null) return const <int>[];
|
if (raw == null) return const <int>[];
|
||||||
return raw.whereType<int>().toList(growable: false);
|
return raw.whereType<int>().toList(growable: false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,9 @@ abstract class Ch934xSerialPlatform extends PlatformInterface {
|
|||||||
Future<Uint8List> read(int length, {int? serialPortIndex});
|
Future<Uint8List> read(int length, {int? serialPortIndex});
|
||||||
|
|
||||||
/// 向串口写入数据(对应 6.2.1 `UsbSerial.write`)。
|
/// 向串口写入数据(对应 6.2.1 `UsbSerial.write`)。
|
||||||
Future<int> write(Uint8List data);
|
///
|
||||||
|
/// [serialPortIndex] 为空时使用当前活跃端口;传入时直接写入指定端口。
|
||||||
|
Future<int> write(Uint8List data, {int? serialPortIndex});
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// GPIO
|
// GPIO
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
name: ch934x_serial
|
name: ch934x_serial
|
||||||
description: "Flutter 插件,封装南京沁恒 CH934X 系列 USB 转串口芯片的 Android SDK,提供设备查找、串口读写、GPIO 与 Modem 控制等能力。"
|
description: "Flutter 插件,封装南京沁恒 CH934X 系列 USB 转串口芯片的 Android SDK,提供设备查找、串口读写、GPIO 与 Modem 控制等能力。"
|
||||||
version: 1.0.0
|
version: 1.0.1
|
||||||
homepage: https://example.com/ch934x_serial
|
homepage: https://example.com/ch934x_serial
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
@@ -69,13 +69,39 @@ void main() {
|
|||||||
test('write 将数据写入原生层并回传字节数', () async {
|
test('write 将数据写入原生层并回传字节数', () async {
|
||||||
mockCall((call) async {
|
mockCall((call) async {
|
||||||
expect(call.method, 'write');
|
expect(call.method, 'write');
|
||||||
expect((call.arguments as Map)['data'], isA<Uint8List>());
|
expect(call.arguments, <String, Object>{
|
||||||
|
'data': Uint8List.fromList([9, 8, 7]),
|
||||||
|
});
|
||||||
return 3;
|
return 3;
|
||||||
});
|
});
|
||||||
final written = await platform.write(Uint8List.fromList([9, 8, 7]));
|
final written = await platform.write(Uint8List.fromList([9, 8, 7]));
|
||||||
expect(written, 3);
|
expect(written, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('write 透传显式串口索引', () async {
|
||||||
|
mockCall((call) async {
|
||||||
|
expect(call.method, 'write');
|
||||||
|
expect(call.arguments, <String, Object>{
|
||||||
|
'data': Uint8List.fromList([9, 8, 7]),
|
||||||
|
'serialPortIndex': 2,
|
||||||
|
});
|
||||||
|
return 3;
|
||||||
|
});
|
||||||
|
final written = await platform.write(
|
||||||
|
Uint8List.fromList([9, 8, 7]),
|
||||||
|
serialPortIndex: 2,
|
||||||
|
);
|
||||||
|
expect(written, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('write 接收负串口索引直接返回零', () async {
|
||||||
|
final written = await platform.write(
|
||||||
|
Uint8List.fromList([9]),
|
||||||
|
serialPortIndex: -1,
|
||||||
|
);
|
||||||
|
expect(written, 0);
|
||||||
|
});
|
||||||
|
|
||||||
test('getModemStatus 默认回退到 0', () async {
|
test('getModemStatus 默认回退到 0', () async {
|
||||||
mockCall((_) async => null);
|
mockCall((_) async => null);
|
||||||
expect(await platform.getModemStatus(), 0);
|
expect(await platform.getModemStatus(), 0);
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class _MockCh934xSerialPlatform extends Ch934xSerialPlatform
|
|||||||
bool closeResult;
|
bool closeResult;
|
||||||
Uint8List? readBytes;
|
Uint8List? readBytes;
|
||||||
int writeResult;
|
int writeResult;
|
||||||
|
int? lastWritePort;
|
||||||
bool gpioOutputResult;
|
bool gpioOutputResult;
|
||||||
int gpioInput;
|
int gpioInput;
|
||||||
bool modemControlResult;
|
bool modemControlResult;
|
||||||
@@ -63,8 +64,7 @@ class _MockCh934xSerialPlatform extends Ch934xSerialPlatform
|
|||||||
Future<List<Ch934xSerialPortInfo>> getSerialPortList(
|
Future<List<Ch934xSerialPortInfo>> getSerialPortList(
|
||||||
int deviceId, {
|
int deviceId, {
|
||||||
required int interfaceNumber,
|
required int interfaceNumber,
|
||||||
}) async =>
|
}) async => ports;
|
||||||
ports;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> openPort(Ch934xPortTarget target) async => openResult;
|
Future<bool> openPort(Ch934xPortTarget target) async => openResult;
|
||||||
@@ -79,17 +79,20 @@ class _MockCh934xSerialPlatform extends Ch934xSerialPlatform
|
|||||||
Future<bool> requestUsbPermission(int deviceId) async => true;
|
Future<bool> requestUsbPermission(int deviceId) async => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Uint8List> read(int length, {int? serialPortIndex}) async => readBytes ?? Uint8List(0);
|
Future<Uint8List> read(int length, {int? serialPortIndex}) async =>
|
||||||
|
readBytes ?? Uint8List(0);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> write(Uint8List data) async => writeResult;
|
Future<int> write(Uint8List data, {int? serialPortIndex}) async {
|
||||||
|
lastWritePort = serialPortIndex;
|
||||||
|
return writeResult;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> setGpioOutput({
|
Future<bool> setGpioOutput({
|
||||||
required int gpioNumber,
|
required int gpioNumber,
|
||||||
required int level,
|
required int level,
|
||||||
}) async =>
|
}) async => gpioOutputResult;
|
||||||
gpioOutputResult;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> getGpioInput(int gpioNumber) async => gpioInput;
|
Future<int> getGpioInput(int gpioNumber) async => gpioInput;
|
||||||
@@ -105,13 +108,19 @@ class _MockCh934xSerialPlatform extends Ch934xSerialPlatform
|
|||||||
Future<void> setExceptionCallback(
|
Future<void> setExceptionCallback(
|
||||||
void Function(Ch934xException exception) onException,
|
void Function(Ch934xException exception) onException,
|
||||||
) async {}
|
) async {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
test('默认平台实现是 MethodChannelCh934xSerial', () {
|
test('默认平台实现是 MethodChannelCh934xSerial', () {
|
||||||
expect(Ch934xSerialPlatform.instance, isInstanceOf<MethodChannelCh934xSerial>());
|
expect(
|
||||||
|
Ch934xSerialPlatform.instance,
|
||||||
|
isInstanceOf<MethodChannelCh934xSerial>(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Ch934xSerial 委托 platform 调用 getDeviceList', () async {
|
test('Ch934xSerial 委托 platform 调用 getDeviceList', () async {
|
||||||
@@ -131,6 +140,20 @@ void main() {
|
|||||||
expect(list.single.serialNumber, 'SN-1');
|
expect(list.single.serialNumber, 'SN-1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Ch934xSerial write 透传可选串口索引', () async {
|
||||||
|
final mock = _MockCh934xSerialPlatform(writeResult: 3);
|
||||||
|
final plugin = Ch934xSerial.withPlatform(mock);
|
||||||
|
|
||||||
|
expect(await plugin.write(Uint8List.fromList([1, 2, 3])), 3);
|
||||||
|
expect(mock.lastWritePort, isNull);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await plugin.write(Uint8List.fromList([1, 2, 3]), serialPortIndex: 4),
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
expect(mock.lastWritePort, 4);
|
||||||
|
});
|
||||||
|
|
||||||
test('ModemStatus.isSet 按位与工作', () {
|
test('ModemStatus.isSet 按位与工作', () {
|
||||||
const status = ModemStatus.cts | ModemStatus.dcd;
|
const status = ModemStatus.cts | ModemStatus.dcd;
|
||||||
expect(ModemStatus.isSet(status, ModemStatus.cts), isTrue);
|
expect(ModemStatus.isSet(status, ModemStatus.cts), isTrue);
|
||||||
|
|||||||
Reference in New Issue
Block a user