Kotlin 代码范例 - 通过 OP-BT / OP-BTS 蓝牙光电头发送命令并显示响应


Kotlin BLE Demo:通过 OP-BT / OP-BTS 蓝牙光电头发送命令并显示响应

本页面根据 Kotlin BLE Demo-251218.txt 示例整理,演示如何使用 Kotlin + Android BLE GATT 与 OP-BT / OP-BTS 设备通信,发送命令 BaudTran,9600,N,8,1,并在界面上显示设备返回结果(例如:OK,VER=01.00)。

1. 环境准备

  • 开发工具:Android Studio(建议搭配 JDK 11 / Java 11)
  • 新建项目参数:
    • 项目名称:OPManagerDemo
    • 模板:Empty Activity
    • 语言:Kotlin
    • 最低 SDK:建议 Android 8.0(API 26) 及以上,方便做 BLE 演示

源代码

本示例的完整源代码可在 GitHub 上获取:

您可以直接克隆仓库并在 Android Studio 中打开:

git clone https://github.com/zenovate-team/OPManagerDemo-kotlin.git
cd OPManagerDemo-kotlin

2. Demo 功能说明

2.1 主要功能

  1. 扫描附近的 BLE 蓝牙设备
  2. 列表展示设备名称和 MAC 地址
  3. 选择目标设备并建立 BLE GATT 连接
  4. 发送命令:BaudTran,9600,N,8,1
  5. 通过通知特征接收设备返回,例如:OK,VER=01.00
  6. 在界面上以日志方式显示连接状态 / 发送命令 / 接收数据

2.2 使用到的 API / 库

  • 蓝牙通信(BLE GATT)
    • BluetoothLeScanner
    • BluetoothGatt / BluetoothGattCallback
    • BluetoothGattCharacteristic / BluetoothGattDescriptor
  • 运行时权限
    • AndroidX Activity Result API:ActivityResultContracts.RequestMultiplePermissions

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

3. 界面截图

设备扫描界面:展示附近 BLE 设备并提供连接按钮

设备扫描列表界面示意图

连接详情界面:输入命令并显示设备响应日志

命令发送与响应日志界面示意图

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. 关键 Kotlin 代码片段

完整源码请参考同目录下的 Kotlin BLE Demo-251218.txt。下面仅摘录与发送命令和接收响应相关的关键逻辑,便于快速查看:

object BleConfig {
    const val SERVICE_UUID_STR = "18f0"
    const val WRITE_CHAR_UUID_STR = "2af1"
    const val NOTIFY_CHAR_UUID_STR = "2af0"
    // 省略 UUID 转换代码...
}

class BleConnectionManager(private val context: Context) {
    // 省略成员变量与构造...

    fun connect(
        address: String,
        onStateChange: (ConnectionState) -> Unit,
        onLog: (ConnectionLog) -> Unit
    ) {
        // 通过 MAC 地址建立 GATT 连接、发现服务并找到写特征与通知特征
        // 详细实现见 Kotlin BLE Demo-251218.txt
    }

    fun send(
        text: String,
        onLog: (ConnectionLog) -> Unit
    ) {
        // 将命令按 ASCII+CRLF 写入写特征
        val payload = text + "\r\n"
        // gatt.writeCharacteristic(writeCharacteristic)
        onLog(ConnectionLog(LogType.SEND, "Sending: $text"))
    }
}

@Composable
private fun ConnectionDetailScreen(
    device: BluetoothDeviceUi?,
    connectionState: ConnectionState,
    logs: List<ConnectionLog>,
    onBack: () -> Unit,
    onReconnect: () -> Unit,
    onSendCommand: (String) -> Unit
) {
    // 默认命令为 BaudTran,9600,N,8,1
    var commandText by remember { mutableStateOf("BaudTran,9600,N,8,1") }
    // 省略 UI 代码...
}

6. 运行步骤

  1. 用 USB 数据线连接手机与电脑,在手机端允许 USB 调试权限
  2. 在 Android Studio 中点击 Run ▶ 并选择你的手机设备
  3. App 启动后:
    • 首次会弹出蓝牙 / 位置权限请求,全部允许
    • 在设备列表页点击右上角 Scan 开始扫描
    • 在列表中点击目标 OP-BT / OP-BTS 设备进行连接
  4. 在“连接详情”界面中:
    • 默认命令为 BaudTran,9600,N,8,1,可直接点击 Send
    • 下方日志区域会显示发送记录和设备返回,例如 OK,VER=01.00