android BluetoothDevice.getName()返回null
有时,BluetoothDevice.getName()返回null。我该如何解决它? remoteDeviceName在下面的代码中可能为null。我需要通过remoteDeviceName区分我的设备和其他设备。android BluetoothDevice.getName()返回null
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);
});
BluetoothDevice.getName()
可能返回null
如果名称无法确定。这可能是由于许多因素造成的。无论如何,名称是友好的设备的名称,不应该用于区分它与其他设备。而应使用通过getAddress()
的硬件地址。
用户无法在我们的无线设备(手表等)中看到蓝牙地址,只知道设备的蓝牙名称。所以,当getName()返回null时,选择确切的设备来连接是个问题。 – maonanyue 2014-10-10 05:56:44
最后,我发现了解决方案:
1.适用于设备连接:从复关
读取设备名称特性服务org.bluetooth.service.generic_access的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;
}
}
如何从gatt特性中获取设备名称?你可以给我任何例子 – 2016-04-20 08:27:05
在棉花糖,利用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();
}
getDeviceName方法不存在ScanRecord类。你能发表一个示例代码吗? – 2017-09-18 14:39:12
@NagendraBadiganti包括示例代码。 – Kevin 2017-09-19 21:48:23
我发现如果您在扫描后立即查询设备名称,它可能会返回null。为了解决这个问题,我在UI线程上每隔一秒左右轮询一次runnable,最多3次(所以3秒),这个名字通常是在那个时候解决的。
注意,在所提供的片段,封闭类实现Runnable
,因此为什么我可以通过this
到View.postDelayed(Runnable action, long delayMillis)
private static final int MAX_NAME_CHECKS = 3;
private static final int NAME_CHECK_PERIOD = 1000;
int nameChecks;
@Override
public void run() {
resolveName();
}
/**
* Checks for the device name, for a maximum of {@link ViewHolder#MAX_NAME_CHECKS}
* as the name may not have been resolved at binding.
*/
private void resolveName() {
if (device != null) {
String name = device.getName();
boolean isEmptyName = TextUtils.isEmpty(name);
if (isEmptyName) deviceName.setText(R.string.unknown_device);
else deviceName.setText(name);
// Check later if device name is resolved
if (nameChecks++ < MAX_NAME_CHECKS && isEmptyName)
itemView.postDelayed(this, NAME_CHECK_PERIOD);
}
}
我试图显示我的RN4020蓝牙模块的名称及所面临的同样的问题。发现问题Microchip的论坛:
如果启用私人服务或MLDP,设备 名的最大字节数是6个字节,由于31字节的有效载荷的广告限制。
我已将设备名称设置为9个字符。将名称设置为4个字节可解决问题。
如果您认识到您的自定义服务的UUID,以便您知道它的设备,则还可以连接到设备并读取其名称(如果其长度超过6个字节)。这也是在微芯片论坛中提出的。
为什么你不做一些空检查? – 2014-10-10 02:37:11
cource,我可以检查它是否为null。但是空名对我来说毫无用处。它不是空的,所以有一些API来刷新设备名称? – maonanyue 2014-10-10 02:41:43