One*_*rld 34 android bluetooth-lowenergy gatt android-4.3-jelly-bean
我在Nexus 4上新推出的Android 4.3 BLE API上使用startLeScan(新UUID [] {MY_DESIRED_128_BIT_SERVICE_UUID},回调)时遇到问题.
回调就是没有被调用.我仍然可以在日志中看到传入的包:
08-02 15:48:57.985: I/bt-hci(1051): btu_ble_process_adv_pkt
08-02 15:48:58.636: I/bt-hci(1051): BLE HCI(id=62) event = 0x02)
Run Code Online (Sandbox Code Playgroud)
如果我不使用该参数来过滤UUID,它可以工作.我们使用制造商特定的128位UUID作为我们公司的设备.
现在,我们的设备提供的服务比我在阵列中提供的服务更多.但那应该不是问题.
有人面临同样的问题吗?有解决方案吗
编辑
有几个与扫描有关的问题,这个问题只讨论一个问题:如果您还有扫描问题,请先阅读此评论.还要记住,我的设备强加了16位和128位UUID.大多数人都使用BLE标准提供的16位UUID,如Heart rate或Speed and Cadence.
Har*_*per 39
@Navin的代码很好,但它包含原始16位Android代码的溢出错误.(如果任一字节大于127,则它变为负整数.)
这是一个修复该bug 并添加128位支持的实现:
private List<UUID> parseUuids(byte[] advertisedData) {
List<UUID> uuids = new ArrayList<UUID>();
ByteBuffer buffer = ByteBuffer.wrap(advertisedData).order(ByteOrder.LITTLE_ENDIAN);
while (buffer.remaining() > 2) {
byte length = buffer.get();
if (length == 0) break;
byte type = buffer.get();
switch (type) {
case 0x02: // Partial list of 16-bit UUIDs
case 0x03: // Complete list of 16-bit UUIDs
while (length >= 2) {
uuids.add(UUID.fromString(String.format(
"%08x-0000-1000-8000-00805f9b34fb", buffer.getShort())));
length -= 2;
}
break;
case 0x06: // Partial list of 128-bit UUIDs
case 0x07: // Complete list of 128-bit UUIDs
while (length >= 16) {
long lsb = buffer.getLong();
long msb = buffer.getLong();
uuids.add(new UUID(msb, lsb));
length -= 16;
}
break;
default:
buffer.position(buffer.position() + length - 1);
break;
}
}
return uuids;
}
Run Code Online (Sandbox Code Playgroud)
小智 22
尝试从广告的128位UUID中检索/过滤设备:
private List<UUID> parseUUIDs(final byte[] advertisedData) {
List<UUID> uuids = new ArrayList<UUID>();
int offset = 0;
while (offset < (advertisedData.length - 2)) {
int len = advertisedData[offset++];
if (len == 0)
break;
int type = advertisedData[offset++];
switch (type) {
case 0x02: // Partial list of 16-bit UUIDs
case 0x03: // Complete list of 16-bit UUIDs
while (len > 1) {
int uuid16 = advertisedData[offset++];
uuid16 += (advertisedData[offset++] << 8);
len -= 2;
uuids.add(UUID.fromString(String.format(
"%08x-0000-1000-8000-00805f9b34fb", uuid16)));
}
break;
case 0x06:// Partial list of 128-bit UUIDs
case 0x07:// Complete list of 128-bit UUIDs
// Loop through the advertised 128-bit UUID's.
while (len >= 16) {
try {
// Wrap the advertised bits and order them.
ByteBuffer buffer = ByteBuffer.wrap(advertisedData,
offset++, 16).order(ByteOrder.LITTLE_ENDIAN);
long mostSignificantBit = buffer.getLong();
long leastSignificantBit = buffer.getLong();
uuids.add(new UUID(leastSignificantBit,
mostSignificantBit));
} catch (IndexOutOfBoundsException e) {
// Defensive programming.
Log.e(LOG_TAG, e.toString());
continue;
} finally {
// Move the offset to read the next uuid.
offset += 15;
len -= 16;
}
}
break;
default:
offset += (len - 1);
break;
}
}
return uuids;
}
Run Code Online (Sandbox Code Playgroud)
One*_*rld 11
这是至少在Android 4.3 JWR66Y中报告的错误:
我的设置:我的设备在广告(1 16位和1 128位)上提供2 个UUID,在服务发现时提供4个UUID(1 128位和3 16位).
即使它得到修复,我也警告所有人不要使用Android提供的过滤器选项.为了向后兼容,因为它在使用Android 4.3的三星Galaxy S3上被破坏了
虽然4.3似乎不支持128位UUID的过滤,但这些UUID可能存在于LeScanCallback返回的byte [] scanRecord中.
可能有一种正确的方法来解析这些数据,但如果您每次都可以通过查找要查找的UUID的偏移量来手动过滤结果,那么您将获得相同的数据.您可以通过将扫描数据打印到日志(作为十六进制字符串)并查找您感兴趣的UUID(它们可能会遵循0x06或0x07并将被反转)来完成此操作.找到偏移量后,设置基本过滤器应该不会太难.
下面是一个简单的示例,它通过单个UUID进行过滤(使用Apache Commons Lang for ArrayUtils和此处的字节到十六进制方法,但您可以在必要时替换自己的代码)
public static boolean hasMyService(byte[] scanRecord) {
// UUID we want to filter by (without hyphens)
final String myServiceID = "0000000000001000800000805F9B34FB";
// The offset in the scan record. In my case the offset was 13; it will probably be different for you
final int serviceOffset = 13;
try{
// Get a 16-byte array of what may or may not be the service we're filtering for
byte[] service = ArrayUtils.subarray(scanRecord, serviceOffset, serviceOffset + 16);
// The bytes are probably in reverse order, so we need to fix that
ArrayUtils.reverse(service);
// Get the hex string
String discoveredServiceID = bytesToHex(service);
// Compare against our service
return myServiceID.equals(discoveredServiceID);
} catch (Exception e){
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
27858 次 |
最近记录: |