我在Nexus 4上在Android 4.3上新推出的BLE API上使用startLeScan( new UUID[]{ MY_DESIRED_128_BIT_SERVICE_UUID }, callback )时遇到问题。
回调不会被调用。我仍然可以在日志中看到传入的包:
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)
如果我不使用该参数来过滤UUID,它可以正常工作。我们正在为我们公司的设备使用制造商特定的128位UUID 。
现在,我们的设备提供的服务比我在阵列中提供的服务更多。但那应该不是问题。
有人面临同样的问题吗?任何解决方案?
修改
有几个与扫描相关的问题,此问题仅讨论一个问题:如果您在扫描时遇到一些问题,请先阅读this comment。还要记住,我的设备强加了16位和128位UUID。大多数人都使用BLE标准提供的16位UUID,如Heart rate或Speed and Cadence。
答案 0 :(得分:38)
@Navin的代码很好,但它包含原始16位Android代码的溢出错误。 (如果任一字节大于127,则它变为负整数。)
这是一个修复错误和添加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;
}
答案 1 :(得分:21)
尝试此操作从广告的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;
}
答案 2 :(得分:10)
至少在Android 4.3 JWR66Y中这是reported bug:
我的设置:我的设备在广告(1 16bit and 1 128bit)上提供2个UUID,在服务发现时提供4个UUID(1 128位和3 16位)。
即使它已修复,我也警告大家不要使用Android提供的过滤器选项。为了向后兼容,因为它在使用Android 4.3的三星Galaxy S3上被打破
答案 3 :(得分:5)
虽然4.3似乎不支持128位UUID的过滤,但这些UUID可能存在于LeScanCallback返回的byte [] scanRecord中。
可能有一种正确的方法来解析这些数据,但如果您每次都可以通过查找要查找的UUID的偏移量来手动过滤结果,那么您将获得相同的数据。您可以通过将扫描数据打印到日志(作为十六进制字符串)并查找您感兴趣的UUID(它们可能会遵循0x06或0x07并将被反转)来完成此操作。一旦找到偏移量,设置基本过滤器就不会太难了。
这是一个简单的示例,按单个UUID进行过滤(对{Array}}使用Apache Commons Lang,找到here的字节到十六进制的方法,但您可以在必要时替换自己的代码)
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;
}
}
答案 4 :(得分:1)
您确定外设是否在广告数据或扫描响应数据中列出指定的服务UUID?
答案 5 :(得分:1)
从扫描结果中列出服务UUID的最佳方法是从 ScanRecord.java 中精确复制 parseFromBytes 方法,该方法位于 android内.bluetooth.le 包(确保您拥有最新的Android SDK),将返回更改为 ParcelUuid 的列表,因为它是唯一的我们关心的事情
private static final int DATA_TYPE_FLAGS = 0x01;
private static final int DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL = 0x02;
private static final int DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE = 0x03;
private static final int DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL = 0x04;
private static final int DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE = 0x05;
private static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL = 0x06;
private static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE = 0x07;
private static final int DATA_TYPE_LOCAL_NAME_SHORT = 0x08;
private static final int DATA_TYPE_LOCAL_NAME_COMPLETE = 0x09;
private static final int DATA_TYPE_TX_POWER_LEVEL = 0x0A;
private static final int DATA_TYPE_SERVICE_DATA = 0x16;
private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
public static List<ParcelUuid> parseFromBytes(byte[] scanRecord) {
if (scanRecord == null) {
return null;
}
int currentPos = 0;
int advertiseFlag = -1;
List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
String localName = null;
int txPowerLevel = Integer.MIN_VALUE;
SparseArray<byte[]> manufacturerData = new SparseArray<byte[]>();
Map<ParcelUuid, byte[]> serviceData = new HashMap<ParcelUuid, byte[]>();
try {
while (currentPos < scanRecord.length) {
// length is unsigned int.
int length = scanRecord[currentPos++] & 0xFF;
if (length == 0) {
break;
}
// Note the length includes the length of the field type itself.
int dataLength = length - 1;
// fieldType is unsigned int.
int fieldType = scanRecord[currentPos++] & 0xFF;
switch (fieldType) {
case DATA_TYPE_FLAGS:
advertiseFlag = scanRecord[currentPos] & 0xFF;
break;
case DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL:
case DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE:
parseServiceUuid(scanRecord, currentPos,
dataLength, 2, serviceUuids);
break;
case DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL:
case DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE:
parseServiceUuid(scanRecord, currentPos, dataLength,
BluetoothUuid.UUID_BYTES_32_BIT, serviceUuids);
break;
case DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL:
case DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE:
parseServiceUuid(scanRecord, currentPos, dataLength,
BluetoothUuid.UUID_BYTES_128_BIT, serviceUuids);
break;
case DATA_TYPE_LOCAL_NAME_SHORT:
case DATA_TYPE_LOCAL_NAME_COMPLETE:
localName = new String(
extractBytes(scanRecord, currentPos, dataLength));
break;
case DATA_TYPE_TX_POWER_LEVEL:
txPowerLevel = scanRecord[currentPos];
break;
case DATA_TYPE_SERVICE_DATA:
// The first two bytes of the service data are service data UUID in little
// endian. The rest bytes are service data.
int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
serviceUuidLength);
ParcelUuid serviceDataUuid = BluetoothUuid.parseUuidFrom(
serviceDataUuidBytes);
byte[] serviceDataArray = extractBytes(scanRecord,
currentPos + serviceUuidLength, dataLength - serviceUuidLength);
serviceData.put(serviceDataUuid, serviceDataArray);
break;
case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
// The first two bytes of the manufacturer specific data are
// manufacturer ids in little endian.
int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) +
(scanRecord[currentPos] & 0xFF);
byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2,
dataLength - 2);
manufacturerData.put(manufacturerId, manufacturerDataBytes);
break;
default:
// Just ignore, we don't handle such data type.
break;
}
currentPos += dataLength;
}
if (serviceUuids.isEmpty()) {
serviceUuids = null;
}
// Log.i("SERVICE UUIDS", parcelUuidToString(serviceUuids));
} catch (Exception e) {
Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
// As the record is invalid, ignore all the parsed results for this packet
// and return an empty record with raw scanRecord bytes in results
}
return serviceUuids;
}
您还需要从同一个软件包中导入 BluetoothUuid.java :
import java.util.UUID;
import android.os.ParcelUuid;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.HashSet;
/**
* Static helper methods and constants to decode the ParcelUuid of remote devices.
* @hide
*/
public final class BluetoothUuid {
/* See Bluetooth Assigned Numbers document - SDP section, to get the values of UUIDs
* for the various services.
*
* The following 128 bit values are calculated as:
* uuid * 2^96 + BASE_UUID
*/
public static final ParcelUuid AudioSink =
ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid AudioSource =
ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid AdvAudioDist =
ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid HSP =
ParcelUuid.fromString("00001108-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid HSP_AG =
ParcelUuid.fromString("00001112-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid Handsfree =
ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid Handsfree_AG =
ParcelUuid.fromString("0000111F-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid AvrcpController =
ParcelUuid.fromString("0000110E-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid AvrcpTarget =
ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid ObexObjectPush =
ParcelUuid.fromString("00001105-0000-1000-8000-00805f9b34fb");
public static final ParcelUuid Hid =
ParcelUuid.fromString("00001124-0000-1000-8000-00805f9b34fb");
public static final ParcelUuid Hogp =
ParcelUuid.fromString("00001812-0000-1000-8000-00805f9b34fb");
public static final ParcelUuid PANU =
ParcelUuid.fromString("00001115-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid NAP =
ParcelUuid.fromString("00001116-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid BNEP =
ParcelUuid.fromString("0000000f-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid PBAP_PCE =
ParcelUuid.fromString("0000112e-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid PBAP_PSE =
ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid MAP =
ParcelUuid.fromString("00001134-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid MNS =
ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid MAS =
ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid SAP =
ParcelUuid.fromString("0000112D-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid BASE_UUID =
ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
/** Length of bytes for 16 bit UUID */
public static final int UUID_BYTES_16_BIT = 2;
/** Length of bytes for 32 bit UUID */
public static final int UUID_BYTES_32_BIT = 4;
/** Length of bytes for 128 bit UUID */
public static final int UUID_BYTES_128_BIT = 16;
public static final ParcelUuid[] RESERVED_UUIDS = {
AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
ObexObjectPush, PANU, NAP, MAP, MNS, MAS, SAP};
public static boolean isAudioSource(ParcelUuid uuid) {
return uuid.equals(AudioSource);
}
public static boolean isAudioSink(ParcelUuid uuid) {
return uuid.equals(AudioSink);
}
public static boolean isAdvAudioDist(ParcelUuid uuid) {
return uuid.equals(AdvAudioDist);
}
public static boolean isHandsfree(ParcelUuid uuid) {
return uuid.equals(Handsfree);
}
public static boolean isHeadset(ParcelUuid uuid) {
return uuid.equals(HSP);
}
public static boolean isAvrcpController(ParcelUuid uuid) {
return uuid.equals(AvrcpController);
}
public static boolean isAvrcpTarget(ParcelUuid uuid) {
return uuid.equals(AvrcpTarget);
}
public static boolean isInputDevice(ParcelUuid uuid) {
return uuid.equals(Hid);
}
public static boolean isPanu(ParcelUuid uuid) {
return uuid.equals(PANU);
}
public static boolean isNap(ParcelUuid uuid) {
return uuid.equals(NAP);
}
public static boolean isBnep(ParcelUuid uuid) {
return uuid.equals(BNEP);
}
public static boolean isMap(ParcelUuid uuid) {
return uuid.equals(MAP);
}
public static boolean isMns(ParcelUuid uuid) {
return uuid.equals(MNS);
}
public static boolean isMas(ParcelUuid uuid) {
return uuid.equals(MAS);
}
public static boolean isSap(ParcelUuid uuid) {
return uuid.equals(SAP);
}
/**
* Returns true if ParcelUuid is present in uuidArray
*
* @param uuidArray - Array of ParcelUuids
* @param uuid
*/
public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) {
if ((uuidArray == null || uuidArray.length == 0) && uuid == null)
return true;
if (uuidArray == null)
return false;
for (ParcelUuid element: uuidArray) {
if (element.equals(uuid)) return true;
}
return false;
}
/**
* Returns true if there any common ParcelUuids in uuidA and uuidB.
*
* @param uuidA - List of ParcelUuids
* @param uuidB - List of ParcelUuids
*
*/
public static boolean containsAnyUuid(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
if (uuidA == null && uuidB == null) return true;
if (uuidA == null) {
return uuidB.length == 0 ? true : false;
}
if (uuidB == null) {
return uuidA.length == 0 ? true : false;
}
HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
for (ParcelUuid uuid: uuidB) {
if (uuidSet.contains(uuid)) return true;
}
return false;
}
/**
* Returns true if all the ParcelUuids in ParcelUuidB are present in
* ParcelUuidA
*
* @param uuidA - Array of ParcelUuidsA
* @param uuidB - Array of ParcelUuidsB
*
*/
public static boolean containsAllUuids(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
if (uuidA == null && uuidB == null) return true;
if (uuidA == null) {
return uuidB.length == 0 ? true : false;
}
if (uuidB == null) return true;
HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
for (ParcelUuid uuid: uuidB) {
if (!uuidSet.contains(uuid)) return false;
}
return true;
}
/**
* Extract the Service Identifier or the actual uuid from the Parcel Uuid.
* For example, if 0000110B-0000-1000-8000-00805F9B34FB is the parcel Uuid,
* this function will return 110B
* @param parcelUuid
* @return the service identifier.
*/
public static int getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid) {
UUID uuid = parcelUuid.getUuid();
long value = (uuid.getMostSignificantBits() & 0x0000FFFF00000000L) >>> 32;
return (int)value;
}
/**
* Parse UUID from bytes. The {@code uuidBytes} can represent a 16-bit, 32-bit or 128-bit UUID,
* but the returned UUID is always in 128-bit format.
* Note UUID is little endian in Bluetooth.
*
* @param uuidBytes Byte representation of uuid.
* @return {@link ParcelUuid} parsed from bytes.
* @throws IllegalArgumentException If the {@code uuidBytes} cannot be parsed.
*/
public static ParcelUuid parseUuidFrom(byte[] uuidBytes) {
if (uuidBytes == null) {
throw new IllegalArgumentException("uuidBytes cannot be null");
}
int length = uuidBytes.length;
if (length != UUID_BYTES_16_BIT && length != UUID_BYTES_32_BIT &&
length != UUID_BYTES_128_BIT) {
throw new IllegalArgumentException("uuidBytes length invalid - " + length);
}
// Construct a 128 bit UUID.
if (length == UUID_BYTES_128_BIT) {
ByteBuffer buf = ByteBuffer.wrap(uuidBytes).order(ByteOrder.LITTLE_ENDIAN);
long msb = buf.getLong(8);
long lsb = buf.getLong(0);
return new ParcelUuid(new UUID(msb, lsb));
}
// For 16 bit and 32 bit UUID we need to convert them to 128 bit value.
// 128_bit_value = uuid * 2^96 + BASE_UUID
long shortUuid;
if (length == UUID_BYTES_16_BIT) {
shortUuid = uuidBytes[0] & 0xFF;
shortUuid += (uuidBytes[1] & 0xFF) << 8;
} else {
shortUuid = uuidBytes[0] & 0xFF ;
shortUuid += (uuidBytes[1] & 0xFF) << 8;
shortUuid += (uuidBytes[2] & 0xFF) << 16;
shortUuid += (uuidBytes[3] & 0xFF) << 24;
}
long msb = BASE_UUID.getUuid().getMostSignificantBits() + (shortUuid << 32);
long lsb = BASE_UUID.getUuid().getLeastSignificantBits();
return new ParcelUuid(new UUID(msb, lsb));
}
/**
* Parse UUID to bytes. The returned value is shortest representation, a 16-bit, 32-bit or 128-bit UUID,
* Note returned value is little endian (Bluetooth).
*
* @param uuid uuid to parse.
* @return shortest representation of {@code uuid} as bytes.
* @throws IllegalArgumentException If the {@code uuid} is null.
*/
public static byte[] uuidToBytes(ParcelUuid uuid) {
if (uuid == null) {
throw new IllegalArgumentException("uuid cannot be null");
}
if (is16BitUuid(uuid)) {
byte[] uuidBytes = new byte[UUID_BYTES_16_BIT];
int uuidVal = getServiceIdentifierFromParcelUuid(uuid);
uuidBytes[0] = (byte)(uuidVal & 0xFF);
uuidBytes[1] = (byte)((uuidVal & 0xFF00) >> 8);
return uuidBytes;
}
if (is32BitUuid(uuid)) {
byte[] uuidBytes = new byte[UUID_BYTES_32_BIT];
int uuidVal = getServiceIdentifierFromParcelUuid(uuid);
uuidBytes[0] = (byte)(uuidVal & 0xFF);
uuidBytes[1] = (byte)((uuidVal & 0xFF00) >> 8);
uuidBytes[2] = (byte)((uuidVal & 0xFF0000) >> 16);
uuidBytes[3] = (byte)((uuidVal & 0xFF000000) >> 24);
return uuidBytes;
}
// Construct a 128 bit UUID.
long msb = uuid.getUuid().getMostSignificantBits();
long lsb = uuid.getUuid().getLeastSignificantBits();
byte[] uuidBytes = new byte[UUID_BYTES_128_BIT];
ByteBuffer buf = ByteBuffer.wrap(uuidBytes).order(ByteOrder.LITTLE_ENDIAN);
buf.putLong(8, msb);
buf.putLong(0, lsb);
return uuidBytes;
}
/**
* Check whether the given parcelUuid can be converted to 16 bit bluetooth uuid.
*
* @param parcelUuid
* @return true if the parcelUuid can be converted to 16 bit uuid, false otherwise.
*/
public static boolean is16BitUuid(ParcelUuid parcelUuid) {
UUID uuid = parcelUuid.getUuid();
if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
return false;
}
return ((uuid.getMostSignificantBits() & 0xFFFF0000FFFFFFFFL) == 0x1000L);
}
/**
* Check whether the given parcelUuid can be converted to 32 bit bluetooth uuid.
*
* @param parcelUuid
* @return true if the parcelUuid can be converted to 32 bit uuid, false otherwise.
*/
public static boolean is32BitUuid(ParcelUuid parcelUuid) {
UUID uuid = parcelUuid.getUuid();
if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
return false;
}
if (is16BitUuid(parcelUuid)) {
return false;
}
return ((uuid.getMostSignificantBits() & 0xFFFFFFFFL) == 0x1000L);
}
从我的测试中,结果完全符合我的要求。
答案 6 :(得分:0)
您需要在广告数据中添加服务UUID作为link
然后你可以再试一次startLeScan(UUID [],回调)。
我通过这种方法成功发现了具有特定UUID [0x1809]
的温度计设备它对我有用。
答案 7 :(得分:0)
我的经验是,我必须提供我想要连接的设备提供的每项服务,而不仅仅是我关注的设备。我最终在扫描后进行服务发现以解决这个问题。
答案 8 :(得分:0)
128位UUID LE扫描适用于三星S5,运行Android 4.4.2;但是它在Nexus 4,7上失败了。测试了4.4.2,4.4.3,4.4.4。
答案 9 :(得分:0)
我在Android源5.x中发现了一个错误,但在6.x中没有。
此文件中有一个函数: http://androidxref.com/5.1.1_r6/xref/external/bluetooth/bluedroid/bta/dm/bta_dm_api.c#1560 用于将32位data_mask传递给蓝牙广告和扫描响应堆栈。 但结构&#34; tBTA_DM_API_SET_ADV_CONFIG;&#34;管理16位长的价值!!! 因此,将UINT16更改为UINT32 dor data_mask,重新编译Android,它将起作用。 里夫 http://androidxref.com/5.1.1_r6/xref/external/bluetooth/bluedroid/bta/dm/bta_dm_int.h#594
答案 10 :(得分:-2)
我使用我的N7 2013和Android 4.3与TI的SensorTag遇到了同样的问题。
我发现工作原理是启动LeScan,等待一秒钟,然后重新启动它。
if(!mBluetoothAdapter.startLeScan(mBleScanCallback)){
L.e("could not start scan action");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
mBluetoothAdapter.stopLeScan(mBleScanCallback);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
mBluetoothAdapter.startLeScan(mBleScanCallback);
此外,我注意到有时连接未建立(这可能与固件实现有关,也可能与固定实现无关)。以同样的方式,似乎试图重新连接到gatt似乎可以解决问题。
必须使用这些解决方法真的很令人失望......