【问题标题】:How to parse Eddystone UID BLE beacon info如何解析 Eddystone UID BLE 信标信息
【发布时间】:2021-05-10 11:35:17
【问题描述】:

我正在尝试为 BLE Eddystone UID 数据包编写解析器,但不知道该怎么做。 我正在使用 Beacon Simulator App 广播 Eddystone UID 数据包,当我使用与扫描仪相同的应用程序使用不同的手机进行测试时,我可以看到第一个设备广播的 Eddystone UID 数据包。

我想编写一个示例应用程序来扫描 Eddystone UID 数据包。 我知道我必须使用BluetoothLeScannerScanCallbackonScanResult,我可以获得所有与BLE(蓝牙低功耗)兼容的蓝牙设备。

但问题是我能够从ScanResult 提取设备mac、设备名称,并且可以验证我能够听到我的蓝牙耳机和扬声器,但我不确定我将如何获得namespace 和@ Eddystone UID 的 987654326@,我无法在 ScanResult 中看到任何此类变量,这将对我有所帮助。

谁能指点我任何sn-p或任何关于如何做到这一点的代码。我不想使用任何第三方库进行扫描,在 Kotlin 或 java 中很简单。 Kotlin 是首选,但 java 也很好,我知道这两种语言。

【问题讨论】:

    标签: java android kotlin bluetooth-lowenergy


    【解决方案1】:

    Eddystone UID:具有 10 字节命名空间组件和 6 字节实例组件的唯一静态 ID。 在onScanResult 中,您可以提取 Eddystone uid 数据包,如下所示

    override fun onScanResult(callbackType: Int, result: ScanResult) {
                val scanRecord = result.scanRecord
                if (scanRecord != null) {
                    val serviceUuids = scanRecord.serviceUuids
                    if (serviceUuids != null && serviceUuids.size > 0 && serviceUuids.contains(
                            eddystoneServiceId
                        )
                    ) {
                        val serviceData = scanRecord.getServiceData(eddystoneServiceId)
                        if (serviceData != null && serviceData.size > 18) {
                            val eddystoneUUID =
                                Utils.toHexString(Arrays.copyOfRange(serviceData, 2, 18))
                            val namespace = String(eddystoneUUID.toCharArray().sliceArray(0..19))
                            val instance = String(
                                eddystoneUUID.toCharArray()
                                    .sliceArray(20 until eddystoneUUID.toCharArray().size)
                            )
    
                            Log.e("DINKAR", "Namespace:$namespace Instance:$instance")
                        }
                    }
                   
                }
            }
    

    scanRecord:广告和扫描响应的组合

    serviceUuids:广告中用于识别蓝牙 GATT 服务的服务 UUID 列表。

    eddystoneServiceId:Eddystone UID 的服务 UUID,即“0000FEAA-0000–1000–8000–00805F9B34FB”

    serviceData:与 serviceUuid 关联的服务数据字节数组,在我们的例子中是 eddystoneServiceId

    eddystoneUID 数据包信息在 serviceData 中从索引 2 到 18,我们需要使用实用方法将此字节数组转换为 Hex 字符串。

    命名空间为 10 个字节,以 eddystoneUID 的 20 个字符开头

    instanceId为6个字节,即eddystoneUID的剩余12个字符

    向您展示如何将字节数组转换为十六进制字符串的示例

       private val HEX = "0123456789ABCDEF".toCharArray()
    fun toHexString(bytes: ByteArray): String {
        if (bytes.isEmpty()) {
            return ""
        }
        val hexChars = CharArray(bytes.size * 2)
        for (j in bytes.indices) {
            val v = (bytes[j].toInt() and 0xFF)
            hexChars[j * 2] = HEX[v ushr 4]
            hexChars[j * 2 + 1] = HEX[v and 0x0F]
        }
        return String(hexChars)
    }
    

    我写了一篇关于解析Eddystone UID和iBeacon的博客,你可以参考一下here

    另外,您可以参考完整的工作示例应用程序来扫描 Eddystone UID、iBeacon 和普通蓝牙外围设备here

    【讨论】:

    • 试用了您的示例应用程序,它的运行就像黄油一样顺滑,非常感谢老兄。我可以使用您的回购中的整个代码并根据我的需要进行调整,还是涉及一些许可内容?
    • 很高兴能帮到你。
    • 没有许可证完全没问题,你可以使用我的仓库中的所有代码。
    • 如果我对你有任何帮助,请你接受这个答案并投票,它会有所帮助。
    • 当然,为什么不,让我为你做。
    猜你喜欢
    • 2022-07-07
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多