当前位置:首页 » 安卓系统 » android蓝牙框架

android蓝牙框架

发布时间: 2022-09-11 16:48:36

1. android蓝牙通信要怎么设计

Android平台支持蓝牙网络协议栈,实现蓝牙设备之间数据的无线传输。本文档描述了怎样利用android平台提供的蓝牙API去实现蓝压设备之间的通信。蓝牙具有point-to-point 和 multipoint两种连接功能。
使用蓝牙API,可以做到:
* 搜索蓝牙设备
* 从本地的Bluetooth adapter中查询已经配对的设备
* 建立RFCOMM通道
* 通过service discovery连接到其它设备
* 在设备之间传输数据
* 管理多个连接

基础知识
本文档介绍了如何使用Android的蓝牙API来完成的四个必要的主要任务,使用蓝牙进行设备通信,主要包含四个部分:蓝牙设置、搜索设备(配对的或可见的)、连接、传输数据。
所有的蓝牙API在android.bluetooth包中。实现这些功能主要需要下面这几个类和接口:

BluetoothAdapter
代表本地蓝牙适配器(蓝牙发射器),是所有蓝牙交互的入口。通过它可以搜索其它蓝牙设备,查询已经配对的设备列表,通过已知的MAC地址创建BluetoothDevice,创建BluetoothServerSocket监听来自其它设备的通信。

BluetoothDevice
代表了一个远端的蓝牙设备, 使用它请求远端蓝牙设备连接或者获取 远端蓝牙设备的名称、地址、种类和绑定状态。 (其信息是封装在 bluetoothsocket 中) 。

BluetoothSocket
代表了一个蓝牙套接字的接口(类似于 tcp 中的套接字) ,他是应用程 序通过输入、输出流与其他蓝牙设备通信的连接点。

BluetoothServerSocket
代表打开服务连接来监听可能到来的连接请求 (属于 server 端) , 为了连接两个蓝牙设备必须有一个设备作为服务器打开一个服务套接字。 当远端设备发起连 接连接请求的时候,并且已经连接到了的时候,Blueboothserversocket 类将会返回一个 bluetoothsocket。

BluetoothClass
描述了一个设备的特性(profile)或该设备上的蓝牙大致可以提供哪些服务(service),但不可信。比如,设备是一个电话、计算机或手持设备;设备可以提供audio/telephony服务等。可以用它来进行一些UI上的提示。
BluetoothProfile

BluetoothHeadset
提供手机使用蓝牙耳机的支持。这既包括蓝牙耳机和免提(V1.5)模式。

BluetoothA2dp
定义高品质的音频,可以从一个设备传输到另一个蓝牙连接。 “A2DP的”代表高级音频分配模式。

BluetoothHealth
代表了医疗设备配置代理控制的蓝牙服务

BluetoothHealthCallback
一个抽象类,使用实现BluetoothHealth回调。你必须扩展这个类并实现回调方法接收更新应用程序的注册状态和蓝牙通道状态的变化。


代表一个应用程序的配置,蓝牙医疗第三方应用注册与远程蓝牙医疗设备交流。

BluetoothProfile.ServiceListener
当他们已经连接到或从服务断开时通知BluetoothProfile IPX的客户时一个接口(即运行一个特定的配置文件,内部服务)。

蓝牙权限
为了在你的应用中使用蓝牙功能,至少要在AndroidManifest.xml中声明两个权限:BLUETOOTH(任何蓝牙相关API都要使用这个权限) 和 BLUETOOTH_ADMIN(设备搜索、蓝牙设置等)。

为了执行蓝牙通信,例如连接请求,接收连接和传送数据都必须有BLUETOOTH权限。

必须要求BLUETOOTH_ADMIN的权限来启动设备发现或操纵蓝牙设置。大多数应用程序都需要这个权限能力,发现当地的蓝牙设备。此权限授予其他的能力不应该使用,除非应用程序是一个“电源管理”,将根据用户要求修改的蓝牙设置

注释:要请求BLUETOOTH_ADMIN的话,必须要先有BLUETOOTH。

在你的应用manifest 文件中声明蓝牙权限。例如:

<manifest ... >
<uses-permission android:name="android.permission.BLUETOOTH" />
...
</manifest>
通过查看<uses-permission>资料来声明应用权限获取更多的信息。

蓝牙设置
在你的应用通过蓝牙进行通信之前,你需要确认设备是否支持蓝牙,如果支持,确信它被打开。

如果不支持,则不能使用蓝牙功能。如果支持蓝牙,但不能够使用,你刚要在你的应用中请求使用蓝牙。这个要两步完成,使用BluetoothAdapter。

2. 确认Android中是否有蓝牙的工具hciconfig

首先,要操作蓝牙,先要在AndroidManifest.xml里加入权限

然后,看下api,Android所有关于蓝牙开发的类都在android.bluetooth包下。 而需要用到了就只有几个而已:
1.BluetoothAdapter 顾名思义,蓝牙适配器,直到我们建立bluetoothSocket连接之前,都要不断操作它BluetoothAdapter里的方法很多,常用的有以下几个:cancelDiscovery() 根据字面意思,是取消发现,也就是说正在搜索设备的时候调用这个方法将不再继续搜索disable()关闭蓝牙enable()打开蓝牙,这个方法打开蓝牙不会弹出提示,更多的时候需要问下用户是否打开,一下这两行代码同样是打开蓝牙,不过会提示用户:Intemtenabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enabler,reCode);//同startActivity(enabler);

getAddress()获取本地蓝牙地址getDefaultAdapter()获取默认BluetoothAdapter,实际上,也只有这一种方法获取BluetoothAdaptergetName()获取本地蓝牙名称getRemoteDevice(String address)根据蓝牙地址获取远程蓝牙设备getState()获取本地蓝牙适配器当前状态(感觉可能调试的时候更需要)isDiscovering()判断当前是否正在查找设备,是返回true***isEnabled()判断蓝牙是否打开,已打开返回true,否则,返回false***(String name,UUID uuid)根据名称,UUID创建并返回BluetoothServerSocket,这是创建BluetoothSocket服务器端的第一步startDiscovery()开始搜索,这是搜索的第一步。 2.BluetoothDevice看名字就知道,这个类描述了一个蓝牙设备(UUIDuuid)根据UUID创建并返回一个BluetoothSocket这个方法也是我们获取BluetoothDevice的目的——创建BluetoothSocket
这个类其他的方法,如getAddress(),getName(),同BluetoothAdapter;

3.BluetoothServerSocket如果去除了Bluetooth相信大家一定再熟悉不过了,既然是Socket,方法就应该都差不多,这个类一种只有三个方法
两个重载的accept(),accept(inttimeout)两者的区别在于后面的方法指定了过时时间,需要注意的是,执行这两个方法的时候,直到接收到了客户端的请求(或是过期之后),都会阻塞线程,应该放在新线程里运行。

还有一点需要注意的是,这两个方法都返回一个BluetoothSocket,最后的连接也是服务器端与客户端的两个BluetoothSocket的连接。

4.BluetoothSocket,跟BluetoothServerSocket相对,是客户端一共5个方法,不出意外,都会用到close(),关闭connect()连接getInptuStream()获取输入流getOutputStream()获取输出流getRemoteDevice()获取远程设备,这里指的是获取bluetoothSocket指定连接的那个远程蓝牙设备 。

3. 什么是android系统,android的发展以及android的平台架构和特性

Android平台采用了整合的策略思想,包括底层Linux操作系统、中间层的中间件和上层的java应用程序。下面我把Android的特性及其架构体系结构总结一下。

一、Android的平台特性

Android平台有如下特性:

1. 应用程序框架支持组件的重用与替换。

这样我们可以把系统中不喜欢的应用程序删除,安装我们喜欢的应用程序。

2. Dalvik虚拟机专门为移动设备进行了优化。

Android应用程序将由Java编写、编译的类文件通过DX工具转换成一种后缀名为.dex的文件来执行。Dalvik虚拟机是基于寄存器的,相对于Java虚拟机速度要快很多。

3. 内部集成浏览器基于开源的WebKit引擎。

有了内置的浏览器,这将意味着WAP应用的时代即将结束,真正的移动互联网时代已经来临,手机就是一台“小电脑”,可以在网上随意遨游。

4. 优化的图形库包括2D和3D图形库,3D图形库基于OpenGL ES 1.0。

强大的图形库给游戏开发带来福音。在3G最为重要的的应用莫过于手机上网和手机游戏。

5. SQLite用作结构化的数据存储

6. 多媒体支持包括常见的音频、视频和静态印象文件格式

如MPEG4、H.264、MP3、AAC、AMR、JGP、PNG、GIF。

7. GSM电话(依赖于硬件)。

8. 蓝牙(Bluetooth)、EDGE、3G、WiFi(依赖于硬件)。

9. 照相机、GPS、指南针和加速度计(依赖于硬件)。

10. 丰富的开发环境包括设备模拟器、调试工具、内存及性能分析图表和Eclipse集成的开发环境插件。

Google提供了Android开发包SDK,其中包含了大量的类库和开发工具,并且针对Eclipse的可视化开发插件ADT。

二、Android平台架构

从上图我们可以看出,Android操作系统的体系结构可分为4层,由上到下依次是应用程序、应用程序框架、核心类库和Linux内核,其中第三层还包括Android运行时的环境。下面分别来讲解各个部分。

1. 程序应用

Android
连同一个核心应用程序包一起发布,该应用程序包包括E-mail客户端、SMS短消息程序、日历、地图、浏览器、联系人管理程序等。所有的应用程序都是用Java编写的。

2. 应用程序框架

开发者完全可以访问核心应用程序所使用的API框架。该应用程序框架架构用来简化组件软件的重用,任何一个应用程序都可以发布它的功能块并且任何其他的应用程序都可以使用其所发布的功能块(不过得遵循框架的安全性限制)。该应用程序重用机制使得组件可以被用户替换。

以下所有的应用程序都由一系列的服务和系统组成,包括:

1)一个可扩展的视图(Views)可以用来创建应用程序,包括列表(lists)、网络(grids)、文本框(text
boxes)、按钮(buttons),甚至是一个可嵌入的Web浏览器。

2)内容管理器(Content Providers)使得应用程序可以访问另一个应用程序的数据(如联系人数据库),或者共享它们自己的数据。

3)一个资源管理器(Resource Manager)提供非代码资源的访问,如本地字符串、图形和分层文件(layout files)。

4)一个通知管理器(Notification Manager)使得应用程序可以在状态栏中显示客户通知信息。

5)一个活动类管理器(Activity Manager)用来管理应用程序生命周期并提供常用的导航回退功能。

3. Android程序库

Android包括一个被Android系统中各种不同组件所使用的C/C++集库。该库通过Android应用程序框架为开发者提供服务。

以下是一些主要的核心库:

1)系统C库:一个从BSD继承来的标准C系统函数库(libc),专门为基于Embedded Linux的设备定制。

2)媒体库:基于PacketVideo
OpenCORE;该库支持录放,并且可以录制许多流行的音频视频格式,还有静态映像文件包括MPEG4、H.264、MP3、AAC、JPG、PNG。

3)Surface Manager:对显示子系统的管理,并且为多个应用程序提供2D和3D图层的无缝融合。

4)LibWebCore:一个最新的Web浏览器引擎,用来支持Android浏览器和一个可嵌入的Web视图。

5)SGL:一个内置的2D图形引擎。

6)3D libraries:基于OpenGL ES 1.0 APIs实现;该库可以使用硬件3D加速(如果可用)或者使用高度优化的3D软加速。

7)FreeType:位图(bitmap)和向量(vector)字体显示。

8)SQLite:一个对于所以应用程序可用、功能强劲的轻型关系型数据库引擎。

4. Android运行库

Android包括了一个核心库,该核心库提供了Java编程语言核心库的大多数功能。

每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例。Dalvik是针对同时高效地运行多个VMs实现的。Dalvik虚拟机执行.dex的Dalvik可执行文件,该格式文件针对最小内存使用做了优化。该虚拟机是基于寄存器的,所有的类都是经由Java汇编器编译,然后通过SDK中的DX工具转化成.dex格式由虚拟机执行。

Dalvik虚拟机依赖于Linux的一些功能,比如线程机制和底层内存管理机制。

5. Linux内核

Android的核心系统服务依赖于Linux内核,如安全性、内存管理、进程管理、网络协议栈和驱动模型。Linux内核也同时作为硬件和软件栈之间的硬件抽象层。

4. android 蓝牙 开发问题

public boolean setName(String name)
Set the friendly Bluetooth name of the local Bluetoth adapter.
This name is visible to remote Bluetooth devices.
Valid Bluetooth names are a maximum of 248 UTF-8 characters, however many
remote devices can only display the first 40 characters, and some may be limited
to just 20.

文档中不是有说明吗!
最大有效值是用utf-8编码的248个字符,然而有些蓝牙设备最多能显示40个字符,....20char。

5. 如何使用Android蓝牙开发

Android平台支持蓝牙网络协议栈,实现蓝牙设备之间数据的无线传输。本文档描述了怎样利用android平台提供的蓝牙API去实现蓝压设备之间的通信。蓝牙具有point-to-point 和 multipoint两种连接功能。
使用蓝牙API,可以做到:
* 搜索蓝牙设备
* 从本地的Bluetooth adapter中查询已经配对的设备
* 建立RFCOMM通道
* 通过service discovery连接到其它设备
* 在设备之间传输数据
* 管理多个连接

基础知识
本文档介绍了如何使用Android的蓝牙API来完成的四个必要的主要任务,使用蓝牙进行设备通信,主要包含四个部分:蓝牙设置、搜索设备(配对的或可见的)、连接、传输数据。
所有的蓝牙API在android.bluetooth包中。实现这些功能主要需要下面这几个类和接口:

BluetoothAdapter
代表本地蓝牙适配器(蓝牙发射器),是所有蓝牙交互的入口。通过它可以搜索其它蓝牙设备,查询已经配对的设备列表,通过已知的MAC地址创建BluetoothDevice,创建BluetoothServerSocket监听来自其它设备的通信。

BluetoothDevice
代表了一个远端的蓝牙设备, 使用它请求远端蓝牙设备连接或者获取 远端蓝牙设备的名称、地址、种类和绑定状态。 (其信息是封装在 bluetoothsocket 中) 。

BluetoothSocket
代表了一个蓝牙套接字的接口(类似于 tcp 中的套接字) ,他是应用程 序通过输入、输出流与其他蓝牙设备通信的连接点。

BluetoothServerSocket
代表打开服务连接来监听可能到来的连接请求 (属于 server 端) , 为了连接两个蓝牙设备必须有一个设备作为服务器打开一个服务套接字。 当远端设备发起连 接连接请求的时候,并且已经连接到了的时候,Blueboothserversocket 类将会返回一个 bluetoothsocket。

BluetoothClass
描述了一个设备的特性(profile)或该设备上的蓝牙大致可以提供哪些服务(service),但不可信。比如,设备是一个电话、计算机或手持设备;设备可以提供audio/telephony服务等。可以用它来进行一些UI上的提示。
BluetoothProfile

BluetoothHeadset
提供手机使用蓝牙耳机的支持。这既包括蓝牙耳机和免提(V1.5)模式。

BluetoothA2dp
定义高品质的音频,可以从一个设备传输到另一个蓝牙连接。 “A2DP的”代表高级音频分配模式。

BluetoothHealth
代表了医疗设备配置代理控制的蓝牙服务

BluetoothHealthCallback
一个抽象类,使用实现BluetoothHealth回调。你必须扩展这个类并实现回调方法接收更新应用程序的注册状态和蓝牙通道状态的变化。

6. iOS的蓝牙开发跟Android有什么不同

Native App开发
Native App开发即我们所称的传统APP开发模式(原生APP开发模式),该开发针对IOS、Android等不同的手机操作系统要采用不同的语言和框架进行开发,该模式通常是由“云服务器数据+APP应用客户端”两部份构成,APP应用所有的UI元素、数据内容、逻辑框架均安装在手机终端上。
Web App开发
Web App开发即是一种框架型APP开发模式(HTML5 APP 框架开发模式),该开发具有跨平台的优势,该模式通常由“HTML5云网站+APP应用客户端”两部份构成,APP应用客户端只需安装应用的框架部份,而应用的数据则是每次打开APP的时候,去云端取数据呈现给手机用户。
Web APP应用呈现以下特点:
(1)每次打开APP,都要通过APP框架向云网站取UI及数据;
(2)手机用户无法上网则无法访问APP应用中的数据。
(3)框架型的APP无法调用手机终端的硬件设备(语音、摄像头、短信、GPS、蓝牙、重力感应等)
(4)框架型APP的访问速度受手机终端上网的限制,每次使用均会消耗一定的手机上网流量;
(5)框架型APP应用的安装包小巧,只包含框架文件,而大量的UI元素、数据内容刚存放在云端;
(6)APP用户每次都可以访问到实时的最新的云端数据;
(7)APP用户无须频繁更新APP应用,与云端实现的是实时数据交互;
适用企业:电子商务、金融、新闻资讯、企业集团需经常更新内容的APP应用。
Native App(原生型APP)应用呈现以下特点:
(1)每次获取最新的APP功能,需要升级APP应用;
(2)原生型APP应用的安装包相对较大,包含UI元素、数据内容、逻辑框架;
(3)手机用户无法上网也可访问APP应用中以前下载的数据。
(4)原生型的APP可以调用手机终端的硬件设备(语音、摄像头、短信、GPS、蓝牙、重力感应等)
(5)APP应用更新新功能,涉及到每次要向各个应用商店进行提交审核。
适用企业:游戏、电子杂志、管理应用、物联网等无需经常更新程序框架的APP应用。
移动Web无所不在,移动Web是目前唯一的支持各种设备访问的平台,与桌面Web一样,移动Web支持各种标准的协议。移动Web也是唯一一个可供开发者发布移动应用的平台,它将各种移动交互与桌面任务有效地连接了起来;而开发Native App可以充分利用设备的特性,而这一点往往是Web浏览器做不到的,所以对一个产品本身而言,Native App是最佳的选择。

7. 开发者选项里蓝牙“Gabeldorsche”堆栈有什么用

这是android 11里用Rust框架重构的蓝牙协议栈。

安卓11推出的下一代蓝牙堆栈技术。

旨在提高蓝牙的稳定性。

还在完善之中。

所以现在还放在开发者选项里。

敏感的隐私权限只给一次:

Google 在 Android 10 中引入的“临时权限授予”机制颇受好评,在 Android 11 中,有关用户隐私数据的权限管控得到了进一步强化。

具体而言,针对位置、麦克风和相机这三类权限的权限请求弹窗将包含一个“仅本次允许”的选项,单次授权在应用可见活动(activity)和前台服务(foreground service)持续运行期间有效,不再满足条件时应用获取到的单次授权将被撤销,并且需要重新申请。

通知系统改进

我们在 Android 系统更新的“具透”系列文章中一直强调的一点是,围绕 Android 通知系统的改进一直以来都是 Android 系统更新的一条“暗线”。在 Android 11 中,这条“暗线”分别触到了勿扰模式设置和对话通知上。

8. android 蓝牙外设 谁是server 谁是client

Android平台支持蓝牙网络协议栈,实现蓝牙设备之间数据的无线传输。本文档描述了怎样利用android平台提供的蓝牙API去实现蓝压设备之间的通信。蓝牙具有point-to-point 和 multipoint两种连接功能。使用蓝牙API,可以做到: * 搜索蓝牙设备 * 从本地的Bluetooth adapter中查询已经配对的设备 * 建立RFCOMM通道 * 通过service discovery连接到其它设备 * 在设备之间传输数据 * 管理多个连接 基础知识本文档介绍了如何使用Android的蓝牙API来完成的四个必要的主要任务,使用蓝牙进行设备通信,主要包含四个部分:蓝牙设置、搜索设备(配对的或可见的)、连接、传输数据。所有的蓝牙API在android.bluetooth包中。实现这些功能主要需要下面这几个类和接口: BluetoothAdapter 代表本地蓝牙适配器(蓝牙发射器),是所有蓝牙交互的入口。通过它可以搜索其它蓝牙设备,查询已经配对的设备列表,通过已知的MAC地址创建BluetoothDevice,创建BluetoothServerSocket监听来自其它设备的通信。 BluetoothDevice 代表了一个远端的蓝牙设备, 使用它请求远端蓝牙设备连接或者获取 远端蓝牙设备的名称、地址、种类和绑定状态。 (其信息是封装在 bluetoothsocket 中) 。 BluetoothSocket 代表了一个蓝牙套接字的接口(类似于 tcp 中的套接字) ,他是应用程 序通过输入、输出流与其他蓝牙设备通信的连接点。 BluetoothServerSocket 代表打开服务连接来监听可能到来的连接请求 (属于 server 端) , 为了连接两个蓝牙设备必须有一个设备作为服务器打开一个服务套接字。 当远端设备发起连 接连接请求的时候,并且已经连接到了的时候,Blueboothserversocket 类将会返回一个 bluetoothsocket。 BluetoothClass 描述了一个设备的特性(profile)或该设备上的蓝牙大致可以提供哪些服务(service),但不可信。比如,设备是一个电话、计算机或手持设备;设备可以提供audio/telephony服务等。可以用它来进行一些UI上的提示。 BluetoothProfile BluetoothHeadset 提供手机使用蓝牙耳机的支持。这既包括蓝牙耳机和免提(V1.5)模式。 BluetoothA2dp 定义高品质的音频,可以从一个设备传输到另一个蓝牙连接。 “A2DP的”代表高级音频分配模式。 BluetoothHealth 代表了医疗设备配置代理控制的蓝牙服务 BluetoothHealthCallback 一个抽象类,使用实现BluetoothHealth回调。你必须扩展这个类并实现回调方法接收更新应用程序的注册状态和蓝牙通道状态的变化。 代表一个应用程序的配置,蓝牙医疗第三方应用注册与远程蓝牙医疗设备交流。 BluetoothProfile.ServiceListener 当他们已经连接到或从服务断开时通知BluetoothProfile IPX的客户时一个接口(即运行一个特定的配置文件,内部服务)。 蓝牙权限为了在你的应用中使用蓝牙功能,至少要在AndroidManifest.xml中声明两个权限:BLUETOOTH(任何蓝牙相关API都要使用这个权限) 和 BLUETOOTH_ADMIN(设备搜索、蓝牙设置等)。 为了执行蓝牙通信,例如连接请求,接收连接和传送数据都必须有BLUETOOTH权限。 必须要求BLUETOOTH_ADMIN的权限来启动设备发现或操纵蓝牙设置。大多数应用程序都需要这个权限能力,发现当地的蓝牙设备。此权限授予其他的能力不应该使用,除非应用程序是一个“电源管理”,将根据用户要求修改的蓝牙设置 注释:要请求BLUETOOTH_ADMIN的话,必须要先有BLUETOOTH。 在你的应用manifest 文件中声明蓝牙权限。例如: ... 通过查看资料来声明应用权限获取更多的信息。 蓝牙设置在你的应用通过蓝牙进行通信之前,你需要确认设备是否支持蓝牙,如果支持,确信它被打开。 如果不支持,则不能使用蓝牙功能。如果支持蓝牙,但不能够使用,你刚要在你的应用中请求使用蓝牙。这个要两步完成,使用BluetoothAdapter。 1.获取BluetoothAdapter 所有的蓝牙活动请求BluetoothAdapter,为了获取BluetoothAdapter,呼叫静态方法getDefaultAdapter() 。这个会返回一个BluetoothAdapter,代表设备自己的蓝牙适配器(蓝牙无线电)。这个蓝牙适配器应用于整个系统中,你的应用可以通过这个对象进行交互。如果getDefaultAdapter()返回null,则这个设备不支持蓝牙。例如: BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { // Device does not support Bluetooth } 2.打开蓝牙 其次。你需要确定蓝牙能够使用。通过isEnabled()来检查蓝牙当前是否可用。如果这个方法返回false,则蓝牙不能够使用。为了请求蓝牙使用,呼叫startActivityForResult()与的ACTION_REQUEST_ENABLE动作意图。通过系统设置中启用蓝牙将发出一个请求(不停止蓝牙应用)。例如: if (mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } 对话框中显示请求使用蓝牙权限。如果响应"Yes",这个进程完成(或失败)后你的应用将能够使用蓝牙。 REQUEST_ENABLE_BT常量作为一个整型传到startActivityForResult()中(值必须大于0),该系统传回给你,在你onActivityResult()作为实现的requestCode参数。 如果调用蓝牙成功,你的Activity就会在onActivityResult()中收到RESULT_OK结果,如果蓝牙不能使用由于错误(或用户响应“NO”那么结果返回RESULT_CANCELED。 除了通过onActivityResult(),还可以通过监听ACTION_STATE_CHANGED这个broadcast Intent来知道蓝牙状态是否改变。这个Intent包含EXTRA_STATE,EXTRA_PREVIOUS_STATE两个字段,分别代表新旧状态。可能的值是STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF, 还有STATE_OFF。 小贴: Enabling discoverability 将自动启用蓝牙。如果您计划执行蓝牙活动之前,始终使设备可发现,你可以跳过上面的步骤2。参阅enabling discoverability。 搜索设备使用BluetoothAdapter可以通过设备搜索或查询配对设备找到远程Bluetooth设备。 Device discovery(设备搜索)是一个扫描搜索本地已使能Bluetooth设备并且从搜索到的设备请求一些信息的过程(有时候会收到类似“discovering”,“inquiring”或“scanning”)。但是,搜索到的本地Bluetooth设备只有在打开被发现功能后才会响应一个discovery请求,响应的信息包括设备名,类,唯一的MAC地址。发起搜寻的设备可以使用这些信息来初始化跟被发现的设备的连接。一旦与远程设备的第一次连接被建立,一个pairing请求就会自动提交给用户。如果设备已配对,配对设备的基本信息(名称,类,MAC地址)就被保存下来了,能够使用Bluetooth API来读取这些信息。使用已知的远程设备的MAC地址,连接可以在任何时候初始化而不必先完成搜索(当然这是假设远程设备是在可连接的空间范围内)。 需要记住,配对和连接是两个不同的概念: 配对意思是两个设备相互意识到对方的存在,共享一个用来鉴别身份的链路键(link-key),能够与对方建立一个加密的连接。 连接意思是两个设备现在共享一个RFCOMM信道,能够相互传输数据。 目前Android Bluetooth API's要求设备在建立RFCOMM信道前必须配对(配对是在使用Bluetooth API初始化一个加密连接时自动完成的)。 下面描述如何查询已配对设备,搜索新设备。 注意:Android的电源设备默认是不能被发现的。用户可以通过系统设置让它在有限的时间内可以被发现,或者可以在应用程序中要求用户使能被发现功能。 查找匹配设备在搜索设备前,查询配对设备看需要的设备是否已经是已经存在是很值得的,可以调用getBondedDevices()来做到,该函数会返回一个描述配对设备BluetoothDevice的结果集。例如,可以使用ArrayAdapter查询所有配对设备然后显示所有设备名给用户: Set pairedDevices = mBluetoothAdapter.getBondedDevices(); // If there are paired devices if (pairedDevices.size() > 0) { // Loop through paired devices for (BluetoothDevice device : pairedDevices) { // Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName() + "n" + device.getAddress()); } }; BluetoothDevice对象中需要用来初始化一个连接唯一需要用到的信息就是MAC地址。 扫描设备要开始搜索设备,只需简单的调用startDiscovery() 。该函数时异步的,调用后立即返回,返回值表示搜索是否成功开始。搜索处理通常包括一个12秒钟的查询扫描,然后跟随一个页面显示搜索到设备Bluetooth名称。 应用中可以注册一个带ACTION_FOUND Intent的BroadcastReceiver,搜索到每一个设备时都接收到消息。对于每一个设备,系统都会广播ACTION_FOUND Intent,该Intent携带着而外的字段信息EXTRA_DEVICE和EXTRA_CLASS,分别包含一个BluetoothDevice和一个BluetoothClass。 下面的示例显示如何注册和处理设备被发现后发出的广播: 代码如下: // Create a BroadcastReceiver for ACTION_FOUND private final BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // When discovery finds a device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName() + "n" + device.getAddress()); } } }; // Register the BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter); // Don't forget to unregister ring onDestroy 警告:完成设备搜索对于Bluetooth适配器来说是一个重量级的处理,要消耗大量它的资源。一旦你已经找到一个设备来连接,请确保你在尝试连接前使用了cancelDiscovery()来停止搜索。同样,如果已经保持了一个连接的时候,同时执行搜索设备将会显着的降低连接的带宽,所以在连接的时候不应该执行搜索发现。 使能被发现如果想让本地设备被其他设备发现,可以带ACTION_REQUEST_DISCOVERABLE action Intent调用startActivityForResult(Intent, int) 方法。该方法会提交一个请求通过系统刚设置使设备出于可以被发现的模式(而不影响应用程序)。默认情况下,设备在120秒后变为可以被发现的。可以通过额外增加EXTRA_DISCOVERABLE_DURATION Intent自定义一个值,最大值是3600秒,0表示设备总是可以被发现的(小于0或者大于3600则会被自动设置为120秒)。下面示例设置时间为300: Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent); ! 询问用户是否允许打开设备可以被发现功能时会显示一个对话框。如果用户选择“Yes”,设备会在指定时间过后变为可以被发现的。Activity的onActivityResult()回调函数被调用,结果码等于设备变为可以被发现所需时长。如果用户选择“No”或者有错误发生,结果码会是Activity.RESULT_CANCELLED。 提示:如果Bluetooth没有启用,启用Bluetooth可被发现功能能够自动开启Bluetooth。 在规定的时间内,设备会静静的保持可以被发现模式。如果想在可以被发现模式被更改时受到通知,可以用ACTION_SCAN_MODE_CHANGED Intent注册一个BroadcastReceiver,包含额外的字段信息EXTRA_SCAN_MODE和EXTRA_PREVIOUS_SCAN_MODE分别表示新旧扫描模式,其可能的值为SCAN_MODE_CONNECTABLE_DISCOVERABLE(discoverable mode),SCAN_MODE_CONNECTABLE(not in discoverable mode but still able to receive connections),SCAN_MODE_NONE(not in discoverable mode and unable to receive connections)。如果只需要连接远程设备就不需要打开设备的可以被发现功能。只在应用作为一个服务器socket的宿主用来接收进来的连接时才需要使能可以被发现功能,因为远程设备在初始化连接前必须先发现了你的设备。 连接设备为了在两台设备上创建一个连接,你必须在软件上实现服务器端和客户端的机制,因为一个设备必须必须打开一个server socket,而另一个必须初始化这个连接(使用服务器端设备的MAC地址进行初始化)。当服务器端和客户端在同一个RFCOMM信道上都有一个BluetoothSocket时,就可以认为它们之间建立了一个连接。在这个时刻,每个设备能获得一个输出流和一个输入流,也能够开始数据传输。本节介绍如何在两个设备之间初始化一个连接。服务器端和客户端获得BluetoothSocket的方法是不同的,服务器端是当一个进入的连接被接受时才产生一个BluetoothSocket,客户端是在打开一个到服务器端的RFCOMM信道时获得BluetoothSocket的。 一种实现技术是,每一个设备都自动作为一个服务器,所以每个设备都有一个server socket并监听连接。然后每个设备都能作为客户端建立一个到另一台设备的连接。另外一种代替方法是,一个设备按需打开一个server socket,另外一个设备仅初始化一个到这个设备的连接。 Note: 如果两个设备在建立连接之前并没有配对,那么在建立连接的过程中,Android框架将自动显示一个配对请求的notification或者一个对话框,如Figure 3所示。所以,在尝试连接设备时,你的应用程序无需确保设备之间已经进行了配对。你的RFCOMM连接将会在用户确认配对之后继续进行,或者用户拒绝或者超时之后失败。 作为服务器连接如果要连接两个设备,其中一个必须充当服务器,通过持有一个打开的BluetoothServerSocket对象。服务器socket的作用是侦听进来的连接,如果一个连接被接受,提供一个连接好的BluetoothSocket对象。从BluetoothServerSocket获取到BluetoothSocket对象之后,BluetoothServerSocket就可以(也应该)丢弃了,除非你还要用它来接收更多的连接。 下面是建立服务器socket和接收一个连接的基本步骤: 1.通过调用(String, UUID)得到一个BluetoothServerSocket对象。 该字符串为服务的识别名称,系统将自动写入到一个新的服务发现协议(SDP)数据库接入口到设备上的(名字是任意的,可以简单地是应用程序的名称)项。 UUID也包括在SDP接入口中,将是客户端设备连接协议的基础。也就是说,当客户端试图连接本设备,它将携带一个UUID用来唯一标识它要连接的服务,UUID必须匹配,连接才会被接受。 2.通过调用accept()来侦听连接请求。 这是一个阻塞的调用,知道有连接进来或者产生异常才会返回。只有远程设备发送一个连接请求,并且携带的UUID与侦听它socket注册的UUID匹配,连接请求才会被接受。如果成功,accept()将返回一个连接好的BluetoothSocket对象。 3.除非需要再接收另外的连接,否则的话调用close() 。 close()释放server socket和它的资源,但不会关闭连接accept()返回的连接好的BluetoothSocket对象。与TCP/IP不同,RFCOMM同一时刻一个信道只允许一个客户端连接,因此大多数情况下意味着在BluetoothServerSocket接受一个连接请求后应该立即调用close()。 accept()调用不应该在主Activity UI线程中进行,因为这是个阻塞的调用,会妨碍其他的交互。经常是在在一个新线程中做BluetoothServerSocket或BluetoothSocket的所有工作来避免UI线程阻塞。注意所有BluetoothServerSocket或BluetoothSocket的方法都是线程安全的。 下面是一个简单的接受连接的服务器组件代码示例: private class AcceptThread extends Thread { private final BluetoothServerSocket mmServerSocket; public AcceptThread() { // Use a temporary object that is later assigned to mmServerSocket, // because mmServerSocket is final BluetoothServerSocket tmp = null; try { // MY_UUID is the app's UUID string, also used by the client code tmp = mBluetoothAdapter.(NAME, MY_UUID); } catch (IOException e) { } mmServerSocket = tmp; } public void run() { BluetoothSocket socket = null; // Keep listening until exception occurs or a socket is returned while (true) { try { socket = mmServerSocket.accept(); } catch (IOException e) { break; } // If a connection was accepted if (socket != null) { // Do work to manage the connection (in a separate thread) manageConnectedSocket(socket); mmServerSocket.close(); break; } } } /* * Will cancel the listening socket, and cause the thread to finish * / public void cancel() { try { mmServerSocket.close(); } catch (IOException e) { } }

9. android bluetooth hid协议的开发求助

Android Bluetooth HID实现详解


Android 关于蓝牙的部分使用的是BlueZ协议栈。但是直到目前2.3.3都没有扩展HID的profile,只是实现了最基本的Handset和d2dp的profile,所以我们的工作涉及到从应用到jni三层的修改,具体修改文件如图所示,绿色表示新建的类,橙色表示修改的类。

一. 本地层


路径:framework/base/core/jni/

参照android_server_BluetoothA2dpService.cpp新建android_server_bluetoothHidServer.cpp。该类中主要是通过dbus对bluez协议栈的访问,dbus 的通用方法都在android_bluetooth_common.cpp中实现,我们做的仅仅是通过dbus_func_args_async调用到bluez提供的input接口。

主要实现以下两个方法函数:

static jboolean connectSinkNative(JNIEnv *env, jobject object, jstring path) {


#ifdef HAVE_BLUETOOTH


LOGV(__FUNCTION__);


if (nat) {


const char *c_path = env->GetStringUTFChars(path, NULL);



bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,


c_path, "org.bluez.Input", "Connect",


DBUS_TYPE_INVALID);



env->ReleaseStringUTFChars(path, c_path);


return ret ? JNI_TRUE : JNI_FALSE;


}


#endif


return JNI_FALSE;


}



static jboolean disconnectSinkNative(JNIEnv *env, jobject object,


jstring path) {


#ifdef HAVE_BLUETOOTH


LOGV(__FUNCTION__);


if (nat) {


const char *c_path = env->GetStringUTFChars(path, NULL);



bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,


c_path, "org.bluez.Input", "Disconnect",


DBUS_TYPE_INVALID);



env->ReleaseStringUTFChars(path, c_path);


return ret ? JNI_TRUE : JNI_FALSE;


}


#endif


return JNI_FALSE;


}

这里要注意将该文件添加到AndroidRuntime.cpp和Android.mk中,否则不会编译到动态库中。

此部分编译后最终生成libandroid_runtime.so并替换到system/libs下

二.Framework的java部分

路径framework/base/java/android/server/中添加BluetoothHidService.java文件

路径framework/base/java/android/bluetooth/中添加BluetoothHid.java和IBluetoothHid.aidl文件。


interface IBluetoothHid {


boolean connect(in BluetoothDevice device);


boolean disconnect(in BluetoothDevice device);


int getState(in BluetoothDevice device);


boolean setPriority(in BluetoothDevice device, int priority);


int getPriority(in BluetoothDevice device);


}

BluetoothHid.java中主要的两个方法connect和disconnect间接地通过aidl访问BluetoothHidService。这里主要是实现跨进程并为上层提供可直接访问的方法。

由此framework的主要部分打包生成framework.Jar并最终部署到system/framework里。

三.应用(Settings.apk)

最后需要修改应用部分,应用部分的修改点比较分散,不想框架层那样整块模仿A2DP的样子那么方便,但也不是说jni部分有多么容易。反而对于我这种对C语言不熟悉的人来说,修改jni是最头疼得事了。好在蓝牙HID这部分框架层的修改都是整块进行的,理解上还算比价容易。

总的来说在Settings.apk中要修改的文件主要是这么几个:

LocalBluetoothProfileManager.java这里主要提供一个HID的profile以便应用层访问。建一个HIDProfile的class调用framework中的BluetoothHID。实际上就是通过bender机制调用了BluetoothHidService。

CashedBluetoothDevice中添加显示蓝牙键盘的图标,BluetoothPairingDialog中则需要添加一段蓝牙配对验证处理的代码,我是参照i9000中先弹出一个随机数,然后在键盘中敲入相同的随机数即配对成功,具体实现如下:


// HID


if (isDeviceKeyboard(mDevice)) {


String pin = String.format("%06d", Long.valueOf(Math


.abs(new Random().nextLong() % 1000000L)));


mPairingView.setVisibility(View.GONE);


messageView.setText(getString(


R.string.bluetooth_enter_keyboard_pin_msg, pin, name));



byte[] bytePin = BluetoothDevice.convertPinToBytes(pin);


if (bytePin != null) {


mDevice.setPin(bytePin);


}


}


……


}

转载

10. 求助大神:android4.2蓝牙(bluedroid)协议栈的系统框图!!

http://blog.csdn.net/innost/article/details/9187199

热点内容
java的indexof 发布:2025-01-09 19:51:14 浏览:610
光遇ios国际服怎么登录安卓 发布:2025-01-09 19:44:24 浏览:778
手机如何破解无线密码 发布:2025-01-09 19:36:52 浏览:49
java猫 发布:2025-01-09 19:35:13 浏览:130
linux端口号命令 发布:2025-01-09 19:21:55 浏览:530
输入虚拟手机服务器地址怎么填 发布:2025-01-09 18:58:50 浏览:349
dede换数据库 发布:2025-01-09 18:53:23 浏览:263
sql2000数据库置疑修复 发布:2025-01-09 18:35:54 浏览:411
块设备块缓存 发布:2025-01-09 18:35:46 浏览:485
HED编译 发布:2025-01-09 18:20:26 浏览:408