蓝牙设备作为一种短距离无线连接的载体,由于其体积小、操作方便等优点,在耳机、车载和电脑键鼠等应用方面被越来越多的消费者所青睐,渐渐走入大众视野中。

作为蓝牙设备的使用者,我们的第一想法往往是这个蓝牙设备的名字是什么,这样才知道去连接哪个蓝牙设备,而一个蓝牙名字又对应着全球唯一的蓝牙地址,这其实才是蓝牙设备的关键。本篇文章我们就来聊聊蓝牙名字和地址的这些事。

蓝牙名字:蓝牙设备的名称,代表这个蓝牙设备,类似于我们的姓名

蓝牙地址:一组由48位(6字节)二进制表示的数据,是蓝牙设备的唯一标识。每一个蓝牙设备的地址都是不一致的(就好比世上没有两片相同的落叶 ),类似于我们的基因。

所以市面上众多的蓝牙设备尽管名字是有可能相同的,但蓝牙地址基本上是不一致的。但也有另外,因为从上图可以知道LAP部分虽然有24位二进制来进行分配,但如果这家厂商的设备数量太多,超过了2的24次方(哈哈,概率极小 ),就会出现蓝牙地址重复的现象。

现在我们大概了解了蓝牙Name和Address的关系,那在安卓源码中我们一般是如何获取这两个值的呢?这就随我接着往下分析。

获取这两个值需要分情况来讨论,因为蓝牙设备首次开机和重启开机的获取流程有差异,所以接下来分别作出说明。

1、首次开机(fastboot刷机完成后首次开机)

这种情况下,应用获取到蓝牙名字和地址一般是从蓝牙协议栈bluedroid获取来的,详情可以参照如下时序图来分析:

从上图可以明显得知,底层bluedroid上报的蓝牙名字和地址最终都会存储于全局变量Settings的xml文件中,文件路径:/data/system/users/0/settings_secure.xml,索引名分别为bluetooth_name和bluetooth_address。

第三方应用通过蓝牙适配器BluetoothAdapter对外提供的接口getName()和getAddress()就可以获取到存储于BluetoothManagerService中的蓝牙名字和地址。

但是这里还有如下几个问题需要解决:

问题1:首次开机,上述时序图中BluetoothManagerService.handleOnBootPhase()的处理中为什么是打开蓝牙的操作而不是主动去获取蓝牙的Name和Address ?

解答:系统开机会根据关机前的蓝牙状态来决定开机后是否自动打开蓝牙。

那重新刷机后的首次开机会根据配置文件的值来决定是否默认打开蓝牙。

配置文件路径:frameworks/base/packages/SettingsProvider/res/values/defaults.xml

该文件中的name="def_bluetooth_on"的值会在刷机后的首次开机创建安卓数据库时写入Setting中的settings_global.xml文件中,索引值为name=“bluetooth_on”。

执行写入数据的处理函数为:frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java中的

loadBooleanSetting(stmt,Settings.Global.BLUETOOTH_ON,R.bool.def_bluetooth_on)。

其他情况下的系统重启后,根据settings_global.xml文件中存储的关机前的蓝牙状态来做处理。

因此刷完系统首次开机后,程序会根据配置文件中的默认值来决定是否打开蓝牙,如果默认不打开蓝牙,则程序也会主动读取Name和Address,这个操作其实是bind蓝牙服务及初始化底层的蓝牙模块,等获取到这两个值后再执行unbind蓝牙服务的动作。

问题2:蓝牙名字的原始定义在哪?

解答:上面时序图中获取到的蓝牙名字也只是从蓝牙协议栈的内存里获取到的值,那这个值是从哪儿来的呢?

分析协议栈的代码,有这几个地方可以获取到Name

步骤A:cfg2prop()->btif_config_get_str()查找/data/misc/bluedroid/bt_config.conf文件中[Adapter]是否包含Name,该文件是协议栈初始化时创建的,保存相关变量

步骤B:如果步骤A没有获取到Name,则从btif_dm_get_adapter_property()->btif_get_default_local_name()中获取到宏定义的变量BTM_DEF_LOCAL_NAME的值作为蓝牙名字,该宏定义的路径为:device\generic\common\bluetooth\bdroid_buildcfg.h

所以获取蓝牙名字的流程图大概如下所示:

问题3:蓝牙地址从哪儿获取的?

解答:类似于蓝牙名字是从协议栈相关的配置文件中获取的,蓝牙地址则是从蓝牙芯片获取上来的。

btif_storage_get_adapter_property()中通过接口controller接口获取地址值controller_get_interface()->get_address()。

而controller.c中的address赋值于:

HCI交互为:

第三方应用需要获取蓝牙地址的话,该应用除了“LOCAL_MAC_ADDRESS”的权限外,还需具备系统权限,否则获取到的地址为默认的错误值:“02:00:00:00:00:00”

2、重启开机

从以上分析可以知道,系统重启前会将蓝牙状态、名字和地址等参数存储于Setting的xml文件中,所以系统重启后,会首先从这些xml文件中读取参数,进而BluetoothManagerService在初始化时就已经获取了这些参数值。

现在我们已经分析完成了两种场景下的蓝牙名字和地址的获取流程,至此安卓系统中的蓝牙Name和Adress就会一直存储于Settings的xml文件中。

使用蓝牙设备过程中,蓝牙地址一经固件写入基本上是不可更改的。但蓝牙名字却是可以修改的,第三方应用使用BluetoothAdapter对外提供的接口setName()将新名字写入蓝牙协议栈,存储于bt_config.conf中,这样保证后续主动读取名字时先读取出更改后的名字。同时协议栈也会将最新的Name上报给服务层,通过广播通知BluetoothManagerService更改Settings中的Name值。

蓝牙设备名字和地址ID如何设置相关推荐

  1. 华为服务器系统激活id怎么更改,服务器id怎么设置

    服务器id怎么设置 内容精选 换一换 VPC终端节点支持将云服务或者用户私有服务配置为可被终端节点访问的终端节点服务.终端节点服务包括"网关"和"接口"两种类型 ...

  2. UNP总结 Chapter 11 名字与地址转换

    本章讲述在名字和数值地址间进行转换的函数:gethostbyname和gethostbyaddr在主机名字与IP地址间进行转换,getservbyname和getservbyport在服务器名字和端口 ...

  3. 小程序中,iOS设备获取蓝牙设备的Mac地址

    遇到的问题 在使用蓝牙的过程中,我们需要获取蓝牙设备的Mac地址.在Android设备上,onBluetoothDeviceFound方法中,deviceId是蓝牙设备的Mac地址.而在 iOS设备上 ...

  4. UNP Chapter 9 - 基本名字与地址转换

    9.1. 概述 本章讲述在名字和数值地址间进行转换的函数:gethostbyname和gethostbyaddr在主机名字与IP地址间进行转换,getservbyname和getservbyport在 ...

  5. mac 更换默认蓝牙适配器_聊一聊蓝牙名字和地址的来龙去脉

    蓝牙名字和地址 蓝牙设备作为一种短距离无线连接的载体,由于其体积小.操作方便等优点,在耳机.车载和电脑键鼠等应用方面被越来越多的消费者所青睐,渐渐走入大众视野中. 作为蓝牙设备的使用者,我们的第一想法 ...

  6. (域名、主机名、服务名、端口号)名字与地址的转换 (gethostbyname、getservbyname、getaddrinfo、getnameinfo等)

    转载地址 本章讲述在名字和数值地址间进行转换的函数:gethostbyname和gethostbyaddr在主机名字与IP地址间进行转换,getservbyname和getservbyport在服务器 ...

  7. 网络编程学习——名字与地址转换(一)

    2019独角兽企业重金招聘Python工程师标准>>> 1 域名系统 域名系统(Domain Name System,DNS)主要用于主机名字与IP地址之间的映射.主机名既可以是一个 ...

  8. 名字与地址转换getservbyname 与 getservbyport函数

    名字与地址转换getservbyname 与 getservbyport函数 服务也通常靠名字来标志,getservbyname函数用于根据给定名字查找相应服务. #include struct    ...

  9. 了解IP地址及如何设置IP地址

    众所周知,在电话通讯中,电话用户是靠电话号码来识别的.同样,在网络中为了区别不同的计算机,也需要给计算机指定一个号码,这个号码就是"IP地址". 什么是IP地址 所谓IP地址就是给 ...

最新文章

  1. 算法的sound和complete
  2. Mybatis 3 返回布尔值,需要注意的地方
  3. 使用VS插件在VS2012/2013上编辑和调试Quick-Cocos2d-x的Lua代码
  4. 统计学---数据的标准化
  5. Vue 用户管理后台思维导图
  6. 【job】2013年5-5阿里巴巴暑期实习招聘笔试题目及部分答案
  7. app engine_App Engine中的Google Services身份验证,第2部分
  8. 深度学习在计算机视觉点云中的发展与未来
  9. Tengine(Nginx)动静分离简要配置
  10. CDN(Content Delivery Network)
  11. 通过设置proxyTable实现调用接口跨域
  12. Matplotlib简介和pyplot的简单使用——subplot
  13. java微信web支付开发_java实现微信H5支付方法详解
  14. (精)广东工业大学 2018实时大数据分析——A-Priori算法实验报告
  15. linux服务器下进入BIOS,一种8路服务器Linux操作系统下刷新BIOS的方法与流程
  16. Postgis使用工具raster2pgsql批量导入栅格数据(一)
  17. 用MATLAB写斐波那契数列
  18. 计算方法(三)平方根法及其改进解线性方程组
  19. C语言枚举类 口袋中有红、黄、蓝、白、黑5种颜色的球若干个
  20. 机械键盘知识漫谈(一)- 初级篇

热门文章

  1. 看起来为空的字符串,长度却是1?
  2. Hystrix之四种触发fallback情况
  3. 【达梦数据库的console工具进行备份恢复遇到报错:bakres连接DMAP失败】
  4. (co-,contra-,in-)variance in Scala, what is [+-A]
  5. 自用vscode安装及配置
  6. 车载TBOX嵌入式设备软件的功能测试
  7. 【转】用天文方法计算二十四节气(上)
  8. Navicat可视化界面导入SQL文件生成数据库表
  9. photoshop是中文版怎么改成英文版!!
  10. 亲爱的,你是吃屎了么