如何解析 Eddystone UID BLE 信标信息
How to parse Eddystone UID BLE beacon info
我正在尝试为 BLE Eddystone UID 数据包编写一个解析器,但不知道具体该怎么做。
我正在使用 Beacon Simulator 应用程序广播 Eddystone UID 数据包,当我使用与扫描仪相同的应用程序使用不同的移动设备进行测试时,我可以看到第一台设备广播的 Eddystone UID 数据包。
我想编写一个示例应用程序来扫描 Eddystone UID 数据包。
我知道我必须使用 BluetoothLeScanner
并且在 ScanCallback
的 onScanResult
中我可以获得所有与 BLE(低功耗蓝牙)兼容的蓝牙设备。
但问题是我能够从 ScanResult
中提取设备 mac、设备名称,并且可以验证我能够听到我的蓝牙耳机和扬声器的声音,但我不确定具体如何我将获得 Eddystone UID 的 namespace
和 instance
,但我无法在 ScanResult
中看到任何此类变量,这对我有帮助。
任何人都可以向我指出有关如何执行此操作的任何片段或代码。我不想使用任何第三方库进行扫描,在 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
serviceData 中索引 2 到 18 处有 eddystoneUID 数据包信息,我们需要使用实用方法将此字节数组转换为十六进制字符串。
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
我正在尝试为 BLE Eddystone UID 数据包编写一个解析器,但不知道具体该怎么做。 我正在使用 Beacon Simulator 应用程序广播 Eddystone UID 数据包,当我使用与扫描仪相同的应用程序使用不同的移动设备进行测试时,我可以看到第一台设备广播的 Eddystone UID 数据包。
我想编写一个示例应用程序来扫描 Eddystone UID 数据包。
我知道我必须使用 BluetoothLeScanner
并且在 ScanCallback
的 onScanResult
中我可以获得所有与 BLE(低功耗蓝牙)兼容的蓝牙设备。
但问题是我能够从 ScanResult
中提取设备 mac、设备名称,并且可以验证我能够听到我的蓝牙耳机和扬声器的声音,但我不确定具体如何我将获得 Eddystone UID 的 namespace
和 instance
,但我无法在 ScanResult
中看到任何此类变量,这对我有帮助。
任何人都可以向我指出有关如何执行此操作的任何片段或代码。我不想使用任何第三方库进行扫描,在 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
serviceData 中索引 2 到 18 处有 eddystoneUID 数据包信息,我们需要使用实用方法将此字节数组转换为十六进制字符串。
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