KMP BLE Demo(iOS & Android):通过 OP-BT / OP-BTS 蓝牙光电头发送命令并显示响应
本页面依据最新的 KMP BLE Demo-251222-ios-android.md 示例整理,演示如何使用 Kotlin Multiplatform (KMP) + Android BLE GATT + iOS CoreBluetooth 与 OP-BT / OP-BTS 设备通信,在 Android 和 iOS 上发送命令 BaudTran,9600,N,8,1,并在界面上显示设备返回结果(例如:OK,VER=01.00)。两个平台通过 KMP 输出的 shared 模块共享核心逻辑。
1. 构建要求与环境准备
- 开发工具:Android Studio
- Kotlin Multiplatform (KMP) 模板必须在 File → New → New Project 下可用
- JDK:Gradle/AGP 运行在 JDK 17 上。项目编译目标为 Java 11
- 新建项目参数:
- 项目名称:
OPManagerDemo - 模板:Kotlin Multiplatform (KMP)
- 语言:Kotlin
- 最低 SDK:Android 5.0 (API 21) 及以上
- 项目名称:
源代码
本示例的完整源代码可在 GitHub 上获取:
您可以直接克隆仓库并在 Android Studio 中打开:
git clone https://github.com/zenovate-team/OPManagerDemo-KMP.git
cd OPManagerDemo-KMP
2. Demo 功能说明
2.1 主要功能
- 扫描附近的 BLE 蓝牙设备
- 列表展示设备名称和 MAC 地址
- 选择目标设备并建立 BLE GATT 连接
- 发送命令:
BaudTran,9600,N,8,1 - 通过通知特征接收设备返回,例如:
OK,VER=01.00 - 在界面上以日志方式显示连接状态 / 发送命令 / 接收数据
2.2 使用到的 API / 库
- 蓝牙通信(BLE GATT):
BluetoothLeScannerBluetoothGatt/BluetoothGattCallbackBluetoothGattCharacteristic/BluetoothGattDescriptor
- 运行时权限:
- AndroidX Activity Result API:
ActivityResultContracts.RequestMultiplePermissions
- AndroidX Activity Result API:
- Kotlin Multiplatform:
- 包含
commonMain和androidMain源集的共享模块 - 用于跨平台兼容性的共享模型和工具
- 包含
2.3 通信协议与 UUID
-
文本命令:
- 发送:
BaudTran,9600,N,8,1 - 典型响应:
OK,VER=01.00
- 发送:
-
GATT UUID 配置(支持 16-bit / 32-bit / 128-bit 写法):
- Service UUID:
18F0 - Notification Characteristic UUID:
2AF0 - Write Characteristic UUID:
2AF1
- Service UUID:
3. 界面截图

设备扫描列表界面示意图

命令发送与响应日志界面示意图
4. 修改 Android 权限(AndroidManifest.xml)
编辑:app/src/main/AndroidManifest.xml,参考配置如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 蓝牙权限(兼容 Android 12 前后) -->
<!-- Android 11 及以下使用的传统蓝牙 / 位置权限 -->
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
<!-- Android 12+ 新增蓝牙运行时权限 -->
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- 蓝牙 / BLE 硬件特性(可选,推荐设为 false,方便非 BLE 设备安装) -->
<uses-feature
android:name="android.hardware.bluetooth"
android:required="false" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="false" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.OPManagerDemo">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.OPManagerDemo">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
运行时权限申请逻辑在 Kotlin 代码中通过 ActivityResultContracts.RequestMultiplePermissions 实现(见下节)。
5. 同步项目(Gradle)
打开项目后,点击 Sync Now(或 File → Sync Project with Gradle Files)。
- Gradle 会自动下载此仓库定义的所需依赖和 Android 组件。
- 同步成功后,项目应该能够在设备上构建和运行。
在此阶段,您不需要手动添加依赖。接下来的步骤专注于权限和 BLE 逻辑。
6. 关键 Kotlin 代码结构
完整源码请参考同目录下的 KMP BLE Demo-251218.md。此 KMP 项目使用共享模块结构:
6.1 主 Activity(Android 应用模块)
app/src/main/java/com/example/opmanager/opmanager/demo/MainActivity.kt- 包含 UI(Jetpack Compose)、BluetoothController、BleConnectionManager
- 使用来自
com.example.opmanager.shared包的共享模型
6.2 共享模块(KMP)
共享模块包含被 Android 和 iOS 共同使用的平台无关代码:
-
shared/src/commonMain/kotlin/com/example/opmanager/shared/BleConfigStrings.kt- UUID 字符串常量(支持 16-bit / 32-bit / 128-bit)
- Service UUID:
18f0,Write UUID:2af1,Notify UUID:2af0
-
shared/src/androidMain/kotlin/com/example/opmanager/shared/BleConfig.kt- Android 特定的 UUID 解析(从字符串转换为
UUID对象)
- Android 特定的 UUID 解析(从字符串转换为
-
shared/src/commonMain/kotlin/com/example/opmanager/shared/SharedModels.ktBluetoothDeviceUi、ConnectionLog、LogType、ConnectionState
-
shared/src/commonMain/kotlin/com/example/opmanager/shared/BleTextCommandFormatter.kt- 命令格式化工具(转义处理、追加 CRLF)
-
shared/src/commonMain/kotlin/com/example/opmanager/shared/BleIncomingProcessor.kt- 处理传入的 BLE 通知文本并生成日志
更完整的 Android / iOS 实现示例(包括 MainActivity.kt、BleConnectionManager、BleCentralManager.swift 以及共享工具类)请参考 KMP BLE Demo-251222-ios-android.md 以及对应的 GitHub 仓库源码。
7. 运行步骤(Android & iOS)
7.1 Android
- 用 USB 数据线连接手机与电脑,您会看到调试权限请求。
- 在 Android Studio 中点击 Run ▶ 并选择你的设备
- App 启动后:
- 点击 Scan
- 如果 Android 请求蓝牙/位置权限,请授予它们
- 在列表中点击设备进行连接
- 发送命令
BaudTran,9600,N,8,1 - 显示结果
OK,VER=01.00
7.2 iOS
iOS Demo 使用 Xcode 构建,并依赖由 Gradle 生成的 KMP 共享模块 (shared.framework),具体配置请参考 KMP BLE Demo-251222-ios-android.md。
- 确保已安装 Xcode 16.4+,并在
PATH中可以找到 Java(JDK 17)(例如执行java -version验证) - 在 Xcode 中打开 iOS App 工程(例如
iosApp/OPManagerIOSDemo.xcodeproj) - 编译工程:Xcode 会调用 Gradle 任务(如
:shared:packForXcode)生成/更新shared.framework - 在真实的 iPhone 上运行 OPManagerIOSDemo scheme,在系统提示时授予蓝牙权限
- 在 App 中:
- 点击 Scan 扫描附近 BLE 设备
- 在列表中选择 OP-BT/BTS 设备并点击 Connect
- 在输入框中输入命令(如
BaudTran,9600,N,8,1)并点击 Send - 在日志列表中可以看到设备返回的通知数据(例如
OK,VER=01.00)