Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1379991
  • 博文数量: 860
  • 博客积分: 425
  • 博客等级: 下士
  • 技术积分: 1464
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-20 19:57
个人简介

对技术执着

文章分类

全部博文(860)

文章存档

2019年(16)

2018年(12)

2015年(732)

2013年(85)

2012年(15)

我的朋友

分类: LINUX

2012-10-17 17:03:14

、背景及相关知识学习

1、Android Bluetooth SDK

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

我们可以通过intent调用android.bluetooth.opp包下的activity也可以直接调用android.bluetooth包使用android的蓝牙功能。

方法如下:

通过android.bluetooth.opp包我们需要作的是:

打开蓝牙:

Intent enabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enabler,reCode);//同startActivity(enabler);

通过android.bluetooth包我们需要做的是以下几点:

(1).BluetoothAdapter

顾名思义,蓝牙适配器,直到我们建立bluetoothSocket连接之前,都要不断操作它。BluetoothAdapter里的方法很多,常用的有以下几个:

复制代码

cancelDiscovery() //根据字面意思,是取消发现,也就是说当我们正在搜索设备的时候调用这个方法将不再继续搜索 disable() //关闭蓝牙 enable() //打开蓝牙 getAddress() //获取本地蓝牙地址 getDefaultAdapter() //获取默认BluetoothAdapter,实际上,也只有这一种方法获取BluetoothAdapter getName() //获取本地蓝牙名称 getRemoteDevice(String address) //根据蓝牙地址获取远程蓝牙设备 getState() //获取本地蓝牙适配器当前状态(感觉可能调试的时候更需要) isDiscovering() //判断当前是否正在查找设备,是返回true isEnabled() //判断蓝牙是否打开,已打开返回true,否则,返回false listenUsingRfcommWithServiceRecord(String name,UUID uuid) //根据名称,UUID创建并返回BluetoothServerSocket,这是创建BluetoothSocket服务器端的第一步 startDiscovery() //开始搜索,这是搜索的第一步

复制代码

(2).BluetoothDevice

看名字就知道,这个类描述了一个蓝牙设备

createRfcommSocketToServiceRecord(UUID uuid) // 根据UUID创建并返回一个BluetoothSocket

这个方法也是我们获取BluetoothDevice的目的——创建BluetoothSocket

这个类其他的方法,如getAddress(),getName(),同BluetoothAdapter

(3).BluetoothServerSocket

如果去除了Bluetooth,相信大家一定再熟悉不过了,既然是Socket,方法就应该都差不多, 这个类一种只有三个方法

两个重载的accept(),accept(int timeout)两者的区别在于后面的方法指定了过时时间,需要注意的是,执行这两个方法的时候,直到接收到了客户端的请求(或是过期之后),都会阻塞线程,应该放在新线程里运行!

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

(4).BluetoothSocket

跟BluetoothServerSocket相对,是客户端。一共5个方法,不出意外,都会用到

复制代码

close() //关闭 connect() //连接 getInptuStream() //获取输入流 getOutputStream() //获取输出流 getRemoteDevice() //获取远程设备,这里指的是获取bluetoothSocket指定连接的那个远程蓝牙设备

复制代码

2、Android Bluetooth 底层知识

Android蓝牙协议栈使用的是BlueZ,支持GAP, SDP, and RFCOMM规范,是一个SIG认证的蓝牙协议栈。

Bluez 是GPL许可的,因此Android的框架内与用户空间的bluez代码通过D-BUS进程通讯进行交互,以避免专有代码。

Headset和Handsfree(v1.5)规范就在Android框架中实现的,它是跟Phone App紧密耦合的。这些规范也是SIG认证的。

下面的图表提供了一个以库为导向的蓝牙栈视图。

实线框的是Android模块,红色虚线部分为合作伙伴指定模块(译者注:芯片商提供)。

下面的图表是以进程为导向视图:

移植

BlueZ是兼容蓝牙2.1的,可以工作在任何2.1芯片以及向后兼容的旧的蓝牙版本。有要有两个方面:

串口驱动 UART driver

蓝牙电源开/关 Bluetooth Power On/Off

串口驱动

BlueZ核心子系统使用hciattach守护进程添加你的指定硬件串口驱动。

例如,MSM7201A,这个文件是在drivers/serial/msm_serial.c。你还需要通过修改init.rc为hciattach来编辑命令行选项。

蓝牙电源开/关

蓝牙芯片的电源开关方法1.0和Post 1.0是不同的,具体如下:

1.0:Android框架写0或1到/sys/modules/board_[PLATFORM]/parameters/bluetooth_power_on

Post 1.0:Android框架使用linux rfkill API,参考 arch/arm/mach-msm/board-trout-rfkill.c例子。

编译

编译Android打开蓝牙支持,添加下面这行内容到BoardConfig.mk。

    BOARD_HAVE_BLUETOOTH :=true

调试

调试你的蓝牙实现,可以通过读跟蓝牙相关的logs(adb logcat)和查找ERROR和警告消息。Android使用Bluez,同时会带来一些有用的调式工具。下面的片段为了提供一个建议的例子:

复制代码

1 hciconfig -a # print BT chipset address and features. Useful to check if you can communicate with your BT chipset. 2 hcidump -XVt # print live HCI UART traffic. 3 hcitool scan # scan for local devices. Useful to check if RX/TX works. 4 l2ping ADDRESS # ping another BT device. Useful to check if RX/TX works. 5 sdptool records ADDRESS # request the SDP records of another BT device.

复制代码

守护进程日志

hcid(STDOUT)和hciattach(STDERR)的守护进程日志缺省是被写到/dev/null。编辑init.rc和init.PLATFORM.rc在logwrapper下运行这些守护进程,把它们输出到logcat。

hciconfig -a 和 hcitool

如果你编译你自己的system.img,除了hcitool扫描不行,hciconfig -a是可以工作的,尝试安装固件到蓝牙芯片。XXX TBD

工具

BlueZ为调试和与蓝牙子系统通信提供很多设置命令行工具,包含下面这些:

Hciconfig、hcitool、hcidump、sdptool、dbus-send、dbus-monitor

二、主要类的学习

1、  BluetoothOppProvider

继承ContentProvider,所谓ContentProvider是一个提供数据的机制,当希望对其它app提供数据时需要用到。BluetoothOppProvider提供了蓝牙设置相关的数据。其中的数据表位btopp,其数据项包括BluetoothShare._ID、BluetoothShare.URI、 BluetoothShare.FILENAME_HINT、BluetoothShare._DATA、BluetoothShare.MIMETYPE 、BluetoothShare.DIRECTION、BluetoothShare.DESTINATION、BluetoothShare.VISIBILITY、BluetoothShare.USER_CONFIRMATION 、BluetoothShare.STATUS、 BluetoothShare.TOTAL_BYTES、BluetoothShare.CURRENT_BYTES、BluetoothShare.TIMESTAMP、Constants.MEDIA_SCANNED为字段名的数据项。

2、  BluetoothOppReceiver

继承BroadcastReceiver,所谓BroadcastReceiver是一个能够接受以sendBroadcast()方式发送的intent的基类。BluetoothOppReceiver处理系统消息:Intent.ACTION_BOOT_COMPLETED、BluetoothAdapter.ACTION_STATE_CHANGED;其它app发来的消息:BluetoothDevicePicker.ACTION_DEVICE_SELECTED、Constants.ACTION_INCOMING_FILE_CONFIRM;opp service发来的消息:BluetoothShare.INCOMING_FILE_CONFIRMATION_REQUEST_ACTION、BluetoothShare.TRANSFER_COMPLETED_ACTION;应用层发来的消息:Constants.ACTION_OPEN、Constants.ACTION_LIST、Constants.ACTION_OPEN_OUTBOUND_TRANSFER、Constants.ACTION_OPEN_INBOUND_TRANSFER、Constants.ACTION_HIDE、Constants.ACTION_COMPLETE_HIDE。

3、  BluetoothOppService

继承Service,所谓Service是一个能在系统后台工作,向其他app提供服务的机制。每个Service都需要在AndroidManifest.xml上声明。BluetoothOppService提供蓝牙的后台服务,包括文件传输和消息侦听。

4、  BluetoothOppTransfer

为BluetoothOppService提供对象传输客户端功能,调用BluetoothOppObexClientSession维护传输会话。

5、  BluetoothOppRfcommListener

创建进程在OPUSH(OBEX Object Push) Chanel侦听socket消息,并回调BluetoothOppService中的回调函数进行处理。

6、  BluetoothOppRfcommTransport

利用socket实现传输过程,只是封装来一下,并无实质内容。

7、  BluetoothOppObexServerSession

为BluetoothOppService提供对象传输服务器端功能。

8、  BluetoothOppObexClientSession

为BluetoothOppService提供对象传输客户端功能。

三、总结

android.bluetooth.opp包的结构大体如下图分层,其中UI交互层的类主要负责界面显示,用户交互等功能,特别还有其它app通过intent调用bluetooth应用的入口;事务逻辑层主要负责蓝牙应用层事务逻辑(BluetoothOppManager等)和数据抽象处理(BluetoothOppReceiveFileInfo)的功能;服务提供层主要提供对底层功能的封装调用(BluetoothOppProvider)和工具函数与常量(BluetoothOppUtility)。

至于双模开发,要修改的文件应该没有。

、背景及相关知识学习

1、Android Bluetooth SDK

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

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH" />

我们可以通过intent调用android.bluetooth.opp包下的activity也可以直接调用android.bluetooth包使用android的蓝牙功能。

方法如下:

通过android.bluetooth.opp包我们需要作的是:

打开蓝牙:

Intent enabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enabler,reCode);//同startActivity(enabler);

通过android.bluetooth包我们需要做的是以下几点:

(1).BluetoothAdapter

顾名思义,蓝牙适配器,直到我们建立bluetoothSocket连接之前,都要不断操作它。BluetoothAdapter里的方法很多,常用的有以下几个:

复制代码
cancelDiscovery() //根据字面意思,是取消发现,也就是说当我们正在搜索设备的时候调用这个方法将不再继续搜索 disable() //关闭蓝牙 enable() //打开蓝牙 getAddress() //获取本地蓝牙地址 getDefaultAdapter() //获取默认BluetoothAdapter,实际上,也只有这一种方法获取BluetoothAdapter getName() //获取本地蓝牙名称 getRemoteDevice(String address) //根据蓝牙地址获取远程蓝牙设备 getState() //获取本地蓝牙适配器当前状态(感觉可能调试的时候更需要) isDiscovering() //判断当前是否正在查找设备,是返回true isEnabled() //判断蓝牙是否打开,已打开返回true,否则,返回false listenUsingRfcommWithServiceRecord(String name,UUID uuid) //根据名称,UUID创建并返回BluetoothServerSocket,这是创建BluetoothSocket服务器端的第一步 startDiscovery() //开始搜索,这是搜索的第一步
复制代码

 

(2).BluetoothDevice

看名字就知道,这个类描述了一个蓝牙设备

createRfcommSocketToServiceRecord(UUID uuid) // 根据UUID创建并返回一个BluetoothSocket

这个方法也是我们获取BluetoothDevice的目的——创建BluetoothSocket

这个类其他的方法,如getAddress(),getName(),同BluetoothAdapter

(3).BluetoothServerSocket

如果去除了Bluetooth,相信大家一定再熟悉不过了,既然是Socket,方法就应该都差不多, 这个类一种只有三个方法

两个重载的accept(),accept(int timeout)两者的区别在于后面的方法指定了过时时间,需要注意的是,执行这两个方法的时候,直到接收到了客户端的请求(或是过期之后),都会阻塞线程,应该放在新线程里运行!

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

(4).BluetoothSocket

跟BluetoothServerSocket相对,是客户端。一共5个方法,不出意外,都会用到

复制代码
close() //关闭 connect() //连接 getInptuStream() //获取输入流 getOutputStream() //获取输出流 getRemoteDevice() //获取远程设备,这里指的是获取bluetoothSocket指定连接的那个远程蓝牙设备
复制代码

 

2、Android Bluetooth 底层知识

Android蓝牙协议栈使用的是BlueZ,支持GAP, SDP, and RFCOMM规范,是一个SIG认证的蓝牙协议栈。

Bluez 是GPL许可的,因此Android的框架内与用户空间的bluez代码通过D-BUS进程通讯进行交互,以避免专有代码。

Headset和Handsfree(v1.5)规范就在Android框架中实现的,它是跟Phone App紧密耦合的。这些规范也是SIG认证的。

下面的图表提供了一个以库为导向的蓝牙栈视图。

实线框的是Android模块,红色虚线部分为合作伙伴指定模块(译者注:芯片商提供)。

下面的图表是以进程为导向视图:

 

移植

BlueZ是兼容蓝牙2.1的,可以工作在任何2.1芯片以及向后兼容的旧的蓝牙版本。有要有两个方面:

串口驱动 UART driver

蓝牙电源开/关 Bluetooth Power On/Off

串口驱动

BlueZ核心子系统使用hciattach守护进程添加你的指定硬件串口驱动。

例如,MSM7201A,这个文件是在drivers/serial/msm_serial.c。你还需要通过修改init.rc为hciattach来编辑命令行选项。

蓝牙电源开/关

蓝牙芯片的电源开关方法1.0和Post 1.0是不同的,具体如下:

1.0:Android框架写0或1到/sys/modules/board_[PLATFORM]/parameters/bluetooth_power_on

Post 1.0:Android框架使用linux rfkill API,参考 arch/arm/mach-msm/board-trout-rfkill.c例子。

 

编译

编译Android打开蓝牙支持,添加下面这行内容到BoardConfig.mk。

    BOARD_HAVE_BLUETOOTH :=true

 

调试

调试你的蓝牙实现,可以通过读跟蓝牙相关的logs(adb logcat)和查找ERROR和警告消息。Android使用Bluez,同时会带来一些有用的调式工具。下面的片段为了提供一个建议的例子:

复制代码
1 hciconfig -a # print BT chipset address and features. Useful to check if you can communicate with your BT chipset. 2 hcidump -XVt # print live HCI UART traffic. 3 hcitool scan # scan for local devices. Useful to check if RX/TX works. 4 l2ping ADDRESS # ping another BT device. Useful to check if RX/TX works. 5 sdptool records ADDRESS # request the SDP records of another BT device.
复制代码

 

守护进程日志

hcid(STDOUT)和hciattach(STDERR)的守护进程日志缺省是被写到/dev/null。编辑init.rc和init.PLATFORM.rc在logwrapper下运行这些守护进程,把它们输出到logcat。

hciconfig -a 和 hcitool

如果你编译你自己的system.img,除了hcitool扫描不行,hciconfig -a是可以工作的,尝试安装固件到蓝牙芯片。XXX TBD

 

工具

BlueZ为调试和与蓝牙子系统通信提供很多设置命令行工具,包含下面这些:

Hciconfig、hcitool、hcidump、sdptool、dbus-send、dbus-monitor

 

二、主要类的学习

1、  BluetoothOppProvider

继承ContentProvider,所谓ContentProvider是一个提供数据的机制,当希望对其它app提供数据时需要用到。BluetoothOppProvider提供了蓝牙设置相关的数据。其中的数据表位btopp,其数据项包括BluetoothShare._ID、BluetoothShare.URI、 BluetoothShare.FILENAME_HINT、BluetoothShare._DATA、BluetoothShare.MIMETYPE 、BluetoothShare.DIRECTION、BluetoothShare.DESTINATION、BluetoothShare.VISIBILITY、BluetoothShare.USER_CONFIRMATION 、BluetoothShare.STATUS、 BluetoothShare.TOTAL_BYTES、BluetoothShare.CURRENT_BYTES、BluetoothShare.TIMESTAMP、Constants.MEDIA_SCANNED为字段名的数据项。

2、  BluetoothOppReceiver

继承BroadcastReceiver,所谓BroadcastReceiver是一个能够接受以sendBroadcast()方式发送的intent的基类。BluetoothOppReceiver处理系统消息:Intent.ACTION_BOOT_COMPLETED、BluetoothAdapter.ACTION_STATE_CHANGED;其它app发来的消息:BluetoothDevicePicker.ACTION_DEVICE_SELECTED、Constants.ACTION_INCOMING_FILE_CONFIRM;opp service发来的消息:BluetoothShare.INCOMING_FILE_CONFIRMATION_REQUEST_ACTION、BluetoothShare.TRANSFER_COMPLETED_ACTION;应用层发来的消息:Constants.ACTION_OPEN、Constants.ACTION_LIST、Constants.ACTION_OPEN_OUTBOUND_TRANSFER、Constants.ACTION_OPEN_INBOUND_TRANSFER、Constants.ACTION_HIDE、Constants.ACTION_COMPLETE_HIDE。

3、  BluetoothOppService

继承Service,所谓Service是一个能在系统后台工作,向其他app提供服务的机制。每个Service都需要在AndroidManifest.xml上声明。BluetoothOppService提供蓝牙的后台服务,包括文件传输和消息侦听。

4、  BluetoothOppTransfer

为BluetoothOppService提供对象传输客户端功能,调用BluetoothOppObexClientSession维护传输会话。

5、  BluetoothOppRfcommListener

创建进程在OPUSH(OBEX Object Push) Chanel侦听socket消息,并回调BluetoothOppService中的回调函数进行处理。

6、  BluetoothOppRfcommTransport

利用socket实现传输过程,只是封装来一下,并无实质内容。

7、  BluetoothOppObexServerSession

为BluetoothOppService提供对象传输服务器端功能。

8、  BluetoothOppObexClientSession

为BluetoothOppService提供对象传输客户端功能。

 

三、总结

android.bluetooth.opp包的结构大体如下图分层,其中UI交互层的类主要负责界面显示,用户交互等功能,特别还有其它app通过intent调用bluetooth应用的入口;事务逻辑层主要负责蓝牙应用层事务逻辑(BluetoothOppManager等)和数据抽象处理(BluetoothOppReceiveFileInfo)的功能;服务提供层主要提供对底层功能的封装调用(BluetoothOppProvider)和工具函数与常量(BluetoothOppUtility)。

至于双模开发,要修改的文件应该没有。

 

来自:http://www.cnblogs.com/chenbin7/archive/2012/08/21/2649125.html

阅读(2276) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~