ANDROID的 BLUETOOTH 实现机制--中介模式和代理模式 .
转自:http://blog.csdn.net/GooHong/article/details/8005925
从ANDROID3.0开始BLUETOOTH API提供了对Bluetooth profile协议的支持。目前ANDROID4.0 API提供了五种蓝牙无线接口规范(Bluetooth profile)的支持,用来在设备之间提供蓝牙通讯实现特定功能:包括 Headset和Hands-Freeprofile(实现蓝牙耳机功能),A2dpprofile(第二代蓝牙声音设备协议,用来在蓝牙设备之间实现高质量的声音传输),InputDeviceprofile(实现蓝牙输入设备功能),Bluetooth Panprofile(实现蓝牙个人局域网功能),Bluetooth Healthprofile(实现蓝牙健康设备规范,用来与支持蓝牙健康设备规范的设备进行蓝牙通讯)。另外还有Bluetooth Pbapprofile(实现蓝牙电话本功能),但接口和其它profile实现不一致。
ANDROID对 Bluetooth profile API的实现主要采用了中介模式、代理模式及状态模式等。
应用通过一个统一的类BluetoothAdapter(蓝牙本地适配器类)与这些蓝牙设备协议对应的BLUETOOTH API进行交互。
BluetoothAdapter也是所有蓝牙对象交互的入口。通过BluetoothAdapter除了实现BLUETOOTHprofile API的调用外,还提供发现其它蓝牙设备、查询配对成功的设备、使用已知的MAC地址实例化蓝牙设备、创建一个BluetoothServerSocket对象来监听其它蓝牙设备以及根据地质实例化蓝牙设备等功能。因此几乎所有的蓝牙对象和所有的蓝牙服务都维护一个BluetoothAdapter单例对象,BluetoothAdapter单例对象通过BluetoothAdapter类提供的getDefaultAdapter函数获得。BluetoothAdapter对象可以说是整个系统交互的中介,是中介设计模式的采用。
而几个蓝牙设备协议的实现借助几个ANDROID服务来实现,并通过代理对象对外提供BLUETOOTH API。Headset对应的代理对象为BluetoothHeadset,A2dp对应的代理对象为BluetoothA2dp,InputDeviceprofile对应的代理对象为BluetoothInputDevice,Bluetooth Pan对应的代理对象为BluetoothPan,Bluetooth Health对应的代理对象为BluetoothHealth。
通过BluetoothAdapter类提供的getProfileProxy函数根据不同的profile参数实例化对应的代理对象,getProfileProxy函数还传给代理对象一个实现BluetoothProfile.ServiceListener接口的监听对象。
代理对象实例化时与代理的服务进行绑定,与服务进行绑定成功后调用对应监听对象的onServiceConnected回调函数,并通过回调函数把代理对象传给应用,应用通过代理对象通过BINDER访问蓝牙设备服务。
Headset 对应蓝牙服务为BluetoothHeadsetService及BluetoothHandsfree对象,A2dpprofile对应的蓝牙服务为BluetoothA2dpService,而InputDeviceprofile、Bluetooth Healthprofile及Bluetooth Panprofile都由BluetoothService服务来实现。Bluetooth Pbap profile对应的服务是BluetoothPbapService。
BluetoothAdapter对象相关类图如下:
图中几个蓝牙服务BluetoothHeadsetService、BluetoothA2dpService、BluetoothService、BluetoothPbapService及BluetoothDeviceProfileState、BluetoothHandsfree、BluetoothEventLoop对象都维护一个BluetoothAdapter对象(使用BluetoothAdapter类提供的getDefaultAdapter函数获得),并通过BluetoothAdapter对象提供的getProfileProxy函数根据profile类型获得要访问的代理对象,还通过BluetoothAdapter对象访问其它蓝牙对象。
图中几个代理对象都是BluetoothProfile接口的实现,并都维护一个ServiceListener监听对象。BluetoothHeadset对象通过IBluetoothHeadset对BluetoothHeadsetService服务进行BINDER调用,BluetoothA2dp对象通过IBluetoothA2dp对BluetoothA2dpService服务进行BINDER调用,而BluetoothInputDevice、BluetoothPan、BluetoothHealth对象通过IBluetooth调用BluetoothService的API。
代理对象本身及BluetoothAudioGateway对象也可以通过BluetoothAdapter对象访问其它蓝牙对象来获得蓝牙设备信息和状态。
BluetoothAdapter对象提供的接口除了getProfileProxy外主要有以下几个:
getRemoteDevice() 获得远端设备,返回一个BluetoothDevice对象;
getBondedDevices() 获得已配对设备,返回绑定(配对)到本地蓝牙的BluetoothDevice对象集合;
getState() 获得本地蓝牙的当前状态,包括STATE_ON、STATE_OFF、STATE_TURNING_ON、STATE_TURNING_OFF四种状态,由BluetoothAdapterStateMachine状态机进行维护
isEnabled() 返回当前蓝牙是否可用状态,和getState()==STATE_ON对应。
enable() 打开本地蓝牙
disable() 关闭本地蓝牙
getUuids() 返回本地蓝牙支持的UUIDs数组
isDiscovering() 本地蓝牙当前正处于蓝牙设备发现过程
cancelDiscovery() 取消当前蓝牙设备发现过程
另外还提供创建RfcommSocket监听通道的API。
BluetoothAdapter对象通过六个API来创建RfcommSocket数据连接监听通道(三个使用固定端口三个使用随机端口)及一个SCO监听通道(面向连接方式,主要用于话音传输)。三个创建使用固定端口的监听通道API:一个用来创建需要认证和加密的使用固定socket端口的API(需要BLUETOOTH_ADMIN权限许可);一个用来创建不加密不认证的透明固定端口的RFCOMMSocket API;一个用来创建加密不认证的固定端口的RFCOMMSocket API。三个创建使用随机端口的监听RfcommSocket通道API(一个创建加密认证通道、一个创建透明通道、一个创建加密无认证通道),随机端口的产生由BluetoothAdapter的内部对象RfcommChannelPicker负责产生。
对于蓝牙服务端,可以调用BluetoothAdapter对象的这些API来创建一个BluetoothServerSocket对象,初始化一个服务端RfcommSocket监听通道,并调用BluetoothServerSocket对象的accept函数接收对方连接(实际调用刚实例化的监听RfcommSocket的accept函数)。当成功与对方建立连接后,BluetoothServerSocket对象的accept函数返回一个新RfcommSocket通道,用来作为设备之间的数据传输的通讯通道。
每个RfcommSocket通道对应一个BluetoothSocket对象。BluetoothServerSocket对象实例化时根据BluetoothServerSocket实例化函数传进来的通道socket类型、是否需要认证对方设备、连接是否加密、远端socket端口等参数来实例化一个BluetoothSocket对象,socket端口参数为空时使用产生的随机端口。实例化BluetoothSocket对象时使用的socket端口值为1到30之间的数,但10、11、12、19四个保留端口留给其它Profile使用。
在BluetoothSocket对象的实例化函数中还实例化了一个BluetoothInputStream对象和BluetoothOutputStream对象,用作交换数据使用。
BluetoothSocket对象还可以由蓝牙客户端设备来实例化,即由BluetoothDevice对象来实例化。每个BluetoothDevice对象对应一个远端蓝牙设备。BluetoothDevice对象使用BluetoothSocket对象向蓝牙服务端请求连接。通过BluetoothSocket对象还可以查询远端蓝牙设备的信息如设备名、MAC地址、绑定状态、蓝牙类型等。
BluetoothDevice对象提供了四个创建RfcommSocket的函数(两个用于创建安全连接,两个用于创建透明连接,而两个安全连接和两个透明连接中一个通过SDP设备发现功能产生的随机socket端口,一个使用固定socket端口) 及一个创建SCO socket(用于话音传输)的函数 createScoSocket。createScoSocket及创建透明固定socket端口的API的使用需要BLUETOOTH_ADMIN权限许可。设备发现功能的实现由SdpHelper对象来实现。
下图是BluetoothService相关类图:
BluetoothService服务采用三个ProfileHandler对象提供相关Profile API的服务。BluetoothPanProfileHandler用于Bluetooth PanProfile,BluetoothInputProfileHandler用于Bluetooth InputDeviceProfile,BluetoothHealthProfileHandler用于Bluetooth HealthProfile。
三个ProfileHandler对象通过父对象BluetoothService与其它蓝牙对象交互。三个ProfileHandler对象本身都有一个以BluetoothDevice对象为key的HashMap以维护已连接设备状态。
BluetoothPanProfileHandl对象还通过ConnectivityManager、INetworkManagementService、BluetoothTetheringDataTracker三个对象和接口与数据连接服务交互实现蓝牙连接共享功能。数据连接服务机制见博主的另一篇博文《第十一篇 ANDROID 系统网络连接和管理机制》。
BluetoothHealthProfileHandler使用BluetoothHealthAppConfiguration对象指示一个登记用来与医疗蓝牙设备通讯和接收健康蓝牙设备发来的数据的对象,也称为sink角色,与sink通讯的健康蓝牙设备称为Source。
应用通过调用BluetoothHealth代理对象的registerSinkAppConfiguration函数在BluetoothHealthProfileHandler对象中登记一个BluetoothHealthAppConfiguration对象。
应用使用BluetoothHealth代理对象的connectChannelToSource或connectChannelToSink函数实现sink与Source的连接。
BluetoothHealthProfileHandler使用IBluetoothHealthCallback回调接口通过BluetoothHealth代理对象向应用发送事件通知。
BluetoothService服务还包括几个状态机对象,采用了状态设计模式。
一个BluetoothAdapterStateMachine状态机,处理和维护本地蓝牙的状态事件,包括BluetoothOn、Switching、HotOffWarmUp、PowerOff、PerProcessState等几个状态对象,初始状态为PowerOff。BluetoothAdapterStateMachine状态机还通过IBluetoothStateChangeCallback接口向BluetoothAdapter对象通知本地蓝牙的状态。
在PowerOff状态接收到BluetoothService服务发来的USER_TURN_ON消息时(由应用调用BluetoothAdapter对象的enable函数触发)完成本地蓝牙模块和固件的加载,还启动一个BluetoothEventLoop对象,通过JNI启动一个线程接收本地蓝牙模块bluez产生的蓝牙信号。
两个BluetoothProfileState状态机,其中一个维护A2dp Profile连接状态的管理,另外一个维护Health Profile连接状态的管理。
还有一个以蓝牙设备地址为key的BluetoothDeviceProfileState状态机HashMap集合。为每个已配对远程设备提供一个相关的BluetoothDeviceProfileState状态机,用来跟踪所有的蓝牙Profile的输入输出连接。
InputDevice profile的连接状态的管理由BluetoothInputProfileHandler对象提供的一个状态机对象进行维护。
ANDROID的 BLUETOOTH 实现机制--中介模式和代理模式 .相关推荐
- ANDROID的 BLUETOOTH 实现机制--中介模式和代理模式
原文http://blog.csdn.net/goohong/article/details/8005925 从ANDROID3.0开始BLUETOOTH API提供了对Bluetooth prof ...
- 第十四篇 ANDROID的 BLUETOOTH 实现机制与架构
从ANDROID3.0开始,BLUETOOTH API提供了Bluetooth profile协议的支持.目前ANDROID4.0的蓝牙API提供了五种蓝牙无线接口规范(Bluetooth prof ...
- 中介者模式、代理模式和外观模式的Pk
在学习设计模式的时候,发现这三个模式在一定程度上很是相似.所以总结一下,加以区分. (一)中介者模式. 所谓中介,在我们生活中很是常见,我们买房子可以有中介公司,找兼职也可以有中介公司. ...
- 面试官:策略模式和代理模式有什么区别?
大家好,我是田哥,昨天一哥们面试被问到代理模式,刚好,我也正在写<MyBatis源码分析:小白系列>专栏中的代理模式. 这里也说明一下,本文是MyBatis源码分析专栏中的一篇文章. 感兴 ...
- Java设计模式(四):结构性模式(适配器模式、桥接模式、装饰模式、组合模式、外观模式、亨元模式、代理模式)
目录 一· 适配器设计模式 1.1 现实生活中的适配器例子 1.2 基本介绍 1.3 工作原理 1.4 类适配器模式 1.5 对象适配器模式 1.6 接口适配器模式 1.7 适配器模式在 Spring ...
- 适配器模式(包装模式)和代理模式的区别
适配器模式(包装模式)和代理模式的区别 一.简介 适配器模式:适配器模式(英语:adapter pattern)有时候也称包装样式或者包装.将一个类的接口转接成用户所期待的.一个适配使得因接口不兼容而 ...
- 设计模式之结构型模式:适配器模式、桥接模式、组合模式、装饰器模式、代理模式、
文章目录 什么是结构型模式 适配模式 适配器的数据结构 适配器的实现 缺省适配器 适配器优缺点 适配器模式的使用环境 桥接模式 桥接模式数据结构 桥接模式的实现 桥接模式和适配器模式的联用 桥接模式的 ...
- 结构型模式之代理模式
结构型模式之代理模式 代理模式 结构 静态代理 动态代理 动态代理和静态代理的区别 优缺点 使用场景 源代码 代理模式 一个对象A需要给某个对象B提供一个代理以控制对对象A的访问.这个时候访问对象C不 ...
- 装饰器模式和代理模式的区别
转载自 装饰器模式和代理模式的区别 学习AOP时,教材上面都说使用的是动态代理,可是在印象中代理模式一直都是控制访问什么的,怎么又动态增加行为了,动态增加行为不是装饰器模式吗?于是找了很多资料,想弄清 ...
最新文章
- config文件_您自己的MicroProfile Config来源
- 华为手机asph啥机型_华为正式宣布!19款机型开启新系统内测,你的手机榜首有名吗?...
- 如果你扯了团队后腿,你应该内疚
- mysql 重复了更新_MYSql id相同就更新
- 设计模式-第九篇之观察者模式
- python条形图的间距_Matplotlib有间隙条形图
- getch方法_C语言中getch()函数详解及简单实例
- erphpdown最新版下载v11.12,WordPress内容付费插件
- Word怎么压缩变小?压缩word文档不妨试试这个方法
- 一些心理学需要知道的点。
- php get month,JavaScript从Date对象返回月份 (0 ~ 11)的方法getMonth()
- Android 实现扫描二维码功能
- 如何使用KALI攻击“恶意网站“实验
- Windows 关闭 简繁体切换Ctrl+Shift+F
- 互动让综艺再进化,「黑科技」如何让这届年轻人身临其境做戏精?
- 瑕不掩瑜,读 长铗、刘秋杉《元宇宙-通往无限游戏之路》
- php模板读取工具,打造自己的php半自动化代码审计工具
- java防止注册刷短信攻击_java面试(1)如何防止恶意攻击短信验证码接口
- 谷粒商城高级篇上(未完待续)
- 社区发现的3个评估指标:标准化互信息NMI,ARI指标,以及模块度(modularity)...