On sometime, BluetoothDevice.getName() return null. How can i fix it? remoteDeviceName maybe null in following code. And i need distinguish my device and other devices by 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);
});
I was trying to display name of my RN4020 Bluetooth module and faced the same issue. Found the problem in Microchip's forum:
I had set the device name to 9 characters. Setting the name to 4 bytes fixed the issue.
If you recognize the UUID's of your custom services so you know its your device you can also connect to the device and read its name (if its longer than 6 bytes in my case). This was also suggested in Microchips forum.
http://www.microchip.com/forums/m846328.aspx
Finally, i found out the solution:
1.For device connected:
Read device name from gatt characteristic org.bluetooth.characteristic.gap.device_name of service org.bluetooth.service.generic_access.
2.For device no connected:
BluetoothDevice.getName()
may returnnull
if the name could not be determined. This could be due to any number of factors. Regardless, the name is the friendly name of the device, and shouldn't be used to distinguish it from other devices. Instead, use the hardware address throughgetAddress()
.On Marshmallow, utilize
ScanRecord.getDeviceName()
to retrieve the local name embedded in the scan record.BluetoothDevice.getName()
is unreliable if the local name is included in a scan response, rather than in the immediate advertising packet.I know this is old but this more spec-oriented answer may help answer some cases.
In Bluetooth Low Energy, advertisement and scan-response data is only required to have the Bluetooth Address. Advertisement data is how a client BTLE endpoint discovers a service device. A client can request a scan response and get more data. The device name is optional in this data. However, the BTLE spec requires that all Bluetooth Low Energy endpoints support the Generic Access service which is required to support the Device Name characteristic. Unfortunately, to read that characteristic the Android must first connect and do service discovery. If the advertisement/scan response does not provide the information, I do not believe Android connects to the device to get the name. At least I have never seen any indication of connecting without the app specifically requesting a connection. This is not what you want to be required to do if you want to make a decision to connect.
Fortunately, most BTLE devices I have worked with do provide their name in the advertisement or scan response.
Another possibility is that the device may place the name in the scan response part of the advertisement. Depending upon how one has set up Android's BTLE scanner, one might get only the advertisement data and not the scan response. In this case the name will not be found if the device puts it in the scan response. The default scanner settings, however, are such that a scan response must be received before the scan data is passed up to the app.
I've found that if you query for the device's name immediately after it's picked up at scanning it may return null. To get around this I poll a runnable every second or so on the UI thread a maximum of 3 times (So 3 seconds), and the name is usually resolved by then.
Note, in the snippet provided, the enclosing class implements
Runnable
, hence why I can passthis
intoView.postDelayed(Runnable action, long delayMillis)