Android BLE 扫描永远找不到设备

2024-05-16

几天以来,我尝试在我的应用程序中实现 BLE 连接。我知道我尝试连接的设备功能齐全,因此问题一定是我的代码。

我用BluetoothLeScanner.startScan()方法。
但回调方法永远不会被调用。

   public void startScan() {
        if (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
            isScanning = true;
            Handler mHandler = new Handler();
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mainActivityHandler.setMSG("Scan stopped");
                    isScanning = false;
                    leScanner.stopScan(scanCallback);
                }
            }, SCAN_TIME);

            mainActivityHandler.setMSG("Start scan");

            try {

                leScanner.startScan(scanCallback);
            } catch (Exception e) {
                mainActivityHandler.catchError(e);
            }

        } else mainActivityHandler.catchError(new Exception("Bluetooth not activated"));
    }

我的 CallbackMethod (不知道我是否正确使用 gatt,但这是另一个问题):

    private ScanCallback scanCallback = new ScanCallback() {


    @Override
    public void onBatchScanResults(List<ScanResult> results) {
        mainActivityHandler.setMSG("Callback");
        isScanning = false;
        try {

            mainActivityHandler.setMSG("Connected to " + results.get(0).getDevice().getName());
            gatt = results.get(0).getDevice().connectGatt(mainActivity, true, bluetoothGattCallback);

            BluetoothGattDescriptor descriptor;
            for (int i = 0; i < charIDs.length; i++) {
                gatt.setCharacteristicNotification(gatt.getService(serviceID[0]).getCharacteristic(charIDs[i]), true);

                descriptor = gatt.getService(serviceID[0]).getCharacteristic(charIDs[0]).getDescriptor(charIDs[i]);
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                gatt.writeDescriptor(descriptor);
            }
        } catch (Exception e) {
            mainActivityHandler.catchError(e);
        }

    }
};

问题

问题是你只是覆盖了onBatchScanResults方法而不是onScanResult方法。onBatchScanResults仅在以下情况下才会被触发:

  1. 您已经设置了ScanSettings模式为ScanSettings.SCAN_MODE_LOW_POWER(这是默认值)使用ScanSettings.Builder.
  2. 您已使用以下命令将报告延迟时间设置为 >0 的某个值setReportDelay(long reportDelayMillis)在你的ScanSettings.Builder.

报告延迟毫秒 https://developer.android.com/reference/android/bluetooth/le/ScanSettings.Builder.html#setReportDelay(long)- 报告延迟(以毫秒为单位)。设置为 0 可立即通知结果。值 > 0 会导致扫描结果排队并在请求的延迟后或内部缓冲区填满时传送。

例如:

public void startScan(BluetoothLeScanner scanner) {
    ScanFilter filter = new ScanFilter.Builder().setDeviceName(null).build();

    ArrayList<ScanFilter> filters = new ArrayList<ScanFilter>();
                    filters.add(filter);

    ScanSettings settings = new ScanSettings.Builder()
                                .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
                                .setReportDelay(1l)
                                .build();

    Log.i(TAG,"The setting are "+settings.getReportDelayMillis());
    scanner.startScan(filters,settings,BLEScan);
}

解决方案

但是,您可能只想一次获得一次结果,而不是一批结果。要实现这一点,您不必修改 ScanSettings,只需覆盖onScanResult方法在你的ScanCallback这样就可以了。

private ScanCallback mScanCallback =
        new ScanCallback() {

    public void onScanResult(int callbackType, ScanResult result) {
        System.out.println(result.getDevice().getName())
        // Do whatever you want
    };

    ...
};

替代方案 - RxAndroidBle

无论如何,我强烈推荐使用该库RxAndroidBLE https://github.com/Polidea/rxandroidble。它维护得很好,并且解决了许多开箱即用的 BLE 问题(扫描可能是 BLE 中不太复杂的部分)。

使用该库,可以像这样完成扫描:

Disposable scanSubscription = rxBleClient.scanBleDevices(


    new ScanSettings.Builder()
            // .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // change if needed
            // .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) // change if needed
            .build()
        // add filters if needed
)
    .subscribe(
        scanResult -> {
            // Process scan result here.
        },
        throwable -> {
            // Handle an error here.
        }
    );

// When done, just dispose.
scanSubscription.dispose();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android BLE 扫描永远找不到设备 的相关文章

随机推荐

  • 解释这段代码的工作原理;子进程如何返回值以及在哪里返回值?

    我不明白子进程如何返回该值以及返回给谁 输出为 6 7 问题来源 http www cs utexas edu mwalfish classes s11 cs372h hw sol1 html http www cs utexas edu
  • 意外的令牌:尝试解析 JSON 字符串时

    我正在尝试解析这个 JSON 字符串 RESULTS name Thessaloniki GR type Sailing l sailing weather beach Porto 20Carras 20Marina 45904 name
  • 标记(Markdown)+ Mermaid(流程图和图表)

    努力去争取 美人鱼 https github com knsv mermaid https github com knsv mermaid跟 共事 标记 https github com chjj marked https github c
  • 绘制多边形

    我正在使用 Google Maps API V3 根据路径绘制多边形 该路径是随机未排序坐标点 LatLng 的数组 这会产生以下形状 Polylines intersect Problem 由于多边形的形状取决于路径中点的顺序 因此如何对
  • 值和类型的简洁双向静态 1:1 映射

    我将从我想象如何使用我想要创建的代码开始 它不必完全像这样 但它是我在标题中所说的 简洁 的一个很好的例子 就我而言 它是将类型映射到相关的枚举值 struct bar foo
  • Vue-Router 抽象父路由

    我正在尝试将当前网站迁移到 vuejs 站点地图必须是 login signup password reset browse search dozens of other routes 由于其中一些路线共享大量 fx 因此我将它们设为父路线
  • F# 中的数组初始化

    如何根据给定的记录类型在 F 中创建和初始化数组 假设我想创建一个包含 100 个 record1 记录的数组 e g type record1 value1 string value2 string let myArray Array i
  • 将两个数字相加将它们连接起来而不是计算总和

    我将两个数字相加 但没有得到正确的值 例如 做1 2返回 12 而不是 3 我在这段代码中做错了什么 function myFunction var y document getElementById txt1 value var z do
  • 声纳中的代码覆盖率和线路覆盖率有什么区别

    我知道行覆盖率和分支覆盖率有什么区别 但是代码覆盖率和行覆盖率有什么区别 以前的指令覆盖吗 覆盖范围是线路覆盖范围和分支覆盖范围的微妙组合 您可以在我们的网站上找到公式指标描述页面 https docs sonarqube org late
  • 如何让 mini-css-extract-plugin 与 webpack 5 一起使用?

    我正在尝试提取库中的 css 文件 我已经读过执行此操作的方法是使用 mini css extract plugin 难道我做错了什么 还有其他方法可以提取我的库的 css 文件吗 下面我使用提供的相同文件创建了一个简单的测试项目https
  • 高效创建抗锯齿圆形蒙版

    我正在尝试创建抗锯齿 加权而不是布尔 圆形掩模 以制作用于卷积的圆形内核 radius 3 no of pixels to be 1 on either side of the center pixel shall be decimal a
  • 如何使用 javascript 更改文件扩展名

    有谁知道在 Javascript 中更改文件扩展名的简单方法吗 例如 我有一个带有 first docx 的变量 但我需要将其更改为 first html 这将改变字符串包含文件名 let file first docx file file
  • Apache 网络服务器启动时出现错误[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我刚刚切换
  • MYSQL 的 Google OAuth 2.0 用户 ID 数据类型

    我正在实施 Google OAuth 2 0 并注意到 Google OAuth 返回的唯一用户 ID 是21位数字长的 我想大整数 20 足以满足这种需求 但我现在看到 Google OAuth 返回的用户 ID 的长度感到困惑 关于我应
  • 使用 boost 异步发送和接收自定义数据包?

    我正在尝试使用 boost 异步发送和接收自定义数据包 根据我当前的实现 我有一些问题 tcpclient cpp include tcpclient h include
  • 如何使用VBA根据条件删除Excel中的行?

    我目前正在构建一个宏来格式化数据表并删除不适用的数据行 具体来说 我希望删除列 L ABC 的行以及删除列 AA DEF 的行 到目前为止 我已经实现了第一个目标 但还没有实现第二个目标 现有代码是 Dim LastRow As Integ
  • 使用ExternalInterface和IE从JavaScript获取Flash中的当前URL

    我正在尝试获取 Flash 播放器当前所在的 URL 不是 swf 文件的 URL 而是浏览器指向的 URL 到目前为止我已经使用过 var st String ExternalInterface call window location
  • Bash 解析和 shell 扩展

    我对 bash 解析输入和执行扩展的方式感到困惑 对于输入来说 hello world 作为 bash 中的参数传递给显示其输入内容的脚本 我不太确定 Bash 如何解析它 Example var hello world displaywh
  • 地图路由,像谷歌地图一样吗?

    我一直对地图路由很感兴趣 但我从未找到任何好的入门 甚至高级 级别的教程 有人有任何指示 提示等吗 Update 我主要寻找有关如何实现地图系统 数据结构 算法等 的指导 看看开放街道地图项目 http www openstreetmap
  • Android BLE 扫描永远找不到设备

    几天以来 我尝试在我的应用程序中实现 BLE 连接 我知道我尝试连接的设备功能齐全 因此问题一定是我的代码 我用BluetoothLeScanner startScan 方法 但回调方法永远不会被调用 public void startSc