1、背景及相關知識學習 html
一、Android Bluetooth SDK linux
首先,要操做藍牙,先要在AndroidManifest.xml里加入權限 android
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH" />
咱們能夠經過intent調用android.bluetooth.opp包下的activity也能夠直接調用android.bluetooth包使用android的藍牙功能。 服務器
方法以下: app
經過android.bluetooth.opp包咱們須要做的是: 框架
打開藍牙: socket
Intent enabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enabler,reCode);//同startActivity(enabler);
經過android.bluetooth包咱們須要作的是如下幾點: ide
(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指定鏈接的那個遠程藍牙設備
二、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
2、主要類的學習
一、 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爲字段名的數據項。
二、 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。
三、 BluetoothOppService
繼承Service,所謂Service是一個能在系統後臺工做,向其餘app提供服務的機制。每一個Service都須要在AndroidManifest.xml上聲明。BluetoothOppService提供藍牙的後臺服務,包括文件傳輸和消息偵聽。
四、 BluetoothOppTransfer
爲BluetoothOppService提供對象傳輸客戶端功能,調用BluetoothOppObexClientSession維護傳輸會話。
五、 BluetoothOppRfcommListener
建立進程在OPUSH(OBEX Object Push) Chanel偵聽socket消息,並回調BluetoothOppService中的回調函數進行處理。
六、 BluetoothOppRfcommTransport
利用socket實現傳輸過程,只是封裝來一下,並沒有實質內容。
七、 BluetoothOppObexServerSession
爲BluetoothOppService提供對象傳輸服務器端功能。
八、 BluetoothOppObexClientSession
爲BluetoothOppService提供對象傳輸客戶端功能。
3、總結
android.bluetooth.opp包的結構大致以下圖分層,其中UI交互層的類主要負責界面顯示,用戶交互等功能,特別還有其它app經過intent調用bluetooth應用的入口;事務邏輯層主要負責藍牙應用層事務邏輯(BluetoothOppManager等)和數據抽象處理(BluetoothOppReceiveFileInfo)的功能;服務提供層主要提供對底層功能的封裝調用(BluetoothOppProvider)和工具函數與常量(BluetoothOppUtility)。
至於雙模開發,要修改的文件應該沒有。