1. 程式人生 > >Android BLE 藍芽學習總結(一):手機作為周邊BluetoothGattServer的實現

Android BLE 藍芽學習總結(一):手機作為周邊BluetoothGattServer的實現

低功耗藍芽的基本概念:
在BLE協議中,有兩個角色,周邊(Periphery)和中央(Central)。周邊是資料的提供者,中央是資料的使用和處理者。在Android SDK裡面,Android4.3以後手機可以作為中央使用;Android5.0以後手機才可以作為周邊使用,即此時的手機可以作為BLE裝置(如可穿戴裝置、手環、智慧鎖、心率測量儀等)來為中央提供資料。
一箇中央可以同時連線多個周邊,但一個周邊某一時刻只能連線一箇中央。
Android BLE SDK的四個關鍵類如下:
1、BluetoothGattServer作為周邊來提供資料,BluetoothGattServerCallback返回周邊的狀態,更通俗的說,當中央有請求時,系統呼叫該抽象類的相應方法傳遞資料給周邊。
2、BluetoothGatt作為中央來使用和處理資料,BluetoohGattCallback返回中央的狀態和周邊提供資料,即周邊反饋的資料通過該抽象類的相應方法傳遞到中央。
該篇文章主要總結手機作為周邊的實現
一、建立一個周邊所需的類,如下圖
這裡寫圖片描述


說明:每個周邊BluetoothGattServer包含多個服務,每個服務包含多個特徵,每個特徵又可以包含多個描述
1、new一個描述:descriptor=new BluetoothGattDescriptor(UUID_DESCRIPTOR,
BluetoothGattCharacteristic.PERMISSION_WRITE);
2、new 一個特徵:characteristicRead=new BluetoothGattCharacteristic(
UUID_CHARREAD,
BluetoothGattCharacteristic.PROPERTY_READ,
3、把描述新增到特徵:characteristicRead.addDescriptor(descriptor);
4、new 一個服務: service=new BluetoothGattService(UUID_SERVER,
BluetoothGattService.SERVICE_TYPE_PRIMARY);
5、把特徵新增到服務:service.addCharacteristic(characteristicWrite);
6、獲取BluetoothManager:mBluetoothManager=(BluetoothManager)
getSystemService(Context.BLUETOOTH_SERVICE);
7、獲取周邊:mBluetoothGattServer=mBluetoothManager.openGattServer(
context,bluetoothGattServerCallback);
8、把服務新增到周邊: mBluetoothGattServer.addService(service);
9、將新增的服務廣播出去,在本人實現的案例中,將initServices()在廣播的回撥方法中呼叫。

二、實現的程式講解
手機作為外設:設定廣播與服務主要涉及的類BluetoothLeAdvertiser與BluetoothGattServer
1、設定廣播,主要操作是BluetoothLeAdvertiser
1.1、獲取BluetoothLeAdvertiser例項:

 private void initialize(){
        if(mBluetoothLeAdvertiser==null){
           mBluetoothManager=(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
            if(mBluetoothManager!=null){
                BluetoothAdapter bluetoothAdapter=mBluetoothManager.getAdapter();
                if(bluetoothAdapter!=null){
                    mBluetoothLeAdvertiser=bluetoothAdapter.getBluetoothLeAdvertiser();
                }else{
                    Toast.makeText(this,"裝置不支援藍芽廣播",Toast.LENGTH_SHORT).show();
                }
            }else{
                Toast.makeText(this,"不支援藍芽",Toast.LENGTH_SHORT).show();
            }
        }
    }

1.2、開始廣播,BluetoothLeAdvertiser.startAdvertising(settings,data,mAdvertiseCallback),開始廣播之前需要準備三個引數
1) AdvertiseSettings:

    private AdvertiseSettings buildAdvertiseSettings(){
        AdvertiseSettings.Builder settingsBuilder=new AdvertiseSettings.Builder();
        settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER);
        settingsBuilder.setTimeout(0);
        return settingsBuilder.build();
    }

2)AdvertiseData

    private AdvertiseData buildAdvertiseData(){
        AdvertiseData.Builder dataBuilder=new AdvertiseData.Builder();
       dataBuilder.setIncludeDeviceName(true);
        return dataBuilder.build();
    }

3)mAdvertiseCallback=new SampleAdvertiseCallback,即廣播成功或者失敗的系統回撥

    private class SampleAdvertiseCallback extends AdvertiseCallback{
    @Override
    public void onStartFailure(int errorCode){
        super.onStartFailure(errorCode);
        Log.d(TAG,"廣播失敗");
        sendFailureIntent(errorCode);
        stopSelf();
    }
    @Override
    public void onStartSuccess(AdvertiseSettings settingsInEffect){
        super.onStartSuccess(settingsInEffect);
        Log.d(TAG,"服務端的廣播成功開啟");
        Log.d(TAG,"BLE服務的廣播啟動成功後:TxPowerLv="+settingsInEffect.getTxPowerLevel()+";mode="+settingsInEffect.getMode()+";timeout="+settingsInEffect.getTimeout());
        initServices(getContext());//該方法是新增一個服務
    }
}

1.3、關閉廣播

 private void stopAdvertising(){
        Log.d(TAG,"服務停止廣播");
        if(mBluetoothLeAdvertiser!=null){
            mBluetoothLeAdvertiser.stopAdvertising(mAdertiseCallback);
            mAdertiseCallback=null;
        }
    }

2、設定服務,
2.1、首先先實現服務的回撥:bluetoohtGattServerCallback,該例項將作為引數

//服務事件的回撥
private BluetoothGattServerCallback bluetoothGattServerCallback=new BluetoothGattServerCallback() {
    //1、首先是連線狀態的回撥
    @Override
    public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
        super.onConnectionStateChange(device, status, newState);
        Log.e(TAG,"連線狀態發生改變,安卓系統回撥onConnectionStateChange:device name="+device.getName()+"address="+device.getAddress()+"status="+status+"newstate="+newState);
    }

    @Override
    public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
        Log.e(TAG,"客戶端有讀的請求,安卓系統回撥該onCharacteristicReadRequest()方法");

        mBluetoothGattServer.sendResponse(device,requestId, BluetoothGatt.GATT_SUCCESS,offset,characteristic.getValue());
    }

    //接受具體位元組,當有特徵被寫入時,回撥該方法,寫入的資料為引數中的value
    @Override
    public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
        super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
        Log.e(TAG,"客戶端有寫的請求,安卓系統回撥該onCharacteristicWriteRequest()方法");

        //特徵被讀取,在該回調方法中回覆客戶端響應成功
        mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,value);

        //處理響應內容
        //value:客戶端傳送過來的資料
        onResponseToClient(value,device,requestId,characteristic);
    }

    //特徵被讀取。當回覆相應成功後,客戶端胡讀取然後觸發本方法
    @Override
    public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
        super.onDescriptorReadRequest(device, requestId, offset, descriptor);

        mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,null);
    }

    //2、其次,當有描述請求被寫入時,回撥該方法,
    @Override
    public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
        super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);

        mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,value);
       // onResponseToClient(value,device,requestId,descriptor.getCharacteristic());
    }

    @Override
    public void onServiceAdded(int status,BluetoothGattService service){
        super.onServiceAdded(status,service);
        Log.e(TAG,"新增服務成功,安卓系統回撥該onServiceAdded()方法");
    }
};

2.2、獲取BluetoothGattServer的例項

   mBluetoothGattServer=mBluetoothManager.openGattServer(context,bluetoothGattServerCallback);

2.3、為裝置新增服務:

     //新增一個服務,該服務有一個讀特徵、該特徵有一個描述;一個寫特徵。
//用BluetoothGattServer新增服務,並實現該類的回撥介面
private void initServices(Context context){
    mBluetoothGattServer=mBluetoothManager.openGattServer(context,bluetoothGattServerCallback);
    BluetoothGattService service=new BluetoothGattService(UUID_SERVER,BluetoothGattService.SERVICE_TYPE_PRIMARY);

    characteristicRead=new BluetoothGattCharacteristic(UUID_CHARREAD,BluetoothGattCharacteristic.PROPERTY_READ,BluetoothGattCharacteristic.PERMISSION_READ);
    BluetoothGattDescriptor descriptor=new BluetoothGattDescriptor(UUID_DESCRIPTOR,BluetoothGattCharacteristic.PERMISSION_WRITE);
    characteristicRead.addDescriptor(descriptor);
    service.addCharacteristic(characteristicRead);

    BluetoothGattCharacteristic characteristicWrite=new BluetoothGattCharacteristic(UUID_CHARWRITE,
            BluetoothGattCharacteristic.PROPERTY_WRITE |BluetoothGattCharacteristic.PROPERTY_READ|BluetoothGattCharacteristic.PROPERTY_NOTIFY,
            BluetoothGattCharacteristic.PERMISSION_WRITE);
    service.addCharacteristic(characteristicWrite);

    mBluetoothGattServer.addService(service);
    Log.d(TAG,"初始化服務成功:initServices ok");
}

相關推薦

Android BLE 學習總結手機作為周邊BluetoothGattServer實現

低功耗藍芽的基本概念: 在BLE協議中,有兩個角色,周邊(Periphery)和中央(Central)。周邊是資料的提供者,中央是資料的使用和處理者。在Android SDK裡面,Android4.3以後手機可以作為中央使用;Android5.0以後手機才可以

android BLE詳細講解

本文主要講解Android低功耗藍芽的api使用以及藍芽掃描、連線、傳送資料、接收資料等一系列操作,本篇結尾有本人封裝的BleLib藍芽庫,非常適合藍芽初學者使用,只需要一行程式碼注入就OK了,而且用法也極其簡單,我會在第二篇中專門講解一下BleLib庫的使用。

android ble開發總結附帶自己專案中提取整理的demo地址

一些基本的知識我就不寫了,很多其他部落格都可以查到。我主要寫幾點我在其他部落格沒有看到的東西以及我在實際開發中遇到的問題。最後我會貼上程式碼的地址。 1.需要設定2個或3個uuid。通常連線裝置後會得

Web伺服器學習總結web伺服器簡介

一、WEB伺服器 1.1、WEB伺服器簡介   1、Web伺服器是指駐留於因特網上某種型別計算機的程式,是可以向發出請求的瀏覽器提供文件的程式。當Web瀏覽器(客戶端)連到伺服器上並請求檔案時,伺服器將處理該請求並將檔案反饋到該瀏覽器上,附帶的資訊會告訴瀏覽器如何檢視該檔案(即檔案型別)。   

ElasticSearch學習總結資訊檢索基礎理論

本系列文章為Elasticsearch 的學習筆記,主要是為了便於日後對於相關知識點的回顧,在內容的範圍以及正確性上可能存在一定出入。另外由於Elasticsearch的發展速度很快,很多特性會隨著版本的演變而發生變化,具體的特性說明,如有疑問請參考對應版本的官方文件。本系列部落格主要基於5

JNDI學習總結JNDI到底是什麼?

首先我們來回顧一下簡單的問題,列在下面第一點。1.我們知道,Java 的執行從 static main 開始,為什麼一定要從 static 方法開始呢?2.在我們知道這個世界上的另外一個地方有一個物件存在而且伺服器也會在我們開始工作前為我們準備好,那麼我該怎麼找到它呢?如果這個物件是我這個類建立的,那麼當然簡

機器學習總結常見的損失函式

這是博主的第一篇部落格,mark一下,希望今後能夠堅持下去。 博主是機器學習菜鳥,將來希望從事機器學習的工作,最近在整理機器學習的知識點,將這些總結的文字以部落格的形式展現出來,一是便於複習,二是分享出來希望能對別人會有一點點幫助。 最近蒐集了一些機器學習常

4.0/BLE協議棧學習筆記

 需要的軟體工具: 1、BLE協議棧(BLE-CC254x-1.4.0) 2、IAR開發軟體(IAR Embedded Workbench8.20.2) 注:1.4.0協議棧使用8.2

無需程式設計,DIY自己智慧小車的Android遙控軟體

 很多熱衷於玩微控制器小車、機器人的童靴,往往也向往著有天能自己編寫一個Android手機的遙控程式,通過自己的手機遙控小車,微控制器程式用C語言或者彙編什麼的都可以容易完成,,無奈要寫一個上位機的Android控制程式就要會java、還要學一點xml知識,對於只學過C

nrf51822 BLE 4.0 低功耗協議 解析

參考文件: 《TI 2013研討會藍芽4.0講解部分PPT 20130508.pdf》重點 《TI_BT-LE-TRAINNING.PDF》 《05_BLE Intro.pdf》 BLE: Bluetooth Low Energy 協議棧結構和配置

Android開發教程——搜尋裝置

Android藍芽功能的開發一直是很多新手頭疼的問題,網上雖然也有很多教程貼,但大多都寫得不全面,不能讓我們真正掌握藍芽開發的基本知識。本教程主要講解搜尋藍芽裝置、藍芽裝置之間的連線和藍芽之間的通訊三個主要模組。掌握了這三個,基本就能進行簡單的藍芽開發了。

android5.1 子系統介紹Android下bluedroid、bluetooth apk介紹

前言本文件主要介紹android平臺下bluetooth的應用層軟體,先介紹bluetooth應用層的框架,接著分別介紹Bluedroid層軟體、Bluetooth應用程式(Bluetooth.apk),Bluetooth framework層,最後完整分析一些藍芽的操作流程。基於android 5.1的平臺

Android學習總結

       前幾天接觸了下安卓,剛開始學習和總結的時候找不到重點在哪,所以翻閱了一下資料,從巨集觀上看下Android到底是個什麼東西。 搭建應用開發環境: 1.Dalvik 虛擬機器 2.SDK

JSON必知必會學習總結

tor lint 沒有 script app 對數 數據交換格式 object 什麽 七月第一周,從學校畢業回來上班的第一周。離開一段時候後,再次回來重新工作,有了很多新的認識,不再是實習時那麽混混沌沌了。每天我自己該做什麽,怎麽做,做到什麽程度更清晰了。除了要去完成我負責

PHP學習總結

encode 什麽 code 解決 new span att 面向對象 反斜杠 》PHP 面向對象 使用parent訪問父類的構造方法(__construct)時一定要為當前類繼承要訪問的構造方法 類的構造方法(__construct)在實例化時直接被加載,靜態方法

Java IO學習總結

file flush writer directory 創建 str java 資源 tab 一、File 類 Java中不管文件還是目錄都可以使用File類操作,File能新建、刪除、重命名文件和目錄,但是不能訪問文件內容本身,訪問文件內容需要使用輸入輸出流。 Fi

JSP學習總結

展示 cat 一起 time server 資源 type div simple 一、JSP的介紹與項目部署 JSP,全稱 Java server page是由Sun公司開發的一種動態生成網頁資源的技術。JSP技術使用java語言作為腳本語言,可以將html元素和java代

JAVA學習總結

產生 java虛擬機 右鍵 分布式系 jdk 問題 功能 地址 輸出 一、Java是什麽? Java 是由 Sun Microsystems 在 1995 年首先發布的編程語言和計算平臺。Java 是一項用於開發應用程序的技術,可以讓 Web 變得更有意思和更實用。有許多應

Linux學習總結 windos環境vmware安裝centos7

color 學習總結 oot 遠程訪問服務 分享圖片 watermark 需要 mage 磁盤大小 1.在這裏我先簡單介紹下虛擬化技術,就是我們通過軟件虛擬化出來一個硬件環境,然後就可以在系統裏面安裝子系統,以來我們避免了裝linux,windos雙系統的麻煩,二來我們可以

webservice學習總結-- WebService相關概念介紹

IT strong 資源 fire 求和 log AC service服務 為什麽 一、WebService是什麽? 基於Web的服務:服務器端整出一些資源讓客戶端應用訪問(獲取數據) 一個跨語言、跨平臺的規範(抽象) 多個跨平臺、跨語言的應用間通信整合的方案(實際)