微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何解析 Eddystone UID BLE 信标信息

如何解决如何解析 Eddystone UID BLE 信标信息

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

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

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

任何人都可以向我指出有关如何执行此操作的任何片段或任何代码。我不想使用任何第三方库进行扫描,在 Kotlin 或 Java 中简单明了。 Kotlin 是首选,但 java 也不错,我知道这两种语言。

解决方法

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,我们需要使用实用方法将此字节数组转换为十六进制字符串。

namespace 是 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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。