项目作者: a1anwang

项目描述 :
An easy-to-use BLE library for android. 简单易用的android BLE library
高级语言: Java
项目地址: git://github.com/a1anwang/okble.git


okble: An easy-to-use BLE library for Android

中文 | English

Summary

BLE has two parts:Center & Peripheral. When we develop an android app,the most used is Center. Using Center-API to connect with Peripheral, and then communicate each other. For example, app can read battery level of a wristband, also app can control the bluetooth-light on/off.

Center

Center usually has three parts:Scan, Connect, Communicate. Communicate means swap data with Peripheral using method like Read, Write, Notify/Indicate. We use Read to get the data from Peripheral(for example, read battery level of a wristband). We use Write to send data to Peripheral(for example, send a turn-off command to turn the bluetooth-light off). Notify/Indicate can help us receive the data which Peripheral uploaded(for example, the wristband uploads heart rate value every second, app can show a heart rate spectrum by receiving the value continuously). As we can see, it makes a bidirectional communication.

Peripheral

We could think that Peripheral is a hardware device, it works to provide data. We use little in developing android apps. In android5.0, google add some APIs about Peripheral so that we can make an android device to be a Peripheral. We can use two android phones to develop BLE app nicely. So easy! Mom doesn’t have to worry about no Peripheral any more。Using Peripheral API, we can do a lot, for example chatting by BLE(there is a chatting demo using Classic Bluetooth in google samples), change an android device to an iBeacon.

okble help us achieve the above functions easily

Demo

Download APK-Demo

Features

  • Clear and easy to use, for all of BLE communications you just need an OKBLEDevice.
  • OKBLE use a queue to manager BLE operation, you can read/write/notify/indicate every where and every time, you can diy operation overtime.
  • Dynamic permissions included, there is a scan callback showing whether the location permission is granted in target sdk 23 or above.
  • minimum support API 18(android4.3)
  • Double listeners,more smart: a global listener to monitor Peripheral status, a solely listener for each BLE operation.
  • Auto reconnect: the auto-reconnect works continuously until connect successfully.
  • Easy use for multi-Peripheral
  • Support simulating a Peripheral, Support simulating an iBeacon.
  • Support scanning iBeacon, Support Monitoring enter/exit iBeacon region.

Usage

Add a gradle dependency

  1. repositories {
  2. jcenter()
  3. maven { url "https://jitpack.io" }
  4. }
  5. dependencies {
  6. implementation 'com.github.a1anwang:okble:1.1.3'
  7. }

Scan Peripheral

  1. OKBLEScanManager scanManager=new OKBLEScanManager(this);
  2. scanManager.setScanCallBack(scanCallBack);
  3. DeviceScanCallBack scanCallBack=new DeviceScanCallBack() {
  4. @Override
  5. public void onBLEDeviceScan(BLEScanResult device, int rssi) {
  6. LogUtils.e(" scan:"+device.toString());
  7. }
  8. @Override
  9. public void onFailed(int code) {
  10. switch (code){
  11. case DeviceScanCallBack.SCAN_FAILED_BLE_NOT_SUPPORT:
  12. Toast.makeText(mContext,"the android deice do not support BLE",Toast.LENGTH_SHORT).show();
  13. break;
  14. case DeviceScanCallBack.SCAN_FAILED_BLUETOOTH_DISABLE:
  15. Toast.makeText(mContext,"please enable the bluetooth",Toast.LENGTH_SHORT).show();
  16. break;
  17. case DeviceScanCallBack.SCAN_FAILED_LOCATION_PERMISSION_DISABLE:
  18. Toast.makeText(mContext,"Location Authority has been rejected.",Toast.LENGTH_SHORT).show();
  19. break;
  20. case DeviceScanCallBack.SCAN_FAILED_LOCATION_PERMISSION_DISABLE_FOREVER:
  21. Toast.makeText(mContext,"Location Authority has been rejected forever.",Toast.LENGTH_SHORT).show();
  22. break;
  23. }
  24. }
  25. @Override
  26. public void onStartSuccess() {
  27. }
  28. };

Connect to Peripher

  1. OKBLEDevice okbleDevice=new OKBLEDeviceImp(mContext,bleScanResult);
  2. //okbleDevice=new OKBLEDeviceImp(mContext);
  3. //okbleDevice.setBluetoothDevice(mBluetoothDevice);
  4. okbleDevice.addDeviceListener(this);
  5. okbleDevice.connect(true);//true means OKBLE will auto reconnect to the Peripheral if the connection is disconnected.

APP disconnect forwardly

  1. okbleDevice.disConnect(false); //false means don't need the auto-reconnect function provided by OKBLE after disconnect;after disconnect, you can use okbleDevice.connect() to reconnect.

APP clear the connection

  1. okbleDevice.remove(); //remove will clear the connection completely; if you want to reconnect, make sure use setBleScanResult/setBluetoothDevice to set Peripheral before okbleDevice.connect();

Communicate

Read
  1. okbleDevice.addReadOperation("feea", new BLEOperation.ReadOperationListener() {
  2. @Override
  3. public void onReadValue(final byte[] value) {
  4. runOnUiThread(new Runnable() {
  5. @Override
  6. public void run() {
  7. addLog("onReadValue:"+ OKBLEDataUtils.BytesToHexString(value)+" ("+new String(value)+")");
  8. }
  9. });
  10. }
  11. @Override
  12. public void onFail(int code, final String errMsg) {
  13. runOnUiThread(new Runnable() {
  14. @Override
  15. public void run() {
  16. addLog("read onFail:"+ errMsg);
  17. }
  18. });
  19. }
  20. @Override
  21. public void onExecuteSuccess(BLEOperation.OperationType type) {
  22. }
  23. });
Write
  1. okbleDevice.addWriteOperation("feea",value,new BLEOperation.WriteOperationListener() {
  2. @Override
  3. public void onWriteValue(final byte[] byteValue) {
  4. runOnUiThread(new Runnable() {
  5. @Override
  6. public void run() {
  7. addLog(" onWriteValue:"+value);
  8. }
  9. });
  10. }
  11. @Override
  12. public void onFail(int code, final String errMsg) {
  13. runOnUiThread(new Runnable() {
  14. @Override
  15. public void run() {
  16. addLog("write onFail:"+errMsg);
  17. }
  18. });
  19. }
  20. @Override
  21. public void onExecuteSuccess(BLEOperation.OperationType type) {
  22. runOnUiThread(new Runnable() {
  23. @Override
  24. public void run() {
  25. addLog("write value execute success");
  26. }
  27. });
  28. }
  29. });
Notify/Indicate
  1. okbleDevice.addNotifyOrIndicateOperation("feea", true, new BLEOperation.NotifyOrIndicateOperationListener() {
  2. @Override
  3. public void onNotifyOrIndicateComplete() {
  4. runOnUiThread(new Runnable() {
  5. @Override
  6. public void run() {
  7. addLog("onNotifyOrIndicateComplete");
  8. }
  9. });
  10. }
  11. @Override
  12. public void onFail(int code, final String errMsg) {
  13. runOnUiThread(new Runnable() {
  14. @Override
  15. public void run() {
  16. addLog("NotifyOrIndicate onFail:"+ errMsg);
  17. }
  18. });
  19. }
  20. @Override
  21. public void onExecuteSuccess(BLEOperation.OperationType type) {
  22. }
  23. });
Write big data(for example:OAD)

Exactly, OAD’s principle is load byte[] from firmware file(like .bin), then send byte[] segmentations to Peripheral. The following code shows how to send byte[] segmentations, some details is hidden(like how to package each segmentation),because different products have different demands.

  1. final int sendInterval=50;//interval of each package; you may set 80-100 for some android phones, beacuse too fast ,too higher failure rate;
  2. okbleDevice.setOperationInterval(sendInterval);
  3. byte[] oadValues=loadBytesFromFile(filePath);
  4. final int blockSize=20;//one package contains 20 bytes
  5. final int blockCount= (int) Math.ceil(oadValues.length*1.0f/blockSize);//the total package count
  6. percent=0;
  7. for (int i=0;i<blockCount;i++){
  8. byte[] value=new byte[blockSize];
  9. System.arraycopy(oadValues,i*blockSize,value,0,blockSize);
  10. okbleDevice.addWriteOperation(OAD_WRITE_UUID, value, new OKBLEOperation.WriteOperationListener() {
  11. @Override
  12. public void onWriteValue(byte[] value) {
  13. percent++;
  14. float progress=percent*1.0f/blockCount;
  15. int leftSeconds= (int) ((sendInterval*blockCount)/1000*(1-progress));
  16. Log.e("TAG"," OAD progress:"+progress+" time left:"+leftSeconds +" seconds.");
  17. }
  18. @Override
  19. public void onFail(int code, String errMsg) {
  20. Log.e("TAG"," OAD failed");
  21. okbleDevice.clearOperations();
  22. break;
  23. }
  24. @Override
  25. public void onExecuteSuccess(OKBLEOperation.OperationType type) {
  26. }
  27. });
  28. }

APP simulates a Peripheral (scanable and connectable)

  1. OKBLEAdvertiseManager okbleAdvertiseManager;
  2. OKBLEServerDevice serverDevice;
  3. okbleAdvertiseManager=new OKBLEAdvertiseManager(this);
  4. serverDevice=new OKBLEServerDeviceImp(this);
  5. OKBLEAdvertiseSettings settings= new OKBLEAdvertiseSettings.Builder().setConnectable(true).build();
  6. OKBLEAdvertiseData data=new OKBLEAdvertiseData.Builder().setIncludeDeviceName(true).build();
  7. //start advertising
  8. okbleAdvertiseManager.startAdvertising(settings, data, new OKBLEAdvertiseCallback() {
  9. @Override
  10. public void onStartSuccess() {
  11. LogUtils.e("---onStartSuccess ---");
  12. Toast.makeText(mContext,"Advertising Success",Toast.LENGTH_SHORT).show();
  13. configServer();//config service 和characteristic
  14. }
  15. @Override
  16. public void onStartFailure(int errorCode, String errMsg) {
  17. LogUtils.e("---onStartFailure errMsg:"+errMsg);
  18. Toast.makeText(mContext,"Advertising Failed:"+errMsg,Toast.LENGTH_LONG).show();
  19. }
  20. });
  21. private void configServer(){
  22. OKBLEServiceModel serviceModel=new OKBLEServiceModel(CommonUUIDUtils.createCompleteUUIDByShortUUID("fff0"));
  23. OKBLECharacteristicModel characteristicModel=new OKBLECharacteristicModel(CommonUUIDUtils.createCompleteUUIDByShortUUID("fff1"));
  24. characteristicModel.setCanWrite(true);
  25. characteristicModel.setCanNotify(true);
  26. characteristicModel.setCanRead(true);
  27. OKBLECharacteristicModel characteristicModel_2=new OKBLECharacteristicModel(CommonUUIDUtils.createCompleteUUIDByShortUUID("fff2"));
  28. characteristicModel_2.setCanWriteNoResponse(true);
  29. List<OKBLECharacteristicModel> characteristicModels=new ArrayList<>();
  30. characteristicModels.add(characteristicModel);
  31. characteristicModels.add(characteristicModel_2);
  32. serverDevice.addCharacteristic(characteristicModels, serviceModel, new OKBLEServerOperation.BLEServerOperationListener() {
  33. @Override
  34. public void onAddCharacteristicFailed(int errorCode, String errorMsg) {
  35. LogUtils.e("onAddCharacteristicFailed:"+errorMsg );
  36. }
  37. @Override
  38. public void onAddCharacteristicSuccess() {
  39. LogUtils.e("onAddCharacteristicSuccess");
  40. }
  41. });
  42. }

Scan iBeacon

  1. OKBLEBeaconScanManager scanManager;
  2. scanManager=new OKBLEBeaconScanManager(this);
  3. scanManager.setBeaconScanCallback(scanCallBack);
  4. OKBLEBeaconScanManager.OKBLEBeaconScanCallback scanCallBack=new OKBLEBeaconScanManager.OKBLEBeaconScanCallback() {
  5. @Override
  6. public void onScanBeacon(OKBLEBeacon beacon) {
  7. Log.e("TAG"," scan beacon:"+beacon.toString());
  8. }
  9. };

APP simulates an iBeacon

  1. OKBLEBeBeaconManager beBeaconManager;
  2. beBeaconManager=new OKBLEBeBeaconManager(this);
  3. beBeaconManager.setOKBLEBeBeaconListener(startBeaconListener);
  4. String uuid ="12345678-1234-1234-1234-1234567890ab";
  5. int major=1;
  6. int minor=2;
  7. beBeaconManager.startIBeacon(uuid,major,minor);
  8. OKBLEBeBeaconManager.OKBLEStartBeaconListener startBeaconListener=new OKBLEBeBeaconManager.OKBLEStartBeaconListener() {
  9. @Override
  10. public void onStartSuccess() {
  11. Toast.makeText(mContext,"start success",Toast.LENGTH_SHORT).show();
  12. }
  13. @Override
  14. public void onStartFailure(String errMsg) {
  15. Toast.makeText(mContext,"start failed:"+errMsg,Toast.LENGTH_SHORT).show();
  16. }
  17. };

Monitor enter/exit iBeacon region

  1. OKBLEBeaconManager beaconManager=new OKBLEBeaconManager(this);
  2. beaconManager.setRegionListener(this);
  3. String uuid ="12345678-1234-1234-1234-1234567890ab";
  4. int major=1;
  5. int minor=2;
  6. OKBLEBeaconRegion okbleBeaconRegion=OKBLEBeaconRegion.getInstance(uuid,major,minor);
  7. //OKBLEBeaconRegion okbleBeaconRegion=OKBLEBeaconRegion.getInstance(uuid,major);
  8. //OKBLEBeaconRegion okbleBeaconRegion=OKBLEBeaconRegion.getInstance(uuid);
  9. beaconManager.startMonitoringForRegion(okbleBeaconRegion);
  10. @Override
  11. public void onEnterBeaconRegion(OKBLEBeaconRegion beaconRegion) {
  12. }
  13. @Override
  14. public void onExitBeaconRegion(OKBLEBeaconRegion beaconRegion) {
  15. }

Discuss

Contact me: admin@a1anwang.com

License

Copyright 2018 a1anwang

Licensed under the Apache License, Version 2.0 (the “License”);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.