首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >android BluetoothDevice.getName()返回null

android BluetoothDevice.getName()返回null
EN

Stack Overflow用户
提问于 2014-10-10 09:39:18
回答 4查看 22.9K关注 0票数 13

在某些时候,BluetoothDevice.getName()返回null。我怎么才能修复它?remoteDeviceName在以下代码中可能为空。而且我需要通过remoteDeviceName来区分我的设备和其他设备。

代码语言:javascript
复制
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);
            });
EN

回答 4

Stack Overflow用户

发布于 2014-10-14 21:09:39

最后,我找到了解决方案:

1.对于已连接的设备:

从服务org.bluetooth.service.generic_access的gatt特征org.bluetooth.characteristic.gap.device_name读取设备名称。

2.对于未连接的设备:

代码语言:javascript
复制
    /**
     * 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;
        }
    }
票数 15
EN

Stack Overflow用户

发布于 2018-06-28 07:38:14

我知道这是旧的,但这个更面向规范的答案可能有助于回答某些情况。

在蓝牙低能耗中,广告和扫描响应数据只需要具有蓝牙地址。通告数据是客户端BTLE端点发现服务设备的方式。客户端可以请求扫描响应并获取更多数据。在此数据中,设备名称是可选的。然而,BTLE规范要求所有蓝牙低能耗端点都支持通用接入服务,这是支持设备名称特征所必需的。不幸的是,要读取这一特征,Android必须首先连接并进行服务发现。如果广告/扫描响应没有提供信息,我认为Android不会连接到设备来获取名称。至少我从来没有看到任何连接的迹象,而不是应用程序专门请求连接。如果您想要进行连接,这不是您希望被要求执行的操作。

幸运的是,我使用过的大多数BTLE设备都会在广告或扫描响应中提供自己的名称。

另一种可能性是设备可以将名称放置在广告的扫描响应部分中。根据人们如何设置Android的BTLE扫描仪,人们可能只获得广告数据,而不是扫描响应。在这种情况下,如果设备将其放入扫描响应中,则将找不到该名称。然而,默认的扫描仪设置是,在将扫描数据向上传递到应用程序之前,必须接收扫描响应。

票数 4
EN

Stack Overflow用户

发布于 2016-10-06 05:55:33

在棉花糖上,利用ScanRecord.getDeviceName()检索嵌入在扫描记录中的本地名称。

如果本地名称包含在扫描响应中而不是即时通告数据包中,则BluetoothDevice.getName()是不可靠的。

代码语言:javascript
复制
    @Override
    public void onScanResult(int callbackType, ScanResult scanResult) {
        super.onScanResult(callbackType, scanResult);

        // Retrieve device name via ScanRecord.
        String deviceName = scanResult.getScanRecord().getDeviceName();
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26290640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档