一、背景及相关知识学习

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)。

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

更多相关文章

  1. VFY: unable to find class referenced in signature
  2. Android: 获取当前线程状态
  3. Android(安卓)获取root权限 实现重启
  4. 支付宝蜻蜓刷脸支付——Android
  5. 关于Mac升级Android(安卓)Studio无法获取安装目录权限的解决办法
  6. Android(安卓)在OnCreate()中获取控件高度与宽度
  7. Android(安卓)N Ethernet新IP获取机制—IpManager
  8. Android通过NDK获取Keystore签名值
  9. 关于如何实现android状态栏沉淀式效果

随机推荐

  1. android ScrollView 多张图片之间有空白
  2. android监听edittext输入事件
  3. android studio 复制项目
  4. android 使用百度地图画轨迹
  5. Android中getChildAt()方法介绍
  6. Android(安卓)联系人的增删修改
  7. Android:下载网络图片
  8. Android获得屏幕分辨率的两种方法
  9. android设置全屏模式
  10. Android官方教程翻译(6)——添加ActionBar