背景

个人开发过一种BLE设备有这样一种需求:当设备处于状态A时,广播设备名称A;处于状态B时,广播设备名称B。

问题

我们发现,当Android在进行Ble扫描的时候,扫描回调函数onScanResult中获取的设备名称并未随设备实时改变。

但是当使用nrfConnect进行扫描时,却发现设备广播名称确实是实时改变的。

原因

我们使用如下代码获取BLE设备名称,然而此时device.getName()中的名称是系统缓存的数据,而非实时的广播数据,要想获取实时的设备名称,必须自行解码实时广播数据。

    private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) { BluetoothDevice device = result.getDevice();
if(null != device && null != device.getName()) {
Log.d("test", device.getName()); // not the real name
}
} @Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
} };

解决

通过分析BLE广播包协议,自行解码出设备名称。

      private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) { BluetoothDevice device = result.getDevice();
if(null != device && null != device.getScanRecord().getBytes()) {
byte[] scanRecord = device.getScanRecord().getBytes(); // advertised data
String realName = parseDeviceName(scanRecord);
}
} @Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
} };
     // return name String(successful) or null(failed)
public static String parseDeviceName(byte[] scanRecord) {
String ret = null;
if(null == scanRecord) {
return ret;
} ByteBuffer buffer = ByteBuffer.wrap(scanRecord).order(ByteOrder.LITTLE_ENDIAN);
while (buffer.remaining() > 2) {
byte length = buffer.get();
if (length == 0)
break; byte type = buffer.get();
length -= 1;
switch (type) {
case 0x01: // Flags
buffer.get(); // flags
length--;
break;
case 0x02: // Partial list of 16-bit UUIDs
case 0x03: // Complete list of 16-bit UUIDs
case 0x14: // List of 16-bit Service Solicitation UUIDs
while (length >= 2) {
buffer.getShort();
length -= 2;
}
break;
case 0x04: // Partial list of 32 bit service UUIDs
case 0x05: // Complete list of 32 bit service UUIDs
while (length >= 4) {
buffer.getInt();
length -= 4;
}
break;
case 0x06: // Partial list of 128-bit UUIDs
case 0x07: // Complete list of 128-bit UUIDs
case 0x15: // List of 128-bit Service Solicitation UUIDs
while (length >= 16) {
long lsb = buffer.getLong();
long msb = buffer.getLong();
length -= 16;
}
break;
case 0x08: // Short local device name
case 0x09: // Complete local device name
byte sb[] = new byte[length];
buffer.get(sb, 0, length);
length = 0;
ret = new String(sb).trim();
return ret;
case (byte) 0xFF: // Manufacturer Specific Data
buffer.getShort();
length -= 2;
break;
default: // skip
break;
}
if (length > 0) {
buffer.position(buffer.position() + length);
}
}
return ret;
}

参考资料:

https://www.race604.com/ble-advertising/

杂记:解决Android扫描BLE设备名称不刷新问题的更多相关文章

  1. 关于samsung连接BLE设备的一些资料汇总和开发过程一些经验总结

    1 忙了这么久,终于有时间把最近几个月弄的东西整理一下,顺便我的开发过程和经历. 被公司分到做一个蓝牙4.0的项目,对这种软硬结合的东西也比较感兴趣,所以很快投入到android蓝牙4.0的项目中来. ...

  2. Android 6.0 扫描不到 Ble 设备需开启位置权限

    Android 6.0 扫描不到 Ble 设备需开启位置权限 之前做 Ble 开发都是在 Android 6.0 系统以下的版本中进行测试的,今天使用 Android 6.0 的设备测试的时候,发现扫 ...

  3. Android BLE设备蓝牙通信框架BluetoothKit

    BluetoothKit是一款功能强大的Android蓝牙通信框架,支持低功耗蓝牙设备的连接通信.蓝牙广播扫描及Beacon解析. 关于该项目的详细文档请关注:https://github.com/d ...

  4. 让BLE设备的名称包含MAC地址

    对于研发和测试BLE来说,经常看到同名的设备,是极为不方便的,一大堆设备同时上电会让同事不知道哪一个设备才是自己真正想操作的目标.再说一下小米手环,家中有三支小米手环,打开设备搜索全是“MI”,都不知 ...

  5. Android蓝牙BLE开发,扫描、连接、发送和读取信息;

    1.BLE开发权限 Android蓝牙BLE开发须打开蓝牙权限和6.0位置权限: <uses-permission android:name="android.permission.B ...

  6. 【转】Android bluetooth介绍(三): 蓝牙扫描(scan)设备分析

    原文网址:http://blog.csdn.net/xubin341719/article/details/38584469 关键词:蓝牙blueZ  A2DP.SINK.sink_connect.s ...

  7. hbuilder在android手机里用chrome调试,只显示了设备名称,却没有inspect按钮

    stark 通过“菜单”->“工具”->“检查设备”打开设备检查页面,只显示了设备名称,却没有inspect按钮,要怎么办 1 赞2014-10-09 22:00 ============ ...

  8. Android bluetooth介绍(三): 蓝牙扫描(scan)设备分析

    关键词:蓝牙blueZ  A2DP.SINK.sink_connect.sink_disconnect.sink_suspend.sink_resume.sink_is_connected.sink_ ...

  9. 如何获得Android设备名称(ADB命令详细介绍)

    豌豆荚.360手机管家等软件可以获取android设备名称,显示在界面上,如下图: 我们自己如何来获取设备名称 呢?答案如下: 在命令行中输入“adb shell”进入shell之后,再输入“cat ...

随机推荐

  1. appium自动化测试等待的三种方法

    第一种  sleep(): 设置固定休眠时间.python 的 time 包提供了休眠方法 sleep() ,导入 time包后就可以使用 sleep()进行脚本的执行过程进行休眠. python # ...

  2. 使用 NPOI 导出 Excel 文件

    [NPOI简介] NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就可以在没有安装 Office 或者 ...

  3. tensorflow结果可视化-【老鱼学tensorflow】

    这次我们把上次的结果进行可视化显示,我们会把神经网络的优化过程以图像的方式展示出来,方便我们了解神经网络是如何进行优化的. 首先,我们把测试数据显示出来: # 显示测试数据 fig = plt.fig ...

  4. CodeForces 528D Fuzzy Search 多项式 FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8782849.html 题目传送门 - CodeForces 528D 题意 给你两个串$A,B(|A|\geq| ...

  5. 网络编程-Mysql-2、各种查询

    1.先创建一个学生表 create table students ( id int auto_increment not null primary key, name varchar(20)  not ...

  6. CodeForces 721C Journey(拓扑排序+DP)

    <题目链接> 题目大意:一个DAG图有n个点,m条边,走过每条边都会花费一定的时间,问你在不超过T时间的条件下,从1到n点最多能够经过几个节点. 解题分析:对这个有向图,我们进行拓扑排序, ...

  7. 基于Anaconda安装tensorflow-GPU和caffe-GPU

    1.创建虚拟环境 我们先创建一个用于caffe和tensorflow共存的虚拟环境,安装完成后激活环境. conda create -n caffe_tf_36 python=3.6 source a ...

  8. KVM嵌套虚拟化nested之CPU透传

    嵌套式虚拟nested是一个可通过内核参数来启用的功能.它能够使一台虚拟机具有物理机CPU特性,支持vmx或者svm(AMD)硬件虚拟化.该特性需要内核升级到Linux 3.X版本 ,所以在cento ...

  9. 学习 Vim —— Vimtutor 总结笔记

    Lesson 2 2.1-2.3 删除 [dw] 删除从光标开始处至下一词开始前的部分,光标停在下一词的词首. [de] 删除从光标开始处至词尾的部分. [d$] 删除从光标开始处至行末的部分. 2. ...

  10. python 的 virtualenv 环境搭建及 sublime 手动创建运行环境

    一.安装 virtual env sudo pip install virtualenv二.进入一个空白的目录初始化 virtual env 的环境cd ~/workspace/python/virt ...