BleLibrary.一個簡單的android BLE庫

weixin_33866037發表於2017-12-02

配置:

1.直接將library依賴到專案中

2.gradle配置依賴

compile 'com.jackiepenghe:blelibrary:0.1.0'

3.maven配置依賴

<dependency>
  <groupId>com.jackiepenghe</groupId>
  <artifactId>blelibrary</artifactId>
  <version>0.1.0</version>
  <type>pom</type>
</dependency

4.vy配置依賴

<dependency org='com.jackiepenghe' name='blelibrary' rev='0.1.0'>
  <artifact name='blelibrary' ext='pom' ></artifact>
</dependency>

許可權配置:

<!--藍芽許可權-->
   <uses-permission android:name="android.permission.BLUETOOTH" />
   <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!--BLE許可權-->
    <uses-feature
        android:name="android.hardware.bluetooth_le"
        android:required="true" />
<!-- 5.0以上的手機可能會需要這個許可權 -->
<uses-feature android:name="android.hardware.location.gps" />
<!-- 6.0的手機需要定位許可權許可權 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

判斷裝置本身是否支援BLE:

if(!BleManager.isSupportBle()){
  Log.w(TAG,"裝置不支援BLE");
  return;
}
//裝置支援BLE,繼續執行程式碼

BLE掃描:

//建立化掃描器
BleScanner bleScanner = BleManager.newBleScanner(context);
//呼叫open方法,傳入相關的回撥,並開啟掃描器功能
bleScanner.open(scanList, onScanFindOneNewDeviceListener, 10000, false, onScanCompleteListener);
//開始掃描,掃描的結果在回撥中,掃描的裝置列表會自動新增到上方open函式中的scanList中
bleScanner.startScan();

登出:
一定要記得在activity被銷燬之前,登出掃描器

bleScanner.close();

BLE裝置的連線:

在進行連線之前,一定要檢查是否在AndroidManifest中配置已一個必須的服務!

<service
    android:name="com.jackiepenghe.blelibrary.BluetoothLeService"
    android:enabled="true"
    android:exported="false" />

接下來就是Java程式碼了

//建立聯結器
 BleConnector bleConnector = BleManager.newBleConnector(context);
//設定回撥,在這個回撥中判斷連線成功最為保險
 bleConnector.setOnServicesDiscoveredListener(onServicesDiscoveredListener);
//設定要連線的裝置的地址,併發起連線
private void startConnect() {
        if (bleConnector.checkAndSetAddress(address)) {
            if (bleConnector.startConnect()) {
                LogUtil.w("開始連線");    
            } else {
                LogUtil.w("連線失敗");              
            }
        }
        
     /*if (bleConnector.checkAndSetAddress(address)) {
            //發起連線時傳入true代表斷鏈後自動重連
            if (bleConnector.startConnect(true)) {
                LogUtil.w("開始連線");    
            } else {
                LogUtil.w("連線失敗");              
            }
        }*/
    }

在連線成功之後,就可以獲取裝置的服務列表

List<BluetoothGattService> deviceServices = bleConnector.getServices();

對目標進行資料的傳輸

傳送資料

bleConnector.writeData(serviceUUID,characteristicUUID,value);

獲取資料

bleConnector.readData(serviceUUID,characteristicUUID);

上面的傳送與獲取資料的方法返回的都是boolean型別,代表成功與失敗(其實bleConnector的函式基本上都是返回boolean型別的)

獲取到的資料在回撥中檢視

bleConnector.setOnCharacteristicReadListener(onCharacteristicReadListener);

還有通知

開啟通知:

bleConnector.openNotification(serviceUUID,characteristicUUID);

關閉通知

bleConnector.closeNotification(serviceUUID,characteristicUUID);

通知的回撥

bleConnector.setOnReceiveNotificationListener(onReceiveNotificationListener);

還有其他的很多回撥,可以自己下載原始碼,根據實際需求使用

銷燬

在準備銷燬activity的時候,呼叫close方法。推薦在此處遮蔽super.onBackpressed()方法。

    @Override
    public void onBackPressed() {
        bleConnector.close();
    }

然後在回撥中銷燬activity

BleConnector.OnCloseCompleteListener onCloseCompleteListener;
onCloseCompleteListener = new BleConnector.OnCloseCompleteListener() {
            @Override
            public void onCloseComplete() {
                //ThisActivity.super.onBackPressed();
                finish();
            }
        };
bleConnector.setOnCloseCompleteListener(onCloseCompleteListener);

BLE裝置的繫結(也可以說是配對):

        /*
         * 呼叫繫結的方法(如果需要繫結),否則請直接呼叫連線的方法
         * 注意:如果該裝置不支援繫結,會直接回撥繫結成功的回撥,在繫結成功的回撥中發起連線即可
         * 第一次繫結某一個裝置會觸發回撥,之後再次繫結,可根據繫結時的函式的返回值來判斷繫結狀態,以進行下一步操作
         */
        switch (bleConnector.startBound(address)) {
            case BleConstants.DEVICE_BOND_START_SUCCESS:
                LogUtil.w(TAG, "開始繫結");
                break;
            case BleConstants.DEVICE_BOND_START_FAILED:
                LogUtil.w(TAG, "發起繫結失敗");
                break;
            case BleConstants.DEVICE_BOND_BONDED:
                LogUtil.w(TAG, "此裝置已經被繫結了");
                startConnect();
                break;
            case BleConstants.DEVICE_BOND_BONDING:
                LogUtil.w(TAG, "此裝置正在繫結中");
                break;
            case BleConstants.BLUETOOTH_ADAPTER_NULL:
                LogUtil.w(TAG, "沒有藍芽介面卡存在");
                break;
            case BleConstants.BLUETOOTH_ADDRESS_INCORRECT:
                LogUtil.w(TAG, "藍芽地址錯誤");
                break;
            case BleConstants.BLUETOOTH_MANAGER_NULL:
                LogUtil.w(TAG, "沒有藍芽管理器存在");
                break;
            default:
                LogUtil.w(TAG, "default");
                break;
        }

相關的回撥是:

  //裝置的繫結(也可以說配對)狀態改變後觸發此回撥
        BleInterface.OnDeviceBondStateChangedListener onBondStateChangedListener = new BleInterface.OnDeviceBondStateChangedListener() {
            /**
             * 正在繫結裝置
             */
            @Override
            public void deviceBinding() {

            }

            /**
             * 繫結完成
             */
            @Override
            public void deviceBonded() {
                //發起連線
                startConnect();
            }

            /**
             * 取消繫結或者繫結失敗
             */
            @Override
            public void deviceBindNone() {

            }
        };
        //設定繫結的回撥
         bleConnector.setOnBondStateChangedListener(onBondStateChangedListener);

多連線

首先要在AndroidManifest.xml新增一個服務

<service android:name="com.jackiepenghe.blelibrary.BluetoothMultiService"
  android:enabled="true"
  android:exported="false"/>

獲取多連線的聯結器

BleMultiConnector bleMultiConnectorWeakReference = BleManager.getBleMultiConnector(context);

連線多個裝置

    String device1Address = "00:02:5B:00:15:A4";
    String device2Address = "00:02:5B:00:15:A2";

    //使用預設的回撥連線
//  bleMultiConnector.connect(device1Address);
//  bleMultiConnector.connect(device2Address);

    //斷開後自動連線(此函式呼叫的是系統的API,由系統自動連線裝置)
    bleMultiConnector.connect(device1Address,true);
    bleMultiConnector.connect(device2Address,true);

    //連線時傳入對應的回撥,方便進行操作,通常使用這個就行了
//  bleMultiConnector.connect(device1Address, device1BleCallback);
//  bleMultiConnector.connect(device2Address, device2BleCallback);


    //連線時傳入對應的回撥,方便進行操作,並且在連線斷開之後自動嘗試連線(系統會預設自動去連線該裝置,這是系統自身的重連引數,推薦用這個引數進行重連)
//  bleMultiConnector.connect(device1Address,device1BleCallback,true);
//  bleMultiConnector.connect(device2Address,device2BleCallback,true);

上方的callback是繼承自BaseConnectCallback


public class Device1BleCallback extends BaseConnectCallback {
    private static final String TAG = "Device1BleCallback";

    /**
     * 藍芽連線後無法正常進行服務發現時回撥
     *
     * @param gatt BluetoothGatt
     */
    @Override
    public void onDiscoverServicesFailed(BluetoothGatt gatt) {
        Tool.warnOut(TAG,"onDiscoverServicesFailed");
    }

    /**
     * 藍芽GATT被關閉時回撥
     */
    @Override
    public void onGattClosed() {
        Tool.warnOut(TAG,"onGattClosed");
    }
}

同時連線多個裝置後,如果想要對單獨某一個裝置進行操作

BleDeviceController bleDeviceController =  bleMultiConnectorWeakReference.getBleDeviceController(address);
bleDeviceController.writData(serviceUUID,characteristicUUID,data);
...

在程式退出時或者當前Activity銷燬前close

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        //最好是先清空一下快取
        bleMultiConnectorWeakReference.refreshAllGattCache();
        //關閉所有gatt
        bleMultiConnectorWeakReference.closeAll();
    }
 

特別注意

安卓手機因為系統各個廠家定製的原因,可能會有一些莫名其妙的問題。如:UUID發現後跟裝置本身不一致等。這種問題通常可以通過重啟藍芽解決。但是也有那種頑固無比的手機。如:三星蓋樂世3.這個手機必須要回復出廠設定才能正確發現UUID,原因是:系統記錄了同一個裝置地址的UUID。一旦連線的是同一個地址,UUID第一次發現之後,後續不論怎麼更改裝置的UUID,系統的快取都是不會更新的。對於這種手機,只想說:別用BLE了。沒救了

github傳送門:https://github.com/JackiePenghe/BleSample

相關文章