从 BLE 设备同步读取多个特征(Android 推荐方法)

2024-05-20

我正在开发一个从 BLE 设备读取数据的 Android 应用程序。我在这里遇到了很多关于如何读取多个特征的解决方案,其中大多数都建议使用队列。

我确实实现了 Queue 方法,并且我的代码中的一切都按预期正常工作。我开始这个帖子的原因是为了找到最好、最有效的解决方案,并消除我对某些 BLE 服务特性如何工作的一些疑虑。

我将以下两个链接作为参考,这帮助我使我的代码正常工作。

来源1:

Android:BLE如何读取多个Characteristic? https://stackoverflow.com/questions/21278993/android-ble-how-to-read-multiple-characteristics

来源2:

Android BLE API:未收到 GATT 通知 https://stackoverflow.com/questions/17910322/android-ble-api-gatt-notification-not-received

我的要求是阅读心率测量 & 电池电量。最初,我尝试将心率和电池特性添加到队列中,然后为每个添加的元素调用读取/设置方法。

主要活动:

private void displayGattServices(List<BluetoothGattService> gattServices) 
{
   // get the required service & characteristics
   ................
   ................  

   // add the characteristics via Queue
   hRM_characteristicReadQueue.add(characteristics);

   // Initiate read/set methods
   read_Characteristic();   
};

private void read_Characteristic()
 {
   bluetoothHDPService.read(hRM_characteristicReadQueue.element());
   bluetoothHDPService.set(hRM_characteristicReadQueue.element(),true);
   hRM_characteristicReadQueue.remove();
};

蓝牙HDP服务:

public void read(BluetoothGattCharacteristic characteristic) 
 {
    if (bluetoothAdapter == null || bluetoothGatt == null) 
    {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    };

    bluetoothGatt.readCharacteristic(characteristic);
};

public void set(BluetoothGattCharacteristic characteristic, boolean enabled) 
{
    if(bluetoothAdapter == null || bluetoothGatt == null) 
    {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    };

    bluetoothGatt.setCharacteristicNotification(characteristic, enabled);

    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_UUID);
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
    bluetoothGatt.writeDescriptor(descriptor);
};

Back at 主要活动:(一旦读取特征BLE回调操作被触发)

我使用广播接收器来读取/设置下一个队列元素。

private final BroadcastReceiver gattUpdateReceiver = new BroadcastReceiver() 
{
    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // TODO Auto-generated method stub
        final String action = intent.getAction();

        if (Service_HeartRateX_HDP.ACTION_GATT_CONNECTED.equals(action)) 
        {
            // Connection with the BLE device successful                
            ................
            ................ 
        } 
        else if (Service_HeartRateX_HDP.ACTION_GATT_DISCONNECTED.equals(action)) 
        {
            // BLE device is disconnected 
            ................
            ................ 
        }
        else if (Service_HeartRateX_HDP.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) 
        {
            displayGattServices(bluetoothHDPService.getSupportedGattServices());
        }
        else if (Service_HeartRateX_HDP.ACTION_DATA_AVAILABLE.equals(action)) 
        {
            Log.i(TAG, "Collecting data");

            // Collecting the incoming data
            displayData(intent.getStringExtra(Service_HeartRateX_HDP.HEART_DATA), 
            intent.getStringExtra(Service_HeartRateX_HDP.BATTERY_DATA));

            if(hRM_characteristicReadQueue.size() > 0)
            {
                read_Characteristic();
            };
        };
    };  
}; 

上面的代码片段仅适用于一种特征(心率) BLE 设备继续发送心率测量数据,而对于其他特征 (电池百分比) BLE设备发送电池百分比数据仅一次。请注意,队列元素的顺序是首先读取/设置心率特征并将其从队列中删除,然后是电池特征。

最初,我认为队列没有按预期工作,并尝试交换队列中的特征顺序,其中电池百分比是第一个要读取/设置和删除的元素,然后是心率特征,以查看问题是否确实与不正确的相关编程。

但事实并非如此,因为 BLE 设备做了与之前相同的事情(继续发送心率测量数据,而电池百分比仅发送一次)。

因此,考虑到上述场景,我得出的结论是,需要每隔一段时间读取/设置电池电量百分比特征,以强制 BLE 设备发送其数据。下面的文章进一步帮助了这一点,其中一名开发人员必须使用计时器线程从 BLE 设备定期获取电池百分比更新。

如何在android中的ble中每5秒更新一次电池电量 https://stackoverflow.com/questions/23076353/how-to-update-the-battery-level-for-every-5seconds-in-ble-in-android

我不愿意在代码中使用计时器线程,因为这会使我已经很复杂的代码变得复杂无穷。然后我添加了以下条件read_Characteristic()方法来克服这个问题。

@ 主要活动

// where hrmBattery_Characteristics is a temporary variable which holds the 
// battery characteristics
if(hRM_characteristicReadQueue.element() != hrmBattery_Characteristics)
{
     hRM_characteristicReadQueue.remove();
};

通过这样做,电池特性永远不会从队列中删除,并且read_Characteristic()方法将通过广播接收器每隔一段时间调用一次(保持同步模式)。目前,这在我的代码中完美运行,但我需要专家的建议来确定这是否正确。

这个问题仅与电池有关还是与其他特性有关?幸运的是,到目前为止我只需要这两个特征的数据(心率测量数据和电池百分比)。

我没有尝试过两个以上的特性,因为我的 BLE 设备只有有限的一组特性,而这是目前其中仅有的两个特性。

这是因为 BLE 设备无法在给定的时间内向 Android 设备发送大数据包吗?原因是,即使上述代码运行良好,也从未出现过同时发送数据(心率和电池百分比)的情况。

如果有人能对此有所启发,我将不胜感激。

提前致谢!


None

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

从 BLE 设备同步读取多个特征(Android 推荐方法) 的相关文章

  • 如何快速自动发送FCM或APNS消息?

    我正在开发一项后端服务 通过 FCM 或 APNS 向移动应用程序发送推送通知 我想创建一个可以在一分钟内运行的自动化测试 并验证服务器是否可以成功发送通知 请注意 我不一定需要检查通知是否已送达 只需检查 FCM 或 APNS 是否已成功
  • Android 30+ 中的视频捕获意图 - 只有所有者才能与待处理项目交互

    我正在尝试在我的应用程序上捕获视频 它可以在 android API 30 以下运行 但不能在 30 以上运行 似乎在 sdk 30 之后 android 不允许完全读取外部存储 作用域存储 我目前遇到这个错误 java lang Ille
  • 找不到 com.google.firebase:firebase-core:9.0.0 [重复]

    这个问题在这里已经有答案了 在遵循有些不一致的指示之后here https firebase google com docs admob android quick start name your project and here http
  • 无法获取log.d或输出Robolectrict + gradle

    有没有人能够将 System out 或 Log d 跟踪从 robolectric 测试输出到 gradle 控制台 我在用Robolectric Gradle 测试插件 https github com robolectric robo
  • 谷歌坐标认证

    当我尝试连接到 Google 坐标时 总是出现异常GoogleAuthException 我拥有 Google 地图协调中心许可证 我确实使用我的包应用程序名称和 SHA1 在 google 控制台中创建了我的客户端 ID 我将权限添加到清
  • 如何在android中获取Camera2 API的当前曝光

    In android hardware Camera旧的 我使用下面的代码获取当前曝光并获取它Camera Camera Parameters param mCamera getParameters currentExposure para
  • Adobe 是否为其 PDF 阅读器提供 Android SDK 或 API? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我希望能够在我们的应用程序内的视图中显示本地 PDF 文件 在 Android 4 03 下的平板电脑上运行 目前 我们将 Adob eR
  • Android 中 Kotlin 协程的正确使用方式

    我正在尝试使用异步更新适配器内的列表 我可以看到有太多的样板 这是使用 Kotlin 协程的正确方法吗 这个可以进一步优化吗 fun loadListOfMediaInAsync async CommonPool try Long runn
  • asp.net web 服务和 Ihttphandler 的区别

    像发出 AJAX 请求 传递一个参数并返回结果这样简单的任务 都可以使用 Web Service 和 IHttpHandler 来完成 那么有什么区别呢 ASP NET Web 服务实际上是一种 HttpHandler 它提供基于 W3C
  • 带有 EditText 和 Spinner 的对话框

    我有一个按钮 单击后会弹出一个对话框 我希望对话框有一个EditText and a Spinner对话框内 我不知道如何设置它的视图 我有一个代码AlertDialog它有效 只是EditText and Spinner我需要将其放入其中
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • 是否有 ADB 命令来检查媒体是否正在播放

    我想使用 ADB 命令检查根植于终端的外部设备中是否正在播放音频 视频 我无法找到任何 ADB 命令 如果有 我尝试过 adb shell dumpsys media player 我想要一个命令来指定视频是否正在运行 您可以使用以下命令查
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • 发布android后更改应用内购买项目的价格

    在 Google Play 上发布后 是否可以更改应用内购买商品的价格 我假设该应用程序也已发布 完整的在线文档位于http developer android com http developer android com也http sup
  • 原色(有时)变得透明

    我正在使用最新的 SDK 版本 API 21 和支持库 21 0 2 进行开发 并且在尝试实施新的材料设计指南时遇到了麻烦 材料设计说我需要有我的primary color and my accent color并将它们应用到我的应用程序上
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 如何根据 gradle 风格设置变量

    我想传递一个变量test我为每种风格设置了不同的值作为 NDK 的定义 但出于某种原因 他总是忽略了最后味道的价值 这是 build gradle apply plugin com android library def test andr
  • Firebase 添加新节点

    如何将这些节点放入用户节点中 并创建另一个节点来存储帖子 我的数据库参考 databaseReference child user getUid setValue userInformations 您需要使用以下代码 databaseRef
  • 将两个文本视图并排放置在布局中

    我有两个文本视图 需要在布局中并排放置 并且必须遵守两条规则 Textview2 始终需要完整显示 如果布局中没有足够的空间 则必须裁剪 Textview1 例子 文本视图1 文本视图2 Teeeeeeeeeeeeeeeeeextview1

随机推荐

  • 消息 203,级别 16,状态 2,不是有效标识符

    我收到以下错误 消息 203 级别 16 状态 2 过程 getQuestion 第 18 行名称 select top 1 from tlb Question inner join tlb options on tlb options q
  • 使用 Visual C++ 在桌面上绘图

    我正在编写一个 opencv 应用程序 使用 Visual Studio VC 控制台应用程序使用激光束进行绘图 我想在桌面上画线 我知道绘图功能在 GDI32 dll 中可用 但对如何将 GDI32 dll 与我的 vc 代码集成感到困惑
  • Android 动画 GIF

    我正在尝试使用 WebView 显示动画 GIF 它在大多数设备上运行良好 但仍有一些设备不支持动画并显示静态 GIF 如何检测设备是否支持 WebView 中的动画 GIF 以便在不支持时显示适当的消息 是的 这似乎是一个常见问题 htt
  • 下划线反跳与参数

    假设我有这个事件处理程序 var mousewheel function e blah 但是 我想消除它 所以我这样做 它按预期工作 var mousewheelDebounced debounce mousewheel 500 docum
  • React-navigation、tintColor 在 props 验证中丢失

    我已将反应导航代码放入单独的 Routes 文件中 然后将其导入到 App js 文件中 一切工作正常 但我在 Atom Nuclide 中使用 Airbnb ESLint 配置 并收到了 TintColor 错误 道具验证中缺少tintC
  • 如何除以两个原生 JavaScript BigInt 并获得小数结果

    这是我到目前为止所尝试过的 我正在寻找一个12 34 BigInt 12340000000000000000 BigInt 1000000000000000000 12n Number BigInt 12340000000000000000
  • 合并张量流数据集批次

    请考虑下面的代码 import tensorflow as tf import numpy as np simple features np array 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 simple labels
  • 我正在尝试寻找“调酒师算法”

    我正在解决旧编程竞赛中的一些示例问题 在这个问题中 我们输入了我们有多少调酒师以及他们知道哪种配方 每杯鸡尾酒的制作时间为 1 分钟 我们需要计算是否可以在 5 分钟内使用所有调酒师完成订单 解决这个问题的关键是尽可能高效地分配鸡尾酒 这就
  • R:单纯形错误:在下标赋值中不允许使用 NA

    对于以下具有目标函数和约束的最小化 boot simplex返回错误 Error in tab pr lt tab pr tab pr pc pv o tab pr NAs are not allowed in subscripted as
  • 将文件从一个 Team Foundation 项目移动到另一个 Team Foundation 项目

    我们的项目已经达到了需要将一些代码拆分到一个单独的团队基础项目中的地步 我们希望移动这些文件 以便它们保留其版本控制历史记录 我们暂时将文件复制回原始团队基础项目并重新添加它们 以便我们的日常构建和测试过程不会中断 由于我们能够修改构建和测
  • 如何在sklearn管道中通过特征消除选择特征名称?

    我在 sklearn 管道中使用递归特征消除 管道看起来像这样 from sklearn pipeline import FeatureUnion Pipeline from sklearn import feature selection
  • 在 d3.js 中操纵鼠标悬停在“点击区域”

    我想show and hideSVG 中的一个节点 当鼠标移到 mouseout 问题是我的节点内部的形状是一条宽度只有1 5px的路径 因此在鼠标悬停事件中不容易击中该区域 这对用户体验肯定不方便 我想知道是否有办法做到这一点打击范围更广
  • 如何隐藏 Windows Mobile 6.5 中的小键盘弹出窗口? (C#)

    我有一个应用程序 本质上是一个通过一些对话框的向导 其中一个表单上只有一个按钮 可以打开常见的 拍照 对话框 关闭图片功能后 会出现小键盘图标 不方便地覆盖我的向导按钮之一 我尝试通过调用将覆盖的窗口设置到前面 nextButton Bri
  • 如何向 SQL 连接字符串添加自定义属性?

    我想在 SqlServer 连接字符串中添加一些自定义属性 如下所示 Integrated Security SSPI Extended Properties SomeAttr SomeValue Persist Security Info
  • SQL Server 2005 是否有与 MySql 的 ENUM 数据类型等效的数据类型?

    我正在开发一个项目 我想在表中存储一些容易枚举的信息 MySql 的枚举数据类型正是我想要的 http dev mysql com doc refman 5 0 en enum html http dev mysql com doc ref
  • 使用正则表达式模式查找 -name 并使用 cp 替换文件名

    目前我正在使用该命令cron复制 data从源到目标路径 find source path name data exec cp target path 源码结构为 source path category1 001 data source
  • Android 2.1 的 Camera.Parameters.FLASH_MODE_TORCH 替换

    我正在尝试编写一个需要 LED 闪光灯进入手电筒模式的应用程序 问题是 Android 2 1不支持这种模式 因此我还不能支持该平台 这不是问题 但我正在为我的未婚夫编写它 而她的 Epic 4G 目前只有 2 1 我发现一些代码示例使用了
  • R - 基于列名称的子集

    我的数据框有超过 120 列 变量 我想根据列名称创建子集 例如 我想创建一个子集 其中列名称包含字符串 心情 这可能吗 我一般用 SubData lt myData grep whatIWant colnames myData 我很清楚
  • WPF - 位图效果上的编程绑定

    我希望能够以编程方式将一些数据绑定到 a 上的依赖属性位图效果 对于像 TextBlock 这样的 FrameworkElement 有一个 SetBinding 方法 您可以通过编程方式执行这些绑定 例如 myTextBlock SetB
  • 从 BLE 设备同步读取多个特征(Android 推荐方法)

    我正在开发一个从 BLE 设备读取数据的 Android 应用程序 我在这里遇到了很多关于如何读取多个特征的解决方案 其中大多数都建议使用队列 我确实实现了 Queue 方法 并且我的代码中的一切都按预期正常工作 我开始这个帖子的原因是为了