Android上利用SDK的BluetoothAPI实现传送文件
2012-03-27 16:48
441 查看
从Android 2.0版的SDK开始,公开了蓝牙相关的API接口,而之前的1.5~1.6未公开蓝牙API的系统,实际上也仅仅是未公开API而已,有可能是带有蓝牙服务的,通过一些Hack手段是能够获取到被隐藏的API的,这部分不在本文讨论范围之内。从SDK中公开的API来看,功能相当简单,并没有提供传输文件的直接支持,也就意味着要在Android上编码实现传送文件,还是要花一番功夫的。
蓝牙传输文件是通过OBEX协议来实现的,具体可以参见蓝牙相关的协议说明。对于传送文件而言,我们只需要实现OBEX中OBJECT PUSH的那一部分即可,好在在Android Bluetooth API的基础上实现OBEX的协议中的PUSH部分完全是可行的,下面就来详细说明一下。首先,BluetoothSocket和普通的用于网络编程的Socket有些不同,我们要实现的是一个传送文件的客户端,可以通过BluetoothDevice.
createRfcommSocketToServiceRecord (UUID uuid) 这一接口来创建BluetoothSocket,注意该接口需要传入一个UUID的参数,这一UUID将标示服务类型,可以参见SDP(Service Discover Protocol),用于传输文件的服务的UUID是{00001105-0000-1000-8000-00805F9B34FB},这样如果接收方能够支持这一服务的话,我们就可以成功创建出一个用于传输的Socket。
成功创建Socket之后,我们就需要开始按照OBEX的协议标准来和服务端进行通讯了,传输一个文件的过程是:CONNECT->PUT->PUT….->DISCONNECT,要实现OBEX协议通讯,实际上就是要按照OBEX协议的格式来组织我们写往Socket流的二进制数据,关于OBEX协议标准可以参见相关文档,这里就不赘述,简要介绍一下OBEX协议格式,主要由包头和包体两部分组成,包头中第一个字节表示操作码,用于标示该包数据类型,不同的操作码对应的包头格式也不同。包头中含有的其他信息也都是一个【特征码+信息内容】的格式来组织的。
下面回到我们的传输文件过程,简单的三部曲似乎没有什么特别的,这里需要注意的也就是PUT的过程,可能是分为好几次进行的。CONNECT的时候,服务端回返回一个包可用最大长度,这个长度就限定了我们发送出去的包长度,包括OBEX的协议包头。当文件大小超过这一长度限制-包头长度的时候,就需要分几次来发送文件内容了。第一次PUT的包的头部信息中必须至少包含文件名和文件大小两项,其他关于MimeType等信息都是可选的,第二次就不必再带有这些信息了,PUT包的尾部为BODY/BODY
Final标志,分别为0x48、0x49,非最后一包使用0x48,否则使用0x49,注意,OBEX协议包头中的操作码和这一标志也有一个对应关系,0x02/0x82都表示Put,但只有最后一包可以使用0x82。 另外OBEX也是面向连接的,每次发包到服务端之后都应该获取服务端的响应包,并且解析响应包的内容,如果发生超时或者响应包非正常响应,都因该采取相应的异常处理流程。
最后需要注意的就是传输文件内容完成之后,要记得发送DISCONNECT的包,否则某些情况下服务端会认为是没有成功完成发送。
后记:
后来发现一个新问题,传输的文件发送给android手机的时候,某些文件不能够传输成功.后来查看了Android的源代码,原来Android只支持4中mimetype的接收,video/*,audio/*,image/*,text/plain,所以如果你要传输的文件不属于这四种mimetype,你在代码中还是要把它伪装一下,设置mimetype为其中之一,我选择的是image/*,经测试,效果良好.
蓝牙传输文件是通过OBEX协议来实现的,具体可以参见蓝牙相关的协议说明。对于传送文件而言,我们只需要实现OBEX中OBJECT PUSH的那一部分即可,好在在Android Bluetooth API的基础上实现OBEX的协议中的PUSH部分完全是可行的,下面就来详细说明一下。首先,BluetoothSocket和普通的用于网络编程的Socket有些不同,我们要实现的是一个传送文件的客户端,可以通过BluetoothDevice.
createRfcommSocketToServiceRecord (UUID uuid) 这一接口来创建BluetoothSocket,注意该接口需要传入一个UUID的参数,这一UUID将标示服务类型,可以参见SDP(Service Discover Protocol),用于传输文件的服务的UUID是{00001105-0000-1000-8000-00805F9B34FB},这样如果接收方能够支持这一服务的话,我们就可以成功创建出一个用于传输的Socket。
成功创建Socket之后,我们就需要开始按照OBEX的协议标准来和服务端进行通讯了,传输一个文件的过程是:CONNECT->PUT->PUT….->DISCONNECT,要实现OBEX协议通讯,实际上就是要按照OBEX协议的格式来组织我们写往Socket流的二进制数据,关于OBEX协议标准可以参见相关文档,这里就不赘述,简要介绍一下OBEX协议格式,主要由包头和包体两部分组成,包头中第一个字节表示操作码,用于标示该包数据类型,不同的操作码对应的包头格式也不同。包头中含有的其他信息也都是一个【特征码+信息内容】的格式来组织的。
下面回到我们的传输文件过程,简单的三部曲似乎没有什么特别的,这里需要注意的也就是PUT的过程,可能是分为好几次进行的。CONNECT的时候,服务端回返回一个包可用最大长度,这个长度就限定了我们发送出去的包长度,包括OBEX的协议包头。当文件大小超过这一长度限制-包头长度的时候,就需要分几次来发送文件内容了。第一次PUT的包的头部信息中必须至少包含文件名和文件大小两项,其他关于MimeType等信息都是可选的,第二次就不必再带有这些信息了,PUT包的尾部为BODY/BODY
Final标志,分别为0x48、0x49,非最后一包使用0x48,否则使用0x49,注意,OBEX协议包头中的操作码和这一标志也有一个对应关系,0x02/0x82都表示Put,但只有最后一包可以使用0x82。 另外OBEX也是面向连接的,每次发包到服务端之后都应该获取服务端的响应包,并且解析响应包的内容,如果发生超时或者响应包非正常响应,都因该采取相应的异常处理流程。
最后需要注意的就是传输文件内容完成之后,要记得发送DISCONNECT的包,否则某些情况下服务端会认为是没有成功完成发送。
后记:
后来发现一个新问题,传输的文件发送给android手机的时候,某些文件不能够传输成功.后来查看了Android的源代码,原来Android只支持4中mimetype的接收,video/*,audio/*,image/*,text/plain,所以如果你要传输的文件不属于这四种mimetype,你在代码中还是要把它伪装一下,设置mimetype为其中之一,我选择的是image/*,经测试,效果良好.
相关文章推荐
- Android上利用SDK的BluetoothAPI实现传送文件
- 利用libmp3lame实现在Android上录音MP3文件示例
- 试用socket api借口设计一个文件传送软件,并编程实现,可自定义文件传输的通信。
- 有关Android Bluetooth - OBEX OPP文件传送
- android定时定位 - 利用百度定位API来实现定时定位功能
- 利用HTTP协议实现Android文件上传至WEB服务器,采用PHP接收文件(参考网上自己实现)
- 非MFC,利用window api OPENFILENAME实现定制打开文件对话框
- android 利用极光推送sdk实现分组推送
- 利用input type=file和FileReader API实现在浏览器客户端通过选择对话框读取文件
- 关于利用android-serialport-api实现在安卓设备上进行串口通信,附精简版demo,亲测可用。
- 有关Android Bluetooth - OBEX OPP文件传送
- Android利用WifiDirect实现文件传输功能
- 避开Google Voice Search利用Google Speech API实现Android语音识别
- 避开Google Voice Search利用Google Speech API实现Android语音识别
- PB利用API-SHFileOperation 文件操作函数 实现多文件及文件夹的删除复制等操作
- android利用FTP实现文件共享
- 利用Foxit SDK快速实现自己的Mobile PDF阅读器-Android篇
- 在Spring MVC框架下利用Servlet3.0 API实现文件上传
- 利用java实现android项目结构API文档
- Android 利用缓存机制实现文件下载