android pbap client 蓝牙
一. 简介:
此功能具体使用的是bluetoothV2.1之后的Phone Book Access Profile功能,简称PBAP .目前MTK Android中只实现了server端的功能,并没有实现client.所以该文档简略介绍了如何开发一个简易client.并在最后给出一个测试用的demo.下面就按照客户端的开发流程来说明.
二. 前提设置:
本处介绍执行PBAP之前的蓝牙需要的一些操作.其包括开启和搜索.
首先在manifest中加入权限
<uses-permissionandroid:name="android.permission.BLUETOOTH"/> <uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/> |
判断是否开启
private BluetoothAdaptermBluetoothAdapter; if (null ==mBluetoothAdapter) { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } if (!mBluetoothAdapter.isEnabled()) { mStatus = CLOSE; } else { mStatus = OPEN; } |
如果未开启,则执行开启
Intent startBluetoothIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(startBluetoothIntent, 1001 ); //1001 = BT OPEN |
执行完开启后在onActivityResult中取收取反馈
protected void onActivityResult(int requestCode,int resultCode, Intent data) { if (requestCode ==1001) { //1001 = BT OPEN if (resultCode ==RESULT_OK) { mBtStatus.setCurrStatus(BtStatus.OPEN); } else { //在打开时的dialog中选择取消也会反馈到这里 mBtStatus.setCurrStatus(BtStatus.OPEN_FAILED); } } } |
反馈中接受为OK的话,下一步可以开始搜索附近蓝牙设备
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mBluetoothAdapter.startDiscovery(); |
搜索的时候需要监听下面几个action
IntentFilter iFilter = new IntentFilter(); iFilter.addAction(BluetoothDevice.ACTION_FOUND); iFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); |
在定义的BroadCast中存储搜索到的BLUETOOTH_DEVICE
BluetoothDevice bluetoothDevice = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); |
搜索的时候可以取消,相关函数为
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mBluetoothAdapter. cancelDiscovery (); |
三. 蓝牙的配对连接
//此处的UUID是协议中规定的.这样才能访问server端的pbap服务. //在spec中未看到.但是查阅了蓝牙的UUID相关中有发现这个条目 //同0X1103 MY_UUID = UUID.fromString("0000112f-0000-1000-8000-00805f9b34fb"); //api中提供的安全连接方法 BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID); //连接函数.此为broken方法,需要放入thread中取处理 socket.connect(); |
SPEC中描述2个设备中需要GAP认证建立安全连接.本处使用SDK中提供的
|
上面的步骤操作完之后,服务端和客户端都会弹出一个配对对话框.在双方都配对成功后.服务端又会弹出一个是否允许对方获取联系人的确认.在对方确认后.socket.connect才执行完成.
上面整了这么多.其实都是前期的必须操作.至此2台手机连接上了.并建立了PBAP连接.
四. PhoneBook DownLoad Feature
下面开始操作server端电话本下载功能.在spec中的功能流程图如下
下面分开说明这些步骤:
1. PCE建立和PSE的连接
先声明此处的连接跟前一节说的连接是两回事.前一节是2台机器建立蓝牙连接
此处为OBEX的连接.
client请求数据包格式
Client request 解释:
80 op
001f 整个数据包长度
10 OBEX版本,始终10
00 flags始终00
2000 数据包的最大长度2k
下面7-n为header关于header请查看obex spec
46 target
0013 target header的长度
796135f0f0c511d809660800200c9a66 此处不知道哪里来的.但就是这个
c3 length
0000f483 length值
现在发现connect的时候.这串字符串是不需要变得.肯定是这个
server反馈数据包格式
Server response 解释:
这个是随意找了一台手机做的测试结果.不过一般都相差不大.关键点connect id
a0 response code(只有a0为成功,其他都为各式各样的错误)
001f 长度
10 obex 版本
00 flags
4bc8 最大数据包长度
下面都是header信息.关于header请查看obex spec
Cb connect id(关键.很重要)
00000007connect id value(这个值需要存储下来.下面会用的到)
4a who
0013 who的长度
796135f0f0c511d809660800200c9a660000000 who的值(跟上面的target是一样的)
判断完response code为a0 就可以操作下一步了.
2. PCE下载联系人
PCE下载联系人需要用到的是GET方法.
在OBEX中GET方法如下定义
在PBAP SPEC中定义了如下的要求
按照上图描述.数据组织如下
83 get(也可以为03)
004f 整个数据包的长度.最后手动计算得出
Cb connect id
00000007 此处就为上面connect方法执行完成之后得到的数据.
01 name
0021 name的长度
00740065006c00650063006f006d002f00700062002e0076006300660000
上面为telecom/pb.vcf的unicode码.结尾必须要0000收尾.对于name在obex中定义必须要用unicode来处理.这个字串表示取到对方手机存储中所有的联系人.
42 type
0012 type的长度
782d62742f70686f6e65626f6f6b00 为x-bt/phonebook 结尾必须用00.此处
4c app params
0014 app params 的长度
06 此处为pbap自定义,表示vcardfilter
08 8位
0000000000000000 64位掩码.需要的话请看spec.全为0,则返回所有的
07 vcard 版本
01 长度
01 01= 3.1 00 = 2.0
04 maxlistcount 取多少个
02 长度
Ffff ffff表示取所有的.
此处的例子说明的是取对方联系人中手机内纯中所有的.
maxlistcount的参数并没有做测试.也不知道设置了在此处是否有用.
vcard的版本,服务端是会同时定义好2.0和3.1的vcardbuilder的,这个是协议中要求的.所有对于客户端具体我们想要用那个,视我们用那个vard praser来决定.
Filter其实很有用.规定了我们取哪些数据回来.毕竟如果服务端的联系人都有头像之类的.我们要是全取回来.要考虑下速度的问题了
ListStartOffset,改例子取全部.所有这个参数都没传过去.默认就为0.
server反馈数据包格式
此处没有存数据.暂时没有例子.分析也同上
Response code必须要为a0才能继续解析
Header中的解析到body或者end of body的话.则根据length,把这段buffer存储下来.直接保存到vcf文件中就行了.当然.如果code中实现了vcard praser,则可以直接去解析并载入到联系人数据库中.
顺便说明下:对于PBAP.MTK不支持calllog的处理.其他的spec中有的都支持.
3. 虚线处表示可此处循环.
此处不做详细解释.可以查看pbap spec中虚拟文件夹这一块.此处的功能可以单独下载server端1个或者几个联系人.
要实现此处功能.最好也先了解下phonebook browser的功能.
4. PCE终端跟PSE的连接
调用OBEX的disconnect功能就可以了.目前代码未实现
五. 目前总结
简易完成了demo.保存至T卡的vcf可以正常导入的本地联系人.但是代码流程全是按照一些正常的操作来走的.后续需要把需要的错误处理全部加上去.
参考资料:
使用 JSR-82 API 实现 OBEX 图像传输
http://419443161-qq-com.iteye.com/blog/544299
Android手机的PIM同步技术的研究与实现
http://cdmd.cnki.com.cn/Article/CDMD-10614-1012470693.htm
PBAP协议中文精简版
http://www.docin.com/p-204262132.html
android pbap client 蓝牙的更多相关文章
- 【转】Android 4.2蓝牙介绍
原文网址:http://blog.csdn.net/innost/article/details/9187199 Tieto公司某蓝牙大牛写得<程序员>投稿文章 Android 4.2蓝牙 ...
- ZT Android 4.2蓝牙介绍
Android 4.2蓝牙介绍 分类: Android开发系列 2013-06-27 14:16 7110人阅读 评论(22) 收藏 举报 目录(?)[-] Android 42蓝牙介绍 一 蓝牙规 ...
- Android端简易蓝牙聊天通讯App(原创)
欢迎转载,但请注明出处!谢谢.http://www.cnblogs.com/weizhxa/p/5792775.html 最近公司在做一个蓝牙串口通讯的App,有一个固定的蓝牙设备,需要实现手机连接相 ...
- 【视频】零基础学Android开发:蓝牙聊天室APP(四)
零基础学Android开发:蓝牙聊天室APP第四讲 4.1 ListView控件的使用 4.2 BaseAdapter具体解释 4.3 ListView分布与滚动事件 4.4 ListView事件监听 ...
- Android源代码下载之《Android新闻client源代码》
介绍 Android新闻client源代码,功能上分为:新闻.关注.读报.微博.里面比較有特色的就是读报功能.真正安装报纸的排版进行读报.给人得感觉就像是在读真实的报纸.事实上即使首页的动态云标签很有 ...
- 开源:矿Android新闻client,快、小、支持离线阅读、操作简单、内容丰富,形式多样展示、的信息量、全功能 等待(离开码邮箱)
分享:矿Android新闻client.快.小.支持离线阅读.操作简单.内容丰富,形式多样展示.的信息量.全功能 等待(离开码邮箱) 历时30天我为了开发这个新闻clientAPP,下面简称觅闻 ht ...
- 【视频】零基础学Android开发:蓝牙聊天室APP(二)
零基础学Android开发:蓝牙聊天室APP第二讲 2.1 课程内容应用场景 2.2 Android UI设计 2.3 组件布局:LinearLayout和RelativeLayout 2.4 Tex ...
- Android L2TP Client Setup
原文链接:http://www.softether.org/4-docs/2-howto/9.L2TPIPsec_Setup_Guide_for_SoftEther_VPN_Server/3.Andr ...
- Android 8 设置蓝牙名称 流程
记录android 8设置蓝牙名称的流程. packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothDeviceRenam ...
随机推荐
- 审计参数 audit_trail
audit_trail参数定义了在哪里存放审计记录 默认是DB.如果将其设置为NONE,标准数据库审计功能被取消.audit_trail是静态参数,修改后必须重启数据库. 可以设置的值:- ...
- weka数据预处理
Weka数据预处理(一) 对于数据挖掘而言,我们往往仅关注实质性的挖掘算法,如分类.聚类.关联规则等,而忽视待挖掘数据的质量,但是高质量的数据才能产生高质量的挖掘结果,否则只有"Garbag ...
- int 与 Integer--话说数组转集合
话说是自从JDK5后,而这就可以自动进行类型转换了. 当然,区别还是有的,就是对象和“非对象”什么的.可是,今天进行一个测试,出了一个小问题,现将代码贴下: 代码0:先来一个正常点的,用String进 ...
- shell学习笔记(2)替换命令··与()的区别
·CMD·在执行的时候,shell不管··中的内容是什么,先进性解释,再把解释后的最终结果送给shell,如果解释后的结果不是shell可以行的命令,就会报错.但是仅仅把cmd的执行结果作为文本输出, ...
- run()和star()区别
run()和star()区别 run()-->只是thread类的一个普通方法调用 star()-->用来启动线程,实现多线程运行
- UVA 10498 Happiness(线性规划-单纯形)
Description Prof. Kaykobad has given Nasa the duty of buying some food for the ACM contestents. Nasa ...
- ThinkPHP 中实现 Rewrite 模式
ThinkPHP中默认的URL地址是形如这样的:http://localhost/Myapp/index.php/Index/index/ Myapp是我的项目文件名,默认的访问地址是上面这样的.为了 ...
- 1.表单中 get与post提交方法的区别?
get是发送请求HTTP协议通过url参数传递进行接收,而post是实体数据,可以通过表单提交大量信息. get是从服务器上获取数据,post是向服务器传送数据. GET方式提交的数据最多只能有102 ...
- JSon_零基础_002_将List类型数组转换为JSon格式的对象字符串,返回给界面
将List类型数组转换为JSon格式的对象字符串,返回给界面 所需要导入的包: 编写bean: package com.west.webcourse.po; /** * 第01步:编写bean类, * ...
- android linux
app 权限 - shell 权限2000 system root .adb 指令 a.查看链接终端设备 adb devices b.进入设备终端 adb shell ;多台设备 adb -s 设备号 ...