背景

个人开发过一种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. Javascript我学之三函数的参数

    本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘 函数的参数             对于参数值,JavaScript不会进行类型检查,任何类型的值都可以被传递给参数.             ...

  2. Java List根据对象的某个属性合并list

    package com.test; import java.util.ArrayList; import java.util.List; public class FileTest { public ...

  3. pandas合并merge-【老鱼学pandas】

    本节讲述对于两个数据集按照相同列的值进行合并. 首先定义原始数据: import pandas as pd import numpy as np data0 = pd.DataFrame({'key' ...

  4. bool值的底层应用场景

    这里我们的if 或者while,还有and,or,not 等都是在内部调用一个对象的bool方法,然后返回True或者是False, a = [0, ] # a = [] # print(bool(a ...

  5. 2019-2-20C#开发中常用加密解密方法解析

    C#开发中常用加密解密方法解析 一.MD5加密算法 我想这是大家都常听过的算法,可能也用的比较多.那么什么是MD5算法呢?MD5全称是 message-digest algorithm 5[|ˈmes ...

  6. [jzoj]4216.【NOIP2015模拟9.12】平方和

    Link https://jzoj.net/senior/#main/show/4216 Description 给出一个N个整数构成的序列,有M次操作,每次操作有一下三种: ①Insert Y X, ...

  7. 对Spring 的RestTemplate进行包装

    Spring的RestTemplate及大地简化了REST Client的开发,但每次还要编写大量的模板代码,代码不够简洁.我对他进行了一次包装,采用接口来声明REST接口,使用Annotation对 ...

  8. h5 canvas与SVG的比较

    画布 什么是canvas? HTML5的canvas标签使用JavaScript可以在网页上绘制图像,画布为一个矩形. 画布本身没有绘制能力,只能通过脚本来绘制. 画布例子: <canvas i ...

  9. maven入门概念及使用

    Maven 一.Maven概念 1.maven是什么:Maven 是一个项目管理工具.它负责管理项目开发过程中的几乎所有的东西. 版本.构建.输出物管理.依赖关系.文档和构建结果.项目关系.移植性管理 ...

  10. Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.

    运行代码时,一直报错: 经过查询后才知道,vue模板只能有一个跟对象 我是这样写的 最后修改为 就可以正常运行了