深入瞭解Android藍芽Bluetooth——《進階篇》

來源:互聯網
上載者:User

標籤:代碼   指定   封裝   dir   類型   隱式   eclips   sed   情況   

在 深入瞭解Android藍芽Bluetooth——《基礎篇》一篇中我們對藍芽的各個版本的有了一個認識,藍芽版本的曆程及其優劣式介紹。那麼接下來咱們就深入一點繼續開車進入BLE的進及篇章。BLE藍牙裝置串連讀取的順序:

藍芽BLE4.xBLE分為三部分:
  • Service
  • Characteristic
  • Descriptor

    這三部分都用UUID作為唯一識別碼。UUID為這種格式:0000ffe1-0000-1000-8000-00805f9b34fb。比如有3個Service,那麼就有三個不同的UUID與Service對應。這些UUID都寫在硬體裡,我們通過BLE提供的API可以讀取到。

  • 一個BLE終端可以包含多個Service, 一個Service可以包含多個Characteristic,一個Characteristic包含一個value和多個Descriptor,一個Descriptor包含一個Value。Characteristic是比較重要的,是手機與BLE終端交換資料的關鍵,讀取設定資料等操作都是操作Characteristic的相關屬性。

API相關介紹
  • 1.先介紹一下關於藍芽4.0中的一些名詞吧:
    (1)GATT(Gneric Attibute Profile)

    通過ble串連,讀寫屬性類小資料Profile通用的規範。現在所有的ble應用Profile 都是基於GATT

    • (2)ATT(Attribute Protocal) GATT是基於ATT Potocal的ATT針對BLE裝置專門做的具體就是傳輸過程中使用盡量少的資料,每個屬性都有個唯一的UUID,屬性chartcteristics and Service的形式傳輸。
    • (3)Service是Characteristic的集合。
    • (4).Characteristic 特徵類型。

    比如。有個藍芽ble的血壓計。他可能包括多個Servvice,每個Service有包括多個Characteristic

    注意:藍芽ble只能支援Android 4.3以上的系統 SDK>=18

  • 2.以下是開發的步驟:

  • 2.1首先擷取BluetoothManager

  • 2.2擷取BluetoothAdapter
  • 2.3建立BluetoothAdapter.LeScanCallback
  • 2.4.開始搜尋裝置。
  • 2.5.BluetoothDevice 描述了一個藍牙裝置 提供了getAddress()裝置Mac地址,getName()裝置的名稱。
  • 2.6開始串連裝置
  • 2.7串連到裝置之後擷取裝置的服務(Service)和服務對應的Characteristic。
  • 2.8擷取到特徵之後,找到服務中可以向下位機寫指令的特徵,向該特徵寫入指令。
  • 2.9寫入成功之後,開始讀取裝置返回來的資料。
  • 2.10、中斷連線
  • 2.11、資料的轉換方法
大概整體就是如上的步驟。但是也是要具體根據廠家的協議來實現通訊的過程。

那麼具體要怎麼使用呢?我們據需開車往下走。

一.添加許可權

? 和經典藍芽一樣,應用使用藍芽,需要聲明BLUETOOTH許可權,如果需要掃描裝置或者操作藍芽設定,則還需要BLUETOOTH_ADMIN許可權:

<uses-permission android:name="android.permission.BLUETOOTH"/><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

除了藍芽許可權外,如果需要BLE feature則還需要聲明uses-feature:

<uses-feature android: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 supported on 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();}
第一步:開啟藍芽:
  • 1.首先擷取有BluetoothAdapter兩種方式:
private BluetoothManager bluetoothManager;bluetoothManager =   (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);mBluetoothAdapter = bluetoothManager.getAdapter();

或者是:

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

兩行方式都是可以的。

註:這裡通過getSystemService擷取BluetoothManager,再通過BluetoothManager擷取BluetoothAdapter。BluetoothManager在Android4.3以上支援(API level 18)。
- 2.判斷手機裝置是否有藍芽模組

  // 檢查裝置上是否支援藍芽        if (mBluetoothAdapter == null) {            showToast("沒有發現藍芽模組");            return;        }
  • 3.開啟藍牙裝置

    開啟藍牙裝置有兩種方式:

    • 第一種直接簡單暴力不給使用者進行提示:
    if (!mBluetoothAdapter.isEnabled()) {            mBluetoothAdapter.enable();}
    • 第二種直優雅的踐行開啟並且有彈框進行提示,隱式啟動Intent:
    if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);}
  • 4.掃描藍牙裝置

    我這裡是把掃描到的BLE地址存放到List集合中去。這裡我們可以寫一個方法進行封裝一下。

    /***********     * 掃描裝置     ********/    private void scanLeDevice(final boolean enable) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {            if (enable) {                devices.clear();//清空集合                // Stops scanning after a pre-defined scan period.                mHandler.postDelayed(new Runnable() {                    @Override                    public void run() {                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {                            mBluetoothAdapter.stopLeScan(mLeScanCallback);                        }                    }                }, INTERVAL_TIME);                mBluetoothAdapter.startLeScan(mLeScanCallback);            } else {                try {                    mBluetoothAdapter.stopLeScan(mLeScanCallback);                } catch (Exception e) {                }            }        }    }

在這個掃描方法中,我們在AndroidStudio或者是Eclipse中會看到startLeScan方法會有橫線,表明這個方式顯示到期的方法,那麼

如果你只需要搜尋指定UUID的外設,你可以調用 startLeScan(UUID[], BluetoothAdapter.LeScanCallback)方法。
其中UUID數組指定你的應用程式所支援的GATT Services的UUID。

那麼LeScanCallback的初始化代碼如下:

private void initCallBack(){     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {            mLeScanCallback = new BluetoothAdapter.LeScanCallback() {                @Override                public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {                    runOnUiThread(new Runnable() {                        @Override                        public void run() {                            if (device != null) {                                if (!TextUtils.isEmpty(device.getName())) {                                   // devices.add(device);                                    String name = device.getName();                                    if (name.contains(BluetoothDeviceAttr.OYGEN_DEVICE_NAME)) {                                        if (!devices.contains(device)) {                                            devices.add(device);                                        }                                    }                                }                            }                        }                    });                }            };        } else {            getToast("裝置藍芽版本過低");            return;        }}

那麼如果在裝置多的情況下我們講搜出很多的裝置。我們可以選擇我們所需要的地址進行連結。但是這類要注意的是:搜尋時,你只能搜尋傳統藍牙裝置或者BLE裝置,兩者完全獨立,不可同時被搜尋.

  • 5.進行連結裝置
 final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);        if (device == null) {            Log.w(TAG, "Device not found.  Unable to connect.");            return false;        }        // We want to directly connect to the device, so we are setting the autoConnect        // parameter to false.        mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

這裡調用的是device的connectGatt方法

  /**     * Connect to GATT Server hosted by this device. Caller acts as GATT client.     * The callback is used to deliver results to Caller, such as connection status as well     * as any further GATT client operations.     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct     * GATT client operations.     * @param callback GATT callback handler that will receive asynchronous callbacks.     * @param autoConnect Whether to directly connect to the remote device (false)     *                    or to automatically connect as soon as the remote     *                    device becomes available (true).     * @throws IllegalArgumentException if callback is null     */    public BluetoothGatt connectGatt(Context context, boolean autoConnect,                                     BluetoothGattCallback callback) {        return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO));    }

?api中闡述的是第一個參數是內容物件Context,第二個參數是是否自動連接,第三個是藍芽的GattCallback回調。

private BluetoothGattCallback GattCallback = new BluetoothGattCallback() {    // 這裡有9個要實現的方法,看情況要實現那些,用到那些就實現那些    //當串連狀態發生改變的時候    @Override    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState){    };    //回調響應特徵寫操作的結果。    @Override    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status){    };    //回調響應特徵讀操作的結果。    @Override    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {    }    //當服務被發現的時候回調的結果    @Override    public void onServicesDiscovered(BluetoothGatt gatt, int status) {    }    當串連能被被讀的操作    @Override   public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {            super.onDescriptorRead(gatt, descriptor, status);      }      ......};

?串連的過程我們一個通過service來進行串連,也可以在activity中進行操作。
好,到此為止,一個BLE藍芽串連裝置的整個流程我們已經清楚完畢。

Android4.x的藍芽不太成熟性

?但是在實際操作過程中難免會出現一些比較坑人的問題。比如我用一個地址進行藍牙裝置串連,偶爾會出現藍芽串連不上或者是說串連上裝置後不返回資料等問題。那麼此時我們可能會重啟一下藍芽或手機就立馬有成功了。此時我們千萬不能蒙蔽,也不要懷疑自己的人生。這是因為Android4.x的藍芽還是不太成熟。目前可以來說是個測試階段。
* 手機可能會搜尋不到藍牙裝置
* 有時候會在廣播中接收不到資料
* 出現異常需要重新啟動手機或者是重啟才能恢複正常

這個時候我們怎麼辦呢?

此時不要抱怨什麼,難到我們作為Android程式員就註定如此的苦逼嗎?

答案是否定的。

如何去最佳化呢?那麼我們就應該從UI介面,使用者體驗上進行操作來實現
* 做一個定時器,如果在在確定藍牙裝置一開啟並且存在的情況系,可以在手機搜尋5s內沒有搜尋到藍牙裝置時重啟藍芽,並且在廣播中接收到藍芽開啟後再次搜尋
* 可以在UI上進行對使用者進行相對應的提示
- 當藍芽為啟動時,提示使用者去開啟器藍芽
- 當藍芽開啟後,在處在開啟狀態後,提示使用者藍芽正在開啟…
- 藍芽已開啟,裝置並沒有串連上,提示使用者去進行串連
- 裝置正在串連上手機,提示使用者,正在串連,請等待…
- 藍牙裝置串連上手機,正在讀取,提示資料正在讀取中…

我們不能子在Android系統上來操作什麼,我們在體驗上做到了我們能做的就可以的。
手機藍芽串連BLE裝置要求
  • 手機Android 4.3以上的系統 SDK>=18
  • 藍芽版本>=4.0

學習參考道demo:
https://github.com/androidstarjack/Bluetooth_4.3-master

學到這裡,關於AndroidBLE藍芽串連我們已經基本上實現了藍芽的搜尋,串連,讀取等。

大家項目中如果經常涉及到硬體比如手環,溫度計,汗液儀,心電圖,血壓計等這些ble的藍牙裝置,就一定會用到藍相關方面的知識。這裡筆者先給大家提前踩一下坑,進行了總結,為後面的小夥伴在研究藍芽方面盡量的少踩一些坑。如多對藍芽的曆程還未有清楚的認識,請參考深入瞭解Android藍芽Bluetooth4.0——《基礎篇》。

如果你覺得此文對您有所協助,歡迎入群 QQ交流群 :232203809 ??
公眾號:終端研發部

(歡迎關注學習和交流)

深入瞭解Android藍芽Bluetooth——《進階篇》

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.