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中提供的

 

 

//此處的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();

 

 

 

 

        

        

        

        

        

        

        

 上面的步驟操作完之后,服務端和客戶端都會彈出一個配對對話框.在雙方都配對成功后.服務端又會彈出一個是否允許對方獲取聯系人的確認.在對方確認后.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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM