java在android系统中检测设备名称的变化

dba5bblo  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(484)

我们有一个可编程的设备,我们正在工作,通过设备的名称输出数据。该设备运行正常,可以看到使用类似nrf connect的应用程序正确更改名称。然而,我们在自己的android应用程序中也很难做到这一点。我们可以很好地检测到这些设备,但它们几乎永远不会超过最初的名称。
我开始使用的代码有一个循环,该循环在onresume()中启动,该循环使用bluetoothlescanner和startscan()函数进行扫描。

public void BLEScan(final boolean enable){

    final int SCAN_PERIOD = 12000;
    final BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();

    if (enable) {
        Log.d(TAG, "Starting Scan");
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                BLEScan(false);
                invalidateOptionsMenu();
            }
        }, SCAN_PERIOD);

        bluetoothLeScanner.flushPendingScanResults(mLeScanCallback);
        bluetoothLeScanner.startScan(mLeScanCallback);
    } else {
        Log.d(TAG, "Stopping Scan");
        bluetoothLeScanner.flushPendingScanResults(mLeScanCallback);
        bluetoothLeScanner.stopScan(mLeScanCallback);

        mHandler.removeCallbacksAndMessages(null);

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                BLEScan(true);
            }
        }, SCAN_PERIOD);
    }
}

在mlescancallback中检测到基于设备的过滤器。基本上,如果它以前没有见过设备,它会将其添加到信标列表中。但是,如果它以前看到过它,它会使用beacon的seen()函数更新值,并使用beacon的名称seen,因为这是信息的来源。在这两种情况下,它都将更新其适配器以填充新信息。

private ScanCallback mLeScanCallback =
    new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            final ScanResult res2 = result;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    BluetoothDevice device = res2.getDevice();
                    String address = device.getAddress();

                    if (device.getName() != null){
                        if (device.getName().contains("ABT:")){
                            if (!mLeBeacons.containsKey(address)){
                                BleBeacon beacon = new BleBeacon(device.getName(), address);
                                bleList.add(beacon);
                                adapter.notifyDataSetChanged();

                                mLeBeacons.put(device.getAddress(), beacon);
                            } else {
                                for (int x = 0; x < bleList.size(); x++){
                                    if (device.getAddress().equals(bleList.get(x).getMAC())){
                                        bleList.get(x).seen(device.getName());
                                        adapter.notifyDataSetChanged();
                                    }
                                }
                            }
                        }
                    }
                }
            });
        }
    };

但是,即使在更新名称之后,mlescancallback也只会返回原始名称。
在这里搜索了一段时间后,我不断发现的是使用函数fetchuuidswithsdp()和意图,如action\u found、action\u uuid、action\u discovery\u finished和action\u name\u changed,以查看名称的正确更改。所以,我将fetchuuidswithsdp()添加到mlescancallback中。然而,虽然这会触发意图,但名称仍然没有更新。我试着按实际意图调用fetchuuidswithsdp(),但也没有用。奇怪的是,如果我关掉手机屏幕或者离设备足够远的话,改变名字的动作偶尔会触发。但是,onpause()所做的只是调用 super.onPause() 以及 BLEScan(false) . 而且,由于这些都是我在循环中已经在做的事情,所以我不知道如何在代码处于唤醒状态时将其引入代码中。
在进一步搜索之后,我发现,要使用fetchuuidswithsdq()函数,需要使用bluetoothadapter的startdiscovery()函数。所以,我把blescan改成了使用它,完全去掉了mlescan回调。

public void BLEScan(final boolean enable){
    final int SCAN_PERIOD = 12000;
    if (enable) {
        Log.d(TAG, "Starting Scan");
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                BLEScan(false);
                invalidateOptionsMenu();
            }
        }, SCAN_PERIOD);

        if (mBluetoothAdapter.isDiscovering()){
            mBluetoothAdapter.cancelDiscovery();
        }
        mBluetoothAdapter.startDiscovery();
    } else {
        Log.d(TAG, "Stopping Scan");
        mBluetoothAdapter.cancelDiscovery();

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                BLEScan(true);
            }
        }, SCAN_PERIOD);
    }
}

然而,虽然意图在以前被触发,但现在却没有,即使它们在我的意图过滤器中。在做了更多的搜索之后,我发现有人说startdiscovery()不适用于le设备。所以,我搜索了你应该用的东西…这让我一路回到了蓝牙扫描的startscan。在那一刻,我意识到我已经在一个圈子里,需要帮助。
我回顾了我的整个过程,因为,在这个过程中,我遗漏了一些东西。我只是不知道它在哪里。我应该使用startscan()吗?我没有正确使用startdiscovery()吗?或者有什么我应该完全使用的东西吗?事实上,action\u name\u偶尔会被更改,这让我想回到这个问题上,但是如何让它在设备处于唤醒状态时一直工作呢?

ctehm74n

ctehm74n1#

虽然我没有在我的原始代码中发现我做错了什么(尽管听起来android可能只是在这方面被打破了),但我确实找到了一个解决方法。nrf的nfc工具箱有可用的源代码,并通过添加的过滤器进行批量扫描,还有它自己的北欧图书馆的le扫描仪。现在我的扫描功能是这样的:

public void BLEScan(final boolean enable){

        final BluetoothLeScannerCompat bluetoothLeScanner = BluetoothLeScannerCompat.getScanner();
        final ScanSettings settings = new ScanSettings.Builder()
                .setLegacy(false)
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).setReportDelay(1000).setUseHardwareBatchingIfSupported(false).build();
        final List<ScanFilter> filters = new ArrayList<>();
        ParcelUuid Uuid = new ParcelUuid(UUID.fromString(uuidString));
        filters.add(new ScanFilter.Builder().setServiceUuid(Uuid).build());

        if (enable) {
            Log.d(TAG, "Starting Scan");
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    BLEScan(false);
                    invalidateOptionsMenu();
                }
            }, SCAN_PERIOD);

            bluetoothLeScanner.startScan(filters, settings, mLeScanCallback);
        } else {
            BLEService.refreshGatt();
            Log.d(TAG, "Stopping Scan");
            bluetoothLeScanner.stopScan(mLeScanCallback);

            mHandler.removeCallbacksAndMessages(null);

            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    BLEScan(true);
                }
            }, SCAN_PERIOD);
        }
    }

我的回电是这样的:

private no.nordicsemi.android.support.v18.scanner.ScanCallback mLeScanCallback =
            new no.nordicsemi.android.support.v18.scanner.ScanCallback() {
                @Override
                public void onBatchScanResults(@NonNull final List<no.nordicsemi.android.support.v18.scanner.ScanResult> results) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            for (final no.nordicsemi.android.support.v18.scanner.ScanResult result : results){
                                BluetoothDevice device = result.getDevice();

                                if (device != null){
                                    String address = device.getAddress();
                                    String name = result.getScanRecord() != null ? result.getScanRecord().getDeviceName() : null;

                                    if (!mLeBeacons.containsKey(address)) {
                                        BleBeacon beacon = new BleBeacon(device.getName(), address);
                                        bleList.add(beacon);
                                        adapter.notifyDataSetChanged();

                                        mLeBeacons.put(device.getAddress(), beacon);
                                    } else {
                                        for (int x = 0; x < bleList.size(); x++){
                                            if (device.getAddress().equals(bleList.get(x).getMAC())){
                                                bleList.get(x).seen(device.getName());
                                                adapter.notifyDataSetChanged();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    });
                }

这似乎起了作用。不过,您需要将以下内容添加到依赖项中。

implementation 'no.nordicsemi.android.support.v18:scanner:1.4.2'

在那之后,我的名字动作\u名字\u改变意图被正确触发并且数据被更新。
我不确定这是从结果中检索名称的不同方式,还是批量扫描。但是,如果北欧不使用标准的android ble库,我猜这是最好的方法。

k97glaaz

k97glaaz2#

我想你可能只是在android上缓存有问题。请在此处查看此答案以获取可能的解决方案:https://stackoverflow.com/a/50745997/7473793

相关问题