Android中使用BluetoothKit

最近接觸到了和硬件之間的藍牙交互,有一套Google給的代碼,總來的說使用起來太過冗長,封裝過程略微複雜。找到一個三方的框架BluetoothKit.

這個藍牙框架使用起來較爲簡單。使用方法也較爲簡潔明瞭。但是BluetoothKit不能用在經典藍牙身上,它只支持經典藍牙的SPP搜索,並不能支持經典藍牙的連接。而它只支持BLE設備的操作。

  • GATT協議

    在Android4.3(API 18)以上的設備幾乎都是BLE。BLE的協議是GATT協議,關於GATT協議,我們需要了解幾個關鍵的詞彙:

    ①Profile:一個標準的通信協議,存在於從機中,藍牙有一些規範的Profile,如:HID(人機交互設備),OVER(基於藍牙的IPV6組網方式),心率計等。每個Profile中會包含多個Service,每個Service代表從機的一個能力。

    ②Service:在Ble從機中,有很多服務,比如:電量信息服務,系統信息服務等。一個service包含多個characteristic特徵值。獲取的信息值存放在從機的Profile的Characteristic。然後主機通過characteristic來獲取信息數據。所以說,通信最主要的還是Characteristic。

    ③Characteristic:特徵。讀寫內容都是通過Characteristic來進行的。

    ④UUID:統一標識碼,Service和Characteristic都有自己的唯一UUID。

    藍牙協議圖大致如下:

 

  • BluetoothKit框架的一些介紹和使用方法

       BluetoothKit提供:連接,讀寫,通知等接口。

       會自動斷開不活躍的藍牙設備。

 

       BluetoothKit的使用方法:

1.添加依賴  兩種方式: ①在gradle中添加compile 'com.inuker.bluetooth:library:1.3.8'   ②導入依賴Library模塊

2.添加藍牙權限

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

 

3.掃描藍牙

private void searchDevice() {
        SearchRequest request = new SearchRequest.Builder().searchBluetoothLeDevice(5000,2).searchBluetoothLeDevice(5000).build();
        ClientManager.getClient().search(request, mSearchResponse);
    }

    private final SearchResponse mSearchResponse = new SearchResponse() {
        @Override
        public void onSearchStarted() {
                 //開始掃描,可以在此加入一些狀態設置。以及一些數據清空處理。
                 mDevices.clear();
        }

        @Override
        public void onDeviceFounded(SearchResult device) {
            //監測掃描出的設備是否已經包含在設備數組裏
            if (!mDevices.contains(device)) {
                mDevices.add(device);
                //給設備Adapter設值
                mAdapter.setDataList(mDevices);
            }

            if (mDevices.size() > 0) {
                mRefreshLayout.showState(AppConstants.LIST);
            }
        }

        @Override
        public void onSearchStopped() {
            BluetoothLog.w("MainActivity.onSearchStopped");
            mListView.onRefreshComplete(true);
            mRefreshLayout.showState(AppConstants.LIST);
        }

        @Override
        public void onSearchCanceled() {
            BluetoothLog.w("MainActivity.onSearchCanceled");
            mListView.onRefreshComplete(true);
            mRefreshLayout.showState(AppConstants.LIST);
        }
    };

 

4.連接藍牙

 private void connectDevice() {
        BleConnectOptions options = new BleConnectOptions.Builder()
                .setConnectRetry(3)//重試3次
                .setConnectTimeout(5000)//5s後爲連接超時
                .setServiceDiscoverRetry(3)//連接Service重試3次
                .setServiceDiscoverTimeout(5000)//5s後連接'服務'超時
                .build();
        //此處單例出BluetoothClient對象來進行連接操作
        ClientManager.getClient().connect(mMac, options, new BleConnectResponse() {
            @Override
            public void onResponse(int code, BleGattProfile profile) {
                //如果連接沒有成功,則重試。
                if (code == REQUEST_SUCCESS) {
                    setGattProfile(profile);
                }else{
                    //檢測是否需要連接設備(如果已經連接,則不需要再去連接)
                    connectDeviceIfNeeded();
                }
            }
        });
 }

//獲取屬性
public void setGattProfile(BleGattProfile profile) {
        List<DetailItem> items = new ArrayList<DetailItem>();
        List<BleGattService> services = profile.getServices();

        for (BleGattService service : services) {
            items.add(new DetailItem(DetailItem.TYPE_SERVICE, service.getUUID(), service.getUUID()));
            List<BleGattCharacter> characters = service.getCharacters();
            for (BleGattCharacter character : characters) {
                items.add(new DetailItem(DetailItem.TYPE_CHARACTER, character.getUuid(), service.getUUID()));
            }
        }
        //將得到的items傳遞到需要發送信息的位置。DetailItem是service和character的實體。
        //上面我們就提到過,藍牙間的消息傳遞獲取是根據service的character來做到的。
}

//藍牙的狀態監聽
ClientManager.getClient().registerConnectStatusListener(macAddress, mBleConnectStatusListener);
private final BleConnectStatusListener mBleConnectStatusListener = new BleConnectStatusListener() {
    @Override
    public void onConnectStatusChanged(String macAddress, int status) {

        if (status == STATUS_CONNECTED) {
        //藍牙設備處於連接狀態
        } else if (status == STATUS_DISCONNECTED) {
        //藍牙設備斷開
        }

    }
};

//註銷藍牙狀態監聽
ClientManager.getClient().unregisterConnectStatusListener(macAddress, mBleConnectStatusListener);

 

5.藍牙硬件通信

private List<DetailItem> mDeviceDetailDataList = new ArrayList<>();
public void setDeviceDetailDataList(List<DetailItem> datas) {
        mDeviceDetailDataList.clear();
        //加入最新的service和character數據
        mDeviceDetailDataList.addAll(datas);
        BaseLoginBean baseLoginBean=loginCheck(mDeviceDetailDataList);
        mService=baseLoginBean.getmService();
        mCharacter=baseLoginBean.getmCharacter();
        //寫數據到藍牙設備。需要得知要操作設備的mac,要操作的service和character,
        //以及要傳輸給藍牙設備的信息。以及傳輸回調。
        ClientManager.getClient().write(macAddress, mService, mCharacter, baseLoginBean.getmBytes(), mWriteRsp);
        //將藍牙設備傳遞給我們的信息進行提示返回。需要得知要操作設備的mac,
        //要操作的service和character,以及返回的信息回調。
        ClientManager.getClient().notify(mMac, mService, mCharacter, mNotifyRsp);
}

在讀取的時候還有一種read方法。read方法和notify有什麼不一樣的呢?

notify:有點類似於推送的意思,不管自己去不去讀取藍牙返回給我們的信息。始終都會得到藍牙返回給的信息。

unnotify:不獲取返回信息。

read:用戶自己去獲取數據,自己要獲取的時候纔去獲取數據。

除此writeNoRsp:凡是帶有WRITE_TYPE_NO_RESPONSE標識的,速率比write快2~3倍。建議用於固件升級。

writeDescriptor:對Characteristic的描述,如:範圍,計量單位等。同理readDescriptor則是讀取。

indicate:和notify類似。 unindicate則是不獲取返回信息。

readRssi:讀取藍牙強度。                                              

 6.斷開藍牙

ClientManager.getClient().disconnect(macAddress);

Tips:

1.在某個藍牙設備disconnect()後,再去調用該藍牙的disconnect。依然會執行到藍牙狀態回調去。

2.使用notify的時候最好不要在一個界面去複用多次,可能會出現重複調用情況,導致notify回調邏輯混亂。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章