BLE简介和Android BLE编程
http://www.aiuxian.com/article/p-1752155.html
一.BLE和BT區別
其實我知道許多程序員不太喜歡閱讀除了代碼以外的文檔,因為有時這些過于冗長的文檔對編程并沒有更多的好處,有了協議,接口,demo差不多很多人就能寫出很好質量的代碼了。但其實更深入的編程是少了閱讀的,閱讀文檔可以解決很多編程中遇到的困難,比如在大數據大流量情況下,很多正常的程序會表現出不可靠的一面,這已經不是夠編程能解決的了,硬件的配置,服務器帶寬,使用的數據庫,調用的接口都有可能是瓶頸。比如BLE,同樣的藍牙,但卻有著本質區別,一個表現就是不是所有藍牙設備都支持BLE,編程如果不考慮這個問題,程序出錯就會迷茫。再比如連接到BLE或者藍牙上的設備是有數量限制的,如果不知道這個限制,在連接不上時,也會六神無主。
BLE在智家居中和移動設備中的應用方興未艾,做深入的研究推廣到更多的應用上,還是有意義的。
1藍牙的歷史:藍牙的創始公司是愛立信。1994年愛立信開始對小范圍無線通信技術進行研發,在1997年,愛立信的研究激發了其他公司的濃厚興趣,于是1998年2月,一些跨國大公司包括諾基亞、蘋果、三星組成的一個特殊興趣小組(SIG),他們共同的目標是建立一個全球性的小范圍無線通信技術,該項技術就是藍牙。
?
2.BLE 是Bluetooth Low Energy的縮寫,又叫藍牙4.0,區別于藍牙3.0和之前的技術。BLE前身是NOKIA開發的Wibree技術,主要用于實現移動智能終端與周邊配件之間的持續連接,是功耗極低的短距離無線通信技術,并且有效傳輸距離被提升到了100米以上,同時只需要一顆紐扣電池就可以工作數年之久。 ? 3. BLE是在藍牙技術的基礎上發展起來的,既同于藍牙,又區別于傳統藍牙。BLE設備分單模和雙模兩種,雙模簡稱BR,商標為Bluetooth Smart Ready,單模簡稱BLE或者LE,商標為Bluetooth Smart。Android是在4.3后才支持BLE,這可以解釋不是所有藍牙手機都支持BLE,而且支持BLE的藍牙手機一般是雙模的。 ? 4.雙模兼容傳統藍牙,可以和傳統藍牙通信,也可以和BLE通信,常用在手機上,android4.3和IOS4.0之后版本都支持BR,也就是雙模設備。單模只能和BR和單模的設備通信,不能和傳統藍牙通信,由于功耗低,待機長,所以常用在手環的智能設備上。這可以解釋手機上的BLE與手環等設備上的BLE的區別。 ? 5不是所有手機都支持BLE,因為BLE不僅僅依靠軟件實現,同時需要硬件支持,于是有很多手機不能聯接智能手環等設備。Android4.3手機上安裝的是雙模BR,因此兼容藍牙3.0之前的技術,既能與BLE設備通信,也能與傳統藍牙通信,比較耗電,能夠像傳統設備一樣高速傳輸。大部分智能手環使用的單工BLE,不支持傳統藍牙,不能與之聯結和通信,低功耗低速率設備。 ?二.BLE(低功耗藍牙)的用途
應用特點:小包傳輸,手機擴展,低功耗
☆ 2.4G 藍牙低功耗系統
☆ 消費類電子產品
☆ 秱勱電話外圍擴展設備
☆ 運勱和休閑設備
☆ 健康醫療用品 (血壓計,體溫計 …)
☆ 汽車電子設備
☆ 人機接口設備 (鍵盤,鼠標,遙控器 …)
☆ USB Dongle
?
三藍牙的工作原理
1?藍牙通信的主從關系
藍牙技術規定每一對設備之間進行藍牙通訊時,必須一個為主角色,另一為從角色,才能進行通信,通信時,必須由主端進行查找,發起配對,建鏈成功后,雙方即可收發數據。理論上,一個藍牙主端設備,可同時與7個藍牙從端設備進行通訊。一個具備藍牙通訊功能的設備,可以在兩個角色間切換,平時工作在從模式,等待其它主設備來連接,需要時,轉換為主模式,向其它設備發起呼叫。一個藍牙設備以主模式發起呼叫時,需要知道對方的藍牙地址,配對密碼等信息,配對完成后,可直接發起呼叫。這可以解釋為什么有時無法連接藍牙,有可能是連接的藍牙設備過多。
2藍牙的呼叫過程
藍牙主端設備發起呼叫,首先是查找,找出周圍處于可被查找的藍牙設備。主端設備找到從端藍牙設備后,與從端藍牙設備進行配對,此時需要輸入從端設備的PIN碼,也有設備不需要輸入PIN碼。配對完成后,從端藍牙設備會記錄主端設備的信任信息,此時主端即可向從端設備發起呼叫,已配對的設備在下次呼叫時,不再需要重新配對。已配對的設備,做為從端的藍牙耳機也可以發起建鏈請求,但做數據通訊的藍牙模塊一般不發起呼叫。鏈路建立成功后,主從兩端之間即可進行雙向的數據或語音通訊。在通信狀態下,主端和從端設備都可以發起斷鏈,斷開藍牙鏈路。
3?藍牙一對一的串口數據傳輸應用
藍牙數據傳輸應用中,一對一串口數據通訊是最常見的應用之一,藍牙設備在出廠前即提前設好兩個藍牙設備之間的配對信息,主端預存有從端設備的PIN碼、地址等,兩端設備加電即自動建鏈,透明串口傳輸,無需外圍電路干預。一對一應用中從端設備可以設為兩種類型,一是靜默狀態,即只能與指定的主端通信,不被別的藍牙設備查找;二是開發狀態,既可被指定主端查找,也可以被別的藍牙設備查找建鏈。
?
四.Android與BLE
1.關鍵概念:
Generic Attribute Profile (GATT)
通過BLE連接,讀寫屬性類小數據的Profile通用規范。現在所有的BLE應用Profile都是基于GATT的。
?
Attribute Protocol (ATT)
GATT是基于ATTProtocol的。ATT針對BLE設備做了專門的優化,具體就是在傳輸過程中使用盡量少的數據。每個屬性都有一個唯一的UUID,屬性將以characteristics?and?services的形式傳輸。
?
Characteristic
Characteristic可以理解為一個數據類型,它包括一個value和0至多個對次value的描述(Descriptor)。
?
Descriptor
對Characteristic的描述,例如范圍、計量單位等。
?
Service
Characteristic的集合。例如一個service叫做“Heart Rate Monitor”,它可能包含多個Characteristics,其中可能包含一個叫做“heart ratemeasurement"的Characteristic。一個手環可能
?
2.角色和職責:
Android設備與BLE設備交互有兩組角色:
?
中心設備和外圍設備(Central vs. peripheral);
GATT server vs. GATT client.
?
Central vs. peripheral:
中心設備和外圍設備的概念針對的是BLE連接本身。Central角色負責scan advertisement。而peripheral角色負責make advertisement。
?
GATT server vs. GATT client:
這兩種角色取決于BLE連接成功后,兩個設備間通信的方式。
?
舉例說明:
現 有一個活動追蹤的BLE設備和一個支持BLE的Android設備。Android設備支持Central角色,而BLE設備支持peripheral角色。創建一個BLE連接需要這兩個角色都存在,都僅支持Central角色或者都僅支持peripheral角色則無法建立連接。
?
當 連接建立后,它們之間就需要傳輸GATT數據。誰做server,誰做client,則取決于具體數據傳輸的情況。例如,如果活動追蹤的BLE設備需要向 Android設備傳輸sensor數據,則活動追蹤器自然成為了server端;而如果活動追蹤器需要從Android設備獲取更新信息,則 Android設備作為server端可能更合適。
?
?
3權限及feature:
和經典藍牙一樣,應用使用藍牙,需要聲明BLUETOOTH權限,如果需要掃描設備或者操作藍牙設置,則還需要BLUETOOTH_ADMIN權限:
<uses-permissionandroid:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
?
除了藍牙權限外,如果需要BLE feature則還需要聲明uses-feature:
<uses-featureandroid:name="android.hardware.bluetooth_le"android:required="true"/>
?
按時required為true時,則應用只能在支持BLE的Android設備上安裝運行;required為false時,Android設備均可正常安裝運行,需要在代碼運行時判斷設備是否支持BLE feature:
?
// Use this check to determine whether BLE is supportedon the device. Then
// you can selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
? ? Toast.makeText(this, R.string.ble_not_supported,Toast.LENGTH_SHORT).show();
? ? finish();
}
4、啟動藍牙:
在使用藍牙BLE之前,需要確認Android設備是否支持BLE feature(required為false時),另外要需要確認藍牙是否打開。?
如果發現不支持BLE,則不能使用BLE相關的功能。如果支持BLE,但是藍牙沒打開,則需要打開藍牙。
?
打開藍牙的步驟:
?
1、獲取BluetoothAdapter
?
BluetoothAdapter是Android系統中所有藍牙操作都需要的,它對應本地Android設備的藍牙模塊,在整個系統中BluetoothAdapter是單例的。當你獲取到它的示例之后,就能進行相關的藍牙操作了。
?
獲取BluetoothAdapter代碼示例如下:
// Initializes Bluetooth adapter.
final BluetoothManager bluetoothManager =
? ? ? ? (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
?
注:這里通過getSystemService獲取BluetoothManager,再通過BluetoothManager獲取BluetoothAdapter。BluetoothManager在Android4.3以上支持(API level 18)。
?
2、判斷是否支持藍牙,并打開藍牙
?
獲取到BluetoothAdapter之后,還需要判斷是否支持藍牙,以及藍牙是否打開。
如果沒打開,需要讓用戶打開藍牙:
private BluetoothAdapter mBluetoothAdapter;
...
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
? ? Intent enableBtIntent = newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
? ? startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
?
?
5、搜索BLE設備:
通過調用BluetoothAdapter的startLeScan()搜索BLE設備。調用此方法時需要傳入?BluetoothAdapter.LeScanCallback參數。
因此你需要實現?BluetoothAdapter.LeScanCallback接口,BLE設備的搜索結果將通過這個callback返回。
?
由于搜索需要盡量減少功耗,因此在實際使用時需要注意:
?
1、當找到對應的設備后,立即停止掃描;
2、不要循環搜索設備,為每次搜索設置適合的時間限制。避免設備不在可用范圍的時候持續不停掃描,消耗電量。
搜索的示例代碼如下:
| 01 | /** |
| 02 | ?* Activity for scanning and displaying available BLE devices. |
| 03 | ?*/ |
| 04 | public?class?DeviceScanActivity?extends?ListActivity { |
| 05 | ? |
| 06 | ????private?BluetoothAdapter mBluetoothAdapter; |
| 07 | ????private?boolean?mScanning; |
| 08 | ????private?Handler mHandler; |
| 09 | ? |
| 10 | ????// Stops scanning after 10 seconds. |
| 11 | ????private?static?final?long?SCAN_PERIOD =?10000; |
| 12 | ????... |
| 13 | ????private?void?scanLeDevice(final?boolean?enable) { |
| 14 | ????????if?(enable) { |
| 15 | ????????????// Stops scanning after a pre-defined scan period. |
| 16 | ????????????mHandler.postDelayed(new?Runnable() { |
| 17 | ????????????????@Override |
| 18 | ????????????????public?void?run() { |
| 19 | ????????????????????mScanning =?false; |
| 20 | ????????????????????mBluetoothAdapter.stopLeScan(mLeScanCallback); |
| 21 | ????????????????} |
| 22 | ????????????}, SCAN_PERIOD); |
| 23 | ? |
| 24 | ????????????mScanning =?true; |
| 25 | ????????????mBluetoothAdapter.startLeScan(mLeScanCallback); |
| 26 | ????????}?else?{ |
| 27 | ????????????mScanning =?false; |
| 28 | ????????????mBluetoothAdapter.stopLeScan(mLeScanCallback); |
| 29 | ????????} |
| 30 | ????????? |
| 31 | ????} |
| 32 | ? |
| 33 | } |
如果你只需要搜索指定UUID的外設,你可以調用?startLeScan(UUID[], BluetoothAdapter.LeScanCallback)方法。
其中UUID數組指定你的應用程序所支持的GATT Services的UUID。
?
?
BluetoothAdapter.LeScanCallback的實現示例如下:
| 01 | private?LeDeviceListAdapter mLeDeviceListAdapter; |
| 02 | ... |
| 03 | // Device scan callback. |
| 04 | private?BluetoothAdapter.LeScanCallback mLeScanCallback = |
| 05 | ????????new?BluetoothAdapter.LeScanCallback() { |
| 06 | ????@Override |
| 07 | ????public?void?onLeScan(final?BluetoothDevice device,?int?rssi, |
| 08 | ????????????byte[] scanRecord) { |
| 09 | ????????runOnUiThread(new?Runnable() { |
| 10 | ???????????@Override |
| 11 | ???????????public?void?run() { |
| 12 | ???????????????mLeDeviceListAdapter.addDevice(device); |
| 13 | ???????????????mLeDeviceListAdapter.notifyDataSetChanged(); |
| 14 | ???????????} |
| 15 | ???????}); |
| 16 | ???} |
| 17 | }; |
注意:搜索時,你只能搜索傳統藍牙設備或者BLE設備,兩者完全獨立,不可同時被搜索。
?
?
6、連接GATTServer:
兩個設備通過BLE通信,首先需要建立GATT連接。這里我們講的是Android設備作為client端,連接GATT Server。
連接GATT Server,你需要調用BluetoothDevice的connectGatt()方法。此函數帶三個參數:Context、autoConnect(boolean)和BluetoothGattCallback對象。調用示例:
?
mBluetoothGatt = device.connectGatt(this, false,mGattCallback);
?
函數成功,返回BluetoothGatt對象,它是GATT profile的封裝。通過這個對象,我們就能進行GATT Client端的相關操作。BluetoothGattCallback用于傳遞一些連接狀態及結果。
?
BluetoothGatt常規用到的幾個操作示例:
?
connect() :連接遠程設備。
discoverServices() : 搜索連接設備所支持的service。
disconnect():斷開與遠程設備的GATT連接。
close():關閉GATTClient端。
readCharacteristic(characteristic) :讀取指定的characteristic。
setCharacteristicNotification(characteristic,?enabled):設置當指定characteristic值變化時,發出通知。
getServices()?:獲取遠程設備所支持的services。
?
等等。
?
注:
1、某些函數調用之間存在先后關系。例如首先需要connect上才能discoverServices。
2、 一些函數調用是異步的,需要得到的值不會立即返回,而會在BluetoothGattCallback的回調函數中返回。例如 discoverServices與onServicesDiscovered回調,readCharacteristic與 onCharacteristicRead回調,setCharacteristicNotification與onCharacteristicChanged回調等。
?
總結
以上是生活随笔為你收集整理的BLE简介和Android BLE编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android BLE学习(三):编写自
- 下一篇: Android 指纹调试流程(高通、MT