android ble4.0开发及遇到的一些坑

Android蓝牙4.0 BLE开发坑总结 onServicesDiscovered 回调里不能直接执行 write /readDataFromCharacteristic() 或者 enableNotificationOfCharacteristic之类的,而要放到主线程里执行,如 handler.post( … ); 如果发现连接上了,service也discover到了,但是始终不能触发onCharacteristicChanged的, 阅读详情

首先我在这里就不把原生的代码写出来了,如果刚入手的小伙伴可以在我另一篇文章看看https://blog.youkuaiyun.com/ZyClient/article/details/83650100

在此我说几点蓝牙开发中一些注意事项及容易踩坑的地方,希望可以帮助到大家!!!

1.权限问题:在android6.0以后部分权限需要我们动态申请,对于蓝牙这块我们需要申请,首先我们在清单文件配置权限

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

其中位置权限需要我们动态申请

2.搜索-连接:在搜索以及连接这两步中我们要弄清楚是在工作线程还是主线程中操作的,另外我建议搜索的时候根据uuid去搜索,这样可以降低搜索范围,提高效率。因为蓝牙搜索本来就是一个耗时而不是很稳定的操作。

3.开启接收新数据通知:其实这是我今天重点讲解的地方,在以往我们可以通过厂商提供的协议然后找到对应服务以及服务下的特征。

var service: BluetoothGattService? = mBluetoothGatt!!.getService(serviceUuid)
        ?: return
var characteristic: BluetoothGattCharacteristic? = service!!.getCharacteristic(characteristicUuid)
        ?: return
// 开启新数据接收通知
mBluetoothGatt!!.setCharacteristicNotification(characteristic, true)
var descriptors = characteristic!!.descriptors
for (dp in descriptors) {
    //设置特征的属性
    dp.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
    mBluetoothGatt!!.writeDescriptor(dp)
    mBluetoothGatt!!.readDescriptor(dp)
}

当你一套流程走完后,其实差不多可以采集到蓝牙设备数据了。

然而在最近与鱼跃蓝牙设备通讯的时候,搜索-连接这套流程都走成功了,并且也跟上诉一样设置了新数据接收通知,可是始终无法接收蓝牙设备测量数据。我怀疑过是我代码出问题了,可是我一步步调试下来,发现没有发现什么可疑之处。于是乎我就换另外一个厂家的设备进行调试(把相应的uuid跟换下)测试结果是:这厂家的设备可以通讯及采集测量数据。这时候我懵了,我又想是不是设备出现问题了,但是如果设备出现问题为什么搜索-连接都能成功呐?最后我实在找不出哪里出现问题了,我在网上搜索了很久很久,终于找到一个作者提到相识问题了这帖子说的是蓝牙芯片nRF设置setCharacteristicNotification是不能真正打开Notify接收通知的。当我看到这里的时候我以为我能解决问题了,结果后面一句话我又懵了。

不过总归知道问题所在了,我看了下原生的Ble好像并没有其他与打开通知的api,于是我尝试了一个第三方库:FastBleLib按照官方示例写了下,

    var uuids = arrayOf(UUID.fromString("00001810-0000-1000-8000-00805f9b34fb"))
        //初始化
        BleManager.getInstance().init(mActivity!!.application)
        BleManager.getInstance()
            .enableLog(true)
            .setReConnectCount(3, 3000).operateTimeout = 3000

        //是否支持ble
        if (!BleManager.getInstance().isSupportBle) {
            WindowUtils.showToast(mActivity!!, "该设备不支持蓝牙")
            return
        }
        //判断当前蓝牙是否已经打开
        if (!BleManager.getInstance().isBlueEnable) {
            BleManager.getInstance().enableBluetooth()
            Observable.interval(1, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : BaseObserver {
                    override fun onNext(t: Any) {
                        super.onNext(t)
                        startBLE_disposable?.let {
                            if (BleManager.getInstance().isBlueEnable)
                                if (!it.isDisposed) {
                                    it.dispose()
                                    initScan(uuids)
                                }
                        }
                    }

                    override fun onSubscribe(d: Disposable) {
                        super.onSubscribe(d)
                        startBLE_disposable = d
                    }

                })
        } else
            initScan(uuids)


    }

    //配置扫描规则
    private fun initScan(uuid: Array<UUID>) {
        var bsrc = BleScanRuleConfig.Builder()
            .setServiceUuids(uuid)      // 只扫描指定的服务的设备,可选
            .setScanTimeOut(10000)       // 扫描超时时间,可选,默认10秒
            .build()
        BleManager.getInstance().initScanRule(bsrc)
        //开始扫描
        startScan()

    }

    //开始扫描
    private fun startScan() {
        BleManager.getInstance().scan(object : BleScanCallback() {
            override fun onScanFinished(scanResultList: MutableList<BleDevice>?) {
                Log.e("-scan-", "扫描结束")
            }

            override fun onScanStarted(success: Boolean) {
                Log.e("-scan-", "开始扫描")
            }

            override fun onScanning(bleDevice: BleDevice?) {
                devices = bleDevice
                //停止扫描
                BleManager.getInstance().cancelScan()
                //延迟100ms在操作
                Observable.timer(100, TimeUnit.MILLISECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(object : BaseObserver {
                        override fun onNext(t: Any) {
                            //开始连接
                            startConnect()
                        }
                    })

            }
        })

    }

    //开始链接
    private fun startConnect() {
        BleManager.getInstance().connect(devices, object : BleGattCallback() {
            override fun onStartConnect() {
                Log.e("-connect-", "开始连接")

            }

            override fun onDisConnected(
                isActiveDisConnected: Boolean,
                device: BleDevice?,
                gatt: BluetoothGatt?,
                status: Int
            ) {
                BleManager.getInstance().disconnect(device)
                Log.e("-connect-", "连接断开")
//                //延迟100ms在操作
//                Observable.interval(2, 2, TimeUnit.SECONDS)
//                    .take(1)
//                    .subscribeOn(Schedulers.io())
//                    .observeOn(AndroidSchedulers.mainThread())
//                    .subscribe(object : BaseObserver {
//                        override fun onNext(t: Any) {
//                            Log.e("-connect-", "重新连接")
//                            //重新连接
//                            startConnect()
//                        }
//                    })
            }

            override fun onConnectSuccess(bleDevice: BleDevice?, gatt: BluetoothGatt?, status: Int) {
                Log.e("-connect-", "连接成功并发现服务")
                //延迟100ms在操作
                Observable.timer(100, TimeUnit.MILLISECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(object : BaseObserver {
                        override fun onNext(t: Any) {
                            //开启通知
                            Openindicate()
                        }
                    })
            }


            override fun onConnectFail(bleDevice: BleDevice?, exception: BleException?) {
                Log.e("-连接失败-", "${exception.toString()}")


            }

        })

    }

    //开启通知
    private fun Openindicate() {
        BleManager.getInstance().indicate(
            devices,
            "00001810-0000-1000-8000-00805f9b34fb",
            "00002a35-0000-1000-8000-00805f9b34fb",
            object : BleIndicateCallback() {
                override fun onCharacteristicChanged(data: ByteArray?) {
                    val sBuffer = StringBuffer()
                    for (i in data!!.indices) {
                        val s = Integer.toHexString(data[i].toInt() and 0xff)
                        if (s.length < 2)
                            sBuffer.append('0')
                        sBuffer.append("$s ")

                    }
                    Log.e("-result-", sBuffer.toString())
                    zhuan(sBuffer.toString())
                }

                override fun onIndicateSuccess() {
                    Log.e("--MSG--", "打开通知操作成功")
                }

                override fun onIndicateFailure(exception: BleException?) {
                    Log.e("--MSG--", "打开通知操作失败")
                }


            })
    }
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

发现终于接收到通知了,我也不知道原生为什么不行,如果有朋友知道的请告知...

第三方库github地址:https://github.com/Jasonchenlijian/FastBle

Android 蓝牙4.0(BLE)开发实现对蓝牙的写入数据和读取数据 由于最近学校组织了一个移动APP(安卓)设计大赛,自己也学习安卓有一段时间了,就跟同学商量一起去参加试试,一拍即合,然后我们就开始想idea,因为最近可穿戴设备比较火,我们也就想试试。经过商量,我负责Android上位机的开发,同学负责下位机的开发。 上位机的开发主要是低功耗蓝牙BLE的开发,然后就开始找资料,各种找,最后谷歌官方提供的demo还有其他网友基于官方demo修改的demo,结合网上 阅读详情

相关推荐

Android 蓝牙BLE开发详解

Android 蓝牙BLE开发详解 有传输数据 多设备连接 获取uuid等

Charon1997的博客 1万+

Android BLE开发详解和FastBle源码解析

转载自:https://www.jianshu.com/p/795bb0a08beb因为自己的项目中有用到了蓝牙相关的功能,所以之前也断断续续地针对蓝牙通信尤其是BLE通信进行了一番探索,整理出了一个开源框架FastBle与各位分享经验。源码地址:https://github.com/Jasonchenlijian/FastBle随着对FastBle框架关注的人越来越多,与我讨论问题的小伙伴也多起...

嘻哈包袱铺 专栏 6996

BLE蓝牙(4.0)你要懂的基本使用

BLE蓝牙(4.0)你要懂的基本使用 每个人对于蓝牙都不陌生,近距离数据传输,方便;可是当你的业务需求需要你第一次接触蓝牙开发的时候,却会发现你对它并不了解;首先,蓝牙发展至今经历了8个版本的更新。1.1、1.2、2.0、2.1、3.0、4.0、4.1、4.2。那么在1.x~3.0之间的我们称之为传统蓝牙,4.x开始的蓝牙我们称之为低功耗蓝牙也就是蓝牙ble,当然4.x版本的蓝牙也是向下兼容的。...

Lukang_0513的博客 1万+

Android蓝牙BLE开发,向设备发送简单数据

用的是git上的蓝牙管理库,首先添加依赖: implementation'com.clj.fastble:FastBleLib:2.3.4' //蓝牙管理库 implementation 'com.yanzhenjie:permission:2.0.3' //6.0+权限管理 一般给蓝牙发数据是嵌入式开发的哥们写好固定的某个UID,这个UID其实是一对的, 分别是uuid_service,其对应的特征值characteristic uuid 然后我们向这对UID发送数据,上代码: priv

qq137464739的博客 2502

Android BLE4.+ 蓝牙开发国产手机兼容性解决方案

算是做了n年的智能穿戴BLE开发了, 首先对国内的安卓开发者提醒下 , BLE开发是真的很坑, 特别是安卓, ios端也坑, 但没安卓坑 因为国产有很多手机 各种奇葩兼容都有, 其实这些方案我很早就写到云笔记里了,一直没公开, 这里的解决方案大部分都是网上搜不到 或者网上搜到类似的问题, 但回复基本上是回答[无法解决] 或 [重启手机解决]等 没意义的解决办法,让我很无语… 以下内...

没错, 我是东芝 1万+

Android蓝牙开发(二) BLE4.0低功耗蓝牙

一、BLE4.0低功耗蓝牙 Bluetooth Low Energy,蓝牙低功耗,是从蓝牙4.0开始支持的技术。相较传统蓝牙,传输速度更快、覆盖范围广、安全性高、延时短、耗电低等特点。 二、关键术语 1.GATT(通用属性配置):通用属性配置文件,用于ble链路上发送和接收“属性”的数据块。目前所有的ble应用都是基于GATT的,一个设备可以实现多个配置文件。 2.ATT(属性

Near的博客 6205

Android下的BLE编程遇到的一些BUG

BLE的连接过程是搜索→连接→发现服务。

MAGI的专栏 5119

新版ble多连接蓝牙库,解决多个问题,FastBLE-2.4.0

Android蓝牙低能耗 -简单过滤、扫描、链接、阅读、写入、通知订阅和取消。 —支持信号强度采集和最大传输单元设置。 —支持自定义扫描规则 —支持多设备连接 ——支持重新连接

蓝牙框架FastBle原理详解

搞过蓝牙开发的小伙伴都比较清楚,android4.3之后低功耗的蓝牙隐藏着很多坑,比如搜索设备如果频繁的调用startScan方法是会不回调搜索接口的,这是因为蓝牙底层做了优化;比如蓝牙关闭重新搜索搜不到设备或者连接不上设备有可能你没调用BluetoothGatt.close()方法,在蓝牙断开或主动断开的时候你必须调用close方法,因为手机蓝牙可以存在的连接的数量是有限制的,一般是最多存在多少个未回收的BluetoothGatt,不管它是连接状态还是断开未处理状态,反正再重新连接时就连不上了;蓝牙连接的

xiatiandefeiyu的博客 6787

Streamlit安装避坑指南:从零到一键启动你的第一个数据可视化应用

本文提供了一份详尽的Streamlit安装避坑指南,帮助用户从零开始快速启动第一个数据可视化应用。文章深入剖析了安装过程中常见的网络超时、依赖冲突、环境变量缺失等核心问题,并给出了使用虚拟环境、配置国内镜像源、利用.whl文件离线安装等多种经过验证的解决方案,确保安装过程顺畅无阻。

weixin_29065015的博客 615

Qt中常见的面试题总结

基于Qt开发的一些常用面试题

一名热爱编程的程序员 8493

Android——Bluetooth 开发(五)

蓝牙 4.0 蓝牙4.0集成了传统蓝牙和低功耗蓝牙两个标准,所以蓝牙4.0有双模和单模之分。双模即传统蓝牙部分+低功耗蓝牙部分,单模即是单纯的低功耗蓝牙部分(BLE)。 蓝牙操作流程 蓝牙开发之前需要在 AndroidManifest.xml 中申请蓝牙相关权限 &lt;!-- 蓝牙相关权限 --&gt; &lt;uses-permission android:na...

Mr_Four 1431

软件自动化测试脚本如何编写,编写自动化测试脚本的几点注意事项

我们需要自动化测试脚本的原因:1、验收测试是一项非常复杂和费力的被用来确保软件质量的环节。它的目的就是使软件能得到充分运行并且能使其符合原始需求。2、测试的目的无非就是满足了两个结果:测试通过或测试不通过。为了能实现每个测试结果,必须要明确每个测试用例。并且对于整个系统而言在合同中必须定义测试用例的失败标准,而且这个失败标准数必须是可接受的。3、测试用例的通过条件必须有一个清晰的标准,标准可以被定...

weixin_39575775的博客 2251

蓝牙4.0开发

https://blog.csdn.net/roshen_android/article/details/76916111(对BLE系统的介绍,没有之一。)相关资源谷歌官方文档,但是遗憾的是没有写操作。这个我可是研究了好几天,哎。。。https://developer.android.com/guide/topics/connectivity/bluetooth-le....

weixin_34162695的博客 113

Proteus 8.17安装部署全指南:避坑、汉化与STM32库配置

Proteus是一款广泛用于单片机仿真与电路设计的EDA工具,其核心价值在于支持嵌入式系统原型验证与教学实践。Proteus 8.17版本重构了许可证机制(LIC Engine)、依赖环境(VC++ 2019/NET 4.8)及路径加载逻辑,导致传统安装方法失效。掌握正确安装部署流程,是保障原理图绘制、VSM仿真(如51/STM32/ESP32)及外设波形观测(OLED、SPI、ADC)稳定运行的前提。本文聚焦Windows平台下零失败安装路径选择、权限配置、汉化实施与高频器件(如STM32F103)元件库

weixin_33377602的博客 402

从厘米级到公里级:北斗网格10级精度在ArcPro中的完整应用指南

本文提供了北斗网格十级精度体系在ArcGIS Pro中的完整应用指南。详细解析了从660公里到1.5厘米的十级网格尺度及其编码逻辑,并重点演示了如何在ArcPro中生成网格、计算编码,以及根据项目需求(如滑坡监测)选择合适精度层级的实战策略。指南旨在帮助GIS专业人士利用这套统一的网格框架,高效管理多尺度空间数据并优化分析工作流。

Black的专栏 472

Android BLE蓝牙4.0开发详解

这篇博客主要讲解蓝牙 BLE的用法。在讲解之前先讲一些概念性的东西,对于之前没接触过蓝牙开发,现在手上又有个蓝牙BLE项目需要做的人,先看下这些概念还是很重要的。因为我之前就是这样,之前没有接触过蓝牙方面的开发,然后来了个蓝牙的项目,于是就到网上百度了一番,于是有点茫然,产生了几点疑惑: 1:发现蓝牙有传统蓝牙和低功耗蓝牙(ble)之分。那么什么是传...

我的博客 5万+

芯片ATE测试PAT(Part Average Testing)学习总结-20250916

文章摘要:零件平均测试(PAT)是半导体制造中基于统计学的质量控制方法,分为静态和动态两种类型。静态PAT通过预先设定的固定限值(每6-8批次更新)筛选异常芯片,计算采用稳健平均值和四分位间距。动态PAT则根据实时数据调整限值,能更精确识别异常而不误判合格芯片。两种方法均采用"均值±6倍标准差"的计算公式,但动态PAT具有更好的适应性和准确性。该方法通过统计分析提高了芯片产品的质量和可靠性。

歌颂苦难的行为是无耻的; 1191

Android开发之蓝牙(二)——基于BLE协议蓝牙模块通信

介绍 基本概念 Android蓝牙开发流程 app是ble与spp选择连接蓝牙模块,关于spp的可以看 介绍摘要:蓝牙4.0——BLE是近年来应用比较广泛的profile,与传统蓝牙相比,其低功耗的特征最为显著,在蓝牙模块中(CC2540),一块纽扣电池可供电半年到一年之间。

zh1豪的博客 9538

【Go语言实战】(26) 分布式搜索引擎

基于go语言的分布式搜索引擎

面向生活编程 2380

SAP-ABAP:SAP基础数据校验工具开发系列博客(共5篇) 第一篇:需求梳理与架构设计:从零搭建SAP主数据校验能力底座

摘要: 本系列博客介绍SAP主数据校验工具的开发和设计,旨在解决物料、供应商、客户等主数据录入不规范、关联缺失和合规性问题。第一篇聚焦需求梳理与架构设计,提出分层技术架构(展示层、业务逻辑层、数据访问层),支持实时校验和批量校验两种模式,并详细说明规则引擎设计、SAP系统对接方案及权限管控逻辑。后续篇章将深入规则引擎实现、接口对接、结果可视化和性能优化,帮助构建集中式、可配置的主数据校验能力,提升SAP数据质量。

baidu_35680696的博客 330

安卓BLE开发介绍

跟经典蓝牙(BR/EDR)对比,BLE可以实现功更低耗、但带宽更小;例如未建立连接时,BLE 会处于睡眠模式。蓝牙芯片分单模和双模,其中双模是指同时支持BR/EDR和BLE(一般是共享一个天线、芯片在运行时切换模式)。安卓设备上,蓝牙是作为标配功能(OS 4.3及以上是双模芯片),因此潜在用户市场很大。

专注移动开发 1836

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android蓝牙BLE开发

这篇文章是本人这几天对BLE开发基础的大概总结

weixin_51890646的博客 8207

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Android Ble4.0开发

最近在做一个蓝牙的项目,是Blu4.0,Android系统知识 http://blog.csdn.net/hellogv/article/details/6036849 http://blog.csdn.net/hellogv/article/details/6042091

流水不腐小夏 4042

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

上一篇: Flutter Kotlin 到底该如何选择?
下一篇: android studio找不到app moudle和project moudle
ZyClient
博客等级 码龄10年 29粉丝 60原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值