在某些时候,BluetoothDevice.getName()返回null。我怎么才能修复它?remoteDeviceName在以下代码中可能为空。而且我需要通过remoteDeviceName来区分我的设备和其他设备。
BluetoothAdapter.getDefaultAdapter().startLeScan(new LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi,
byte[] scanRecord) {
String remoteDeviceName = device.getName();
Log.d("Scanning", "scan device " + remoteDeviceName);
});
发布于 2014-10-14 21:09:39
最后,我找到了解决方案:
1.对于已连接的设备:
从服务org.bluetooth.service.generic_access的gatt特征org.bluetooth.characteristic.gap.device_name读取设备名称。
2.对于未连接的设备:
/**
* Get device name from ble advertised data
*/
private LeScanCallback mScanCb = new LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi,
byte[] scanRecord) {
final BleAdvertisedData badata = BleUtil.parseAdertisedData(scanRecord);
String deviceName = device.getName();
if( deviceName == null ){
deviceName = badata.getName();
}
}
////////////////////// Helper Classes: BleUtil and BleAdvertisedData ///////////////
final public class BleUtil {
private final static String TAG=BleUtil.class.getSimpleName();
public static BleAdvertisedData parseAdertisedData(byte[] advertisedData) {
List<UUID> uuids = new ArrayList<UUID>();
String name = null;
if( advertisedData == null ){
return new BleAdvertisedData(uuids, name);
}
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;
case 0x09:
byte[] nameBytes = new byte[length-1];
buffer.get(nameBytes);
try {
name = new String(nameBytes, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
break;
default:
buffer.position(buffer.position() + length - 1);
break;
}
}
return new BleAdvertisedData(uuids, name);
}
}
public class BleAdvertisedData {
private List<UUID> mUuids;
private String mName;
public BleAdvertisedData(List<UUID> uuids, String name){
mUuids = uuids;
mName = name;
}
public List<UUID> getUuids(){
return mUuids;
}
public String getName(){
return mName;
}
}
发布于 2018-06-28 07:38:14
我知道这是旧的,但这个更面向规范的答案可能有助于回答某些情况。
在蓝牙低能耗中,广告和扫描响应数据只需要具有蓝牙地址。通告数据是客户端BTLE端点发现服务设备的方式。客户端可以请求扫描响应并获取更多数据。在此数据中,设备名称是可选的。然而,BTLE规范要求所有蓝牙低能耗端点都支持通用接入服务,这是支持设备名称特征所必需的。不幸的是,要读取这一特征,Android必须首先连接并进行服务发现。如果广告/扫描响应没有提供信息,我认为Android不会连接到设备来获取名称。至少我从来没有看到任何连接的迹象,而不是应用程序专门请求连接。如果您想要进行连接,这不是您希望被要求执行的操作。
幸运的是,我使用过的大多数BTLE设备都会在广告或扫描响应中提供自己的名称。
另一种可能性是设备可以将名称放置在广告的扫描响应部分中。根据人们如何设置Android的BTLE扫描仪,人们可能只获得广告数据,而不是扫描响应。在这种情况下,如果设备将其放入扫描响应中,则将找不到该名称。然而,默认的扫描仪设置是,在将扫描数据向上传递到应用程序之前,必须接收扫描响应。
发布于 2016-10-06 05:55:33
在棉花糖上,利用ScanRecord.getDeviceName()
检索嵌入在扫描记录中的本地名称。
如果本地名称包含在扫描响应中而不是即时通告数据包中,则BluetoothDevice.getName()
是不可靠的。
@Override
public void onScanResult(int callbackType, ScanResult scanResult) {
super.onScanResult(callbackType, scanResult);
// Retrieve device name via ScanRecord.
String deviceName = scanResult.getScanRecord().getDeviceName();
}
https://stackoverflow.com/questions/26290640
复制相似问题