Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Ficat/EasyBle
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.0.2
Choose a base ref
...
head repository: Ficat/EasyBle
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 12 commits
  • 39 files changed
  • 1 contributor

Commits on Dec 13, 2024

  1. Verified

    This commit was signed with the committer’s verified signature.
    danharrin Dan Harrin
    Copy the full SHA
    7c69120 View commit details

Commits on Jan 3, 2025

  1. update easyble and demo

    Ficat committed Jan 3, 2025
    Copy the full SHA
    0ff8dda View commit details

Commits on Jan 17, 2025

  1. Update version 3.x

    Ficat committed Jan 17, 2025
    Copy the full SHA
    350780e View commit details

Commits on Jan 21, 2025

  1. 1.Fix bugs; 2.Update demo

    Ficat committed Jan 21, 2025
    Copy the full SHA
    f2fe3d6 View commit details
  2. Update demo and README

    Ficat committed Jan 21, 2025
    Copy the full SHA
    6939a63 View commit details

Commits on Jan 22, 2025

  1. Update readme

    Ficat committed Jan 22, 2025
    Copy the full SHA
    36cff52 View commit details
  2. Update readme

    Ficat committed Jan 22, 2025
    Copy the full SHA
    c0beb42 View commit details
  3. Modify readme

    Ficat committed Jan 22, 2025
    Copy the full SHA
    8ff3130 View commit details
  4. Merge pull request #23 from Ficat/easyble_3.x

    Easyble 3.x
    Ficat authored Jan 22, 2025
    Copy the full SHA
    92be6a0 View commit details

Commits on Feb 10, 2025

  1. Upgrade to AGP 7

    Ficat committed Feb 10, 2025
    Copy the full SHA
    3e7e436 View commit details
  2. Merge pull request #24 from Ficat/agp-upgrade

    Upgrade to AGP 7
    Ficat authored Feb 10, 2025
    Copy the full SHA
    0560da5 View commit details
  3. Update readme

    Ficat committed Feb 10, 2025
    Copy the full SHA
    3fba56e View commit details
Showing with 2,673 additions and 1,418 deletions.
  1. +164 −67 README.md
  2. +0 −257 README_CN.md
  3. +1 −1 build.gradle
  4. +353 −0 doc/README_CN.md
  5. +45 −0 doc/README_MORE.md
  6. +40 −0 doc/README_MORE_CN.md
  7. +3 −5 easyble/build.gradle
  8. +0 −26 easyble/src/androidTest/java/com/ficat/easyble/ExampleInstrumentedTest.java
  9. +30 −3 easyble/src/main/AndroidManifest.xml
  10. +104 −21 easyble/src/main/java/com/ficat/easyble/BleDevice.java
  11. +45 −0 easyble/src/main/java/com/ficat/easyble/BleDeviceAccessor.java
  12. +269 −152 easyble/src/main/java/com/ficat/easyble/BleManager.java
  13. +23 −12 easyble/src/main/java/com/ficat/easyble/BleReceiver.java
  14. +8 −6 easyble/src/main/java/com/ficat/easyble/gatt/BleGatt.java
  15. +24 −0 easyble/src/main/java/com/ficat/easyble/gatt/BleGattAccessor.java
  16. +778 −570 easyble/src/main/java/com/ficat/easyble/gatt/BleGattImpl.java
  17. +66 −0 easyble/src/main/java/com/ficat/easyble/gatt/BleHandlerThread.java
  18. +0 −34 easyble/src/main/java/com/ficat/easyble/gatt/bean/CharacteristicInfo.java
  19. +0 −19 easyble/src/main/java/com/ficat/easyble/gatt/bean/ServiceInfo.java
  20. +13 −3 easyble/src/main/java/com/ficat/easyble/gatt/callback/BleCallback.java
  21. +1 −3 easyble/src/main/java/com/ficat/easyble/gatt/callback/BleConnectCallback.java
  22. +92 −0 easyble/src/main/java/com/ficat/easyble/gatt/data/CharacteristicInfo.java
  23. +97 −0 easyble/src/main/java/com/ficat/easyble/gatt/data/ServiceInfo.java
  24. +24 −0 easyble/src/main/java/com/ficat/easyble/scan/BleScanAccessor.java
  25. +73 −84 easyble/src/main/java/com/ficat/easyble/scan/BleScanner.java
  26. +0 −17 easyble/src/test/java/com/ficat/easyble/ExampleUnitTest.java
  27. +1 −1 gradle/wrapper/gradle-wrapper.properties
  28. +3 −3 sample/build.gradle
  29. +1 −0 sample/src/main/AndroidManifest.xml
  30. +75 −35 sample/src/main/java/com/ficat/sample/MainActivity.java
  31. +181 −75 sample/src/main/java/com/ficat/sample/OperateActivity.java
  32. +8 −8 sample/src/main/java/com/ficat/sample/adapter/DeviceServiceInfoAdapter.java
  33. +2 −2 sample/src/main/java/com/ficat/sample/adapter/ScanDeviceAdapter.java
  34. +79 −0 sample/src/main/java/com/ficat/sample/data/ExtraInfo.java
  35. +22 −2 sample/src/main/res/layout/activity_main.xml
  36. +12 −3 sample/src/main/res/values-en-rGB/strings.xml
  37. +12 −3 sample/src/main/res/values-en-rUS/strings.xml
  38. +12 −3 sample/src/main/res/values-zh-rCN/strings.xml
  39. +12 −3 sample/src/main/res/values/strings.xml
231 changes: 164 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# EasyBle
EasyBle is a framework used for android BLE, this framework makes android Ble operation simpler and supports basic BLE operations, besides, it also support batch writing data and multi connection
>The version 1.0.x is no longer maintained , please use or update to the newest version(2.0.x)
EasyBle is a framework used for android BLE, it makes android Ble operation simpler and supports basic BLE operations
>On android12 or higher devices, BLE requires some permissions, please use or update it to the newest version(3.0.x)
[中文文档](https://github.com/Ficat/EasyBle/blob/master/README_CN.md)
[中文文档](doc/README_CN.md)

## Gradle dependency
```gradle
@@ -13,66 +13,80 @@ allprojects {
}
dependencies {
implementation 'com.github.Ficat:EasyBle:v2.0.2'
implementation 'com.github.Ficat:EasyBle:v3.0.1'
}
```

## Usage
The framework uses BleManager to manager BLE
### 1.Check if the device supports BLE and turn on bluetooth
### 1.Check if the device supports BLE, request BLE required permissions and turn on bluetooth.<br>
[See BLE permission details](doc/README_MORE.md)
```java
//check if the device supports BLE
// Check if the device supports BLE
BleManager.supportBle(context);

//is Bluetooth turned on?
// Request BLE permissions. On Android 12 or higher devices, most BLE operations such
// as enabling Bluetooth, notifications, and write/read require these permissions, so
// this step is necessary. You can get all BLE permissions by BleManager#getBleRequiredPermissions().
List<String> permissions = BleManager.getBleRequiredPermissions();
if (list.size() > 0) { // Lower version may not require any permissions
requestPermissions(permissions);
}

// Is Bluetooth turned on?
BleManager.isBluetoothOn();

//If Bluetooth is turned off, you should call BleManager#enableBluetooth() to
//turn on bluetooth with a request dialog, and you will receive the result from
//the method onActivityResult() of this activity
BleManager.enableBluetooth(activity,requestCode);
// If Bluetooth is turned off, you can call BleManager#enableBluetooth() to turn on
// bluetooth with a request dialog, and you will receive the result from the method
// onActivityResult() of this activity. Note that the method requires BLE permissions,
// so do not forget to request it and ensure all permissions have been granted.
boolean requestStart = BleManager.enableBluetooth(activity,requestCode);
if(!requestStart) {
// No BLE permissions or not support BLE
}
```

### 2.Get ble manager and initialization

```java

//scan/connection options is not necessary, if you don't set,
//it will use default config
// Scan or connection option is not necessary, if you don't set, The default
// configuration will be applied
BleManager.ScanOptions scanOptions = BleManager.ScanOptions
.newInstance()
.scanPeriod(10000)
.scanDeviceName(null);

BleManager.ConnectOptions connectOptions = BleManager.ConnectOptions
BleManager.ConnectionOptions connOptions = BleManager.ConnectionOptions
.newInstance()
.connectTimeout(12000);

BleManager bleManager = BleManager
.getInstance()
.setScanOptions(scanOptions)//it is not necessary
.setConnectionOptions(connectOptions)//like scan options
.setScanOptions(scanOptions)
.setConnectionOptions(connOptions)
.setLog(true, "TAG")
.init(this.getApplication());//Context is needed here,do not use Activity,which can cause Activity leak
.init(this.getApplication());//Init() requires context, to avoid memory leak, you'd better use Application instance

```

### 3.Scan
If sdk version >=23, scanning must have location permission,if Android version sdk version >=29(Android10), scanning must have fine location permission(*Manifest.permission.ACCESS_FINE_LOCATION*)
On API23+ or higher devices, scan requires some permissions, so ensure all BLE permissions have been granted.
[How to use BleDevice to carry extra info](doc/README_MORE.md).
```java
bleManager.startScan(new BleScanCallback() {
@Override
public void onLeScan(BleDevice device, int rssi, byte[] scanRecord) {
String name = device.name;
String address = device.address;
String name = device.getName();
String address = device.getAddress();
}

@Override
public void onStart(boolean startScanSuccess, String info) {
if (startScanSuccess) {
//start scan successfully
// Start scan successfully
} else {
//fail to start scan, you can see details from 'info'
// Fail to start scan, you can see details from 'info'
String failReason = info;
}
}
@@ -83,7 +97,7 @@ If sdk version >=23, scanning must have location permission,if Android version
}
});

//start scan with specified scanOptions
// Start scan with specified scanOptions
bleManager.startScan(scanOptions, bleScanCallback);

```
@@ -94,61 +108,71 @@ Once target remote device has been discovered you can use stopScan() to stop sca
```

### 4.Connect
You can connect to remote device by device address or BleDevice object
You can connect to remote device by device address or BleDevice object. Like scan, now connection also requires permissions.
By default, all operation(like connect/notify/read/write/setMtu/readRssi and so on) callbacks run in UI-Thread, but you can select a thread to run them. [How to select a thread to run all operation callbacks](doc/README_MORE.md).
```java

BleConnectCallback bleConnectCallback = new BleConnectCallback() {
@Override
public void onStart(boolean startConnectSuccess, String info, BleDevice device) {
if (startConnectSuccess) {
//start to connect successfully
public void onStart(boolean startSuccess, String info, BleDevice device) {
if (startSuccess) {
// Start to connect successfully
} else {
//fail to start connection, see details from 'info'
String failReason = info;
// Fail to start connection, see details from 'info'
}
}

@Override
public void onFailure(int failCode, String info, BleDevice device) {
if(failCode == BleConnectCallback.FAIL_CONNECT_TIMEOUT){
//connection timeout
}else{
//connection fail due to other reasons
public void onFailure(int failureCode, String info, BleDevice device) {
switch (failureCode) {
case BleCallback.FAILURE_CONNECTION_TIMEOUT:
// Connection timed out
break;
case BleCallback.FAILURE_CONNECTION_CANCELED:
// Connection canceled. Occurred when a connection is in progress,
// but you call disconnect() or disconnectAll().
break;
case BleCallback.FAILURE_CONNECTION_FAILED:
// Connection failed
break;
default:
// Other reason
break;
}

}

@Override
public void onConnected(BleDevice device) {

}
@Override
public void onConnected(BleDevice device) {
// Connection established
}

@Override
public void onDisconnected(String info, int status, BleDevice device) {
@Override
public void onDisconnected(String info, int status, BleDevice device) {

}
}
};

bleManager.connect(bleDevice, bleConnectCallback);
//connect with specified connectOptions
bleManager.connect(bleDevice, connectOptions, bleConnectCallback);

//connect with mac address
// Connect with mac address
bleManager.connect(address, bleConnectCallback);
bleManager.connect(address, connectOptions, bleConnectCallback);

// Second param: Select a specified connection option
// Last param: Select a thread to run all operation callbacks, like connect/notify/read/write
// and so on. If it's null, all callbacks will run in UI-Thread (By default, it's null)
bleManager.connect(bleDevice, connectionOptions, connectCallback, new BleHandlerThread("BleThread"));
```

Use one of the following methods to disconnect from remote device
Call one of the following methods to disconnect from remote device
```java

//disconnect from the specific remote device by BleDevice object
// Disconnect from the remote device by BleDevice object
bleManager.disconnect(bleDevice);

//disconnect from the specific remote device by address
// Disconnect from the remote device by address
bleManager.disconnect(address);

//disconnect all connected devices
// Disconnect all connected devices
bleManager.disconnectAll();
```

@@ -168,20 +192,28 @@ Both notification and indication use the following method to set notification or
}

@Override
public void onFailure(int failCode, String info, BleDevice device) {
switch (failCode) {
case BleCallback.FAIL_DISCONNECTED://connection has disconnected
public void onFailure(int failureCode, String info, BleDevice device) {
switch (failureCode) {
case BleCallback.FAILURE_CONNECTION_NOT_ESTABLISHED:
// Connection is not established yet, or disconnected from the remote device
break;
case BleCallback.FAIL_OTHER://other reason
case BleCallback.FAILURE_SERVICE_NOT_FOUND:
// Service not found in the remote device
break;
default:
case BleCallback.FAILURE_CHARACTERISTIC_NOT_FOUND_IN_SERVICE:
// Characteristic not found in specified service
break;
case BleCallback.FAILURE_NOTIFICATION_OR_INDICATION_UNSUPPORTED:
// Characteristic not support notification or indication
break;
case BleCallback.FAILURE_OTHER:
// Other reason
break;
}

}
});
```
When you want to cancel notification or indication, you can call cancelNotify()
Call cancelNotify() to cancel notification or indication
```java
bleManager.cancelNotify(bleDevice, notifyUuid);
```
@@ -195,13 +227,29 @@ When you want to cancel notification or indication, you can call cancelNotify()
}

@Override
public void onFailure(int failCode, String info, BleDevice device) {

public void onFailure(int failureCode, String info, BleDevice device) {
switch (failureCode) {
case BleCallback.FAILURE_CONNECTION_NOT_ESTABLISHED:
// Connection is not established yet, or disconnected from the remote device
break;
case BleCallback.FAILURE_SERVICE_NOT_FOUND:
// Service not found in the remote device
break;
case BleCallback.FAILURE_CHARACTERISTIC_NOT_FOUND_IN_SERVICE:
// Characteristic not found in specified service
break;
case BleCallback.FAILURE_WRITE_UNSUPPORTED:
// Characteristic not support writing
break;
case BleCallback.FAILURE_OTHER:
// Other reason (like invalid data length and so on, see 'info').
break;
}
}
});
```

if the length of the data you wanna deliver to remote device is larger than MTU(default 20), you can use the following method to write by batch
If the length of the data you wanna deliver to remote device is larger than MTU(default 20), call the following method to write by batch
```java
bleManager.writeByBatch(bleDevice, serviceUuid, writeUuid, data, lengthPerPackage, new BleWriteByBatchCallback() {
@Override
@@ -210,13 +258,60 @@ if the length of the data you wanna deliver to remote device is larger than MTU(
}

@Override
public void onFailure(int failCode, String info, BleDevice device) {
public void onFailure(int failureCode, String info, BleDevice device) {
switch (failureCode) {
case BleCallback.FAILURE_CONNECTION_NOT_ESTABLISHED:
// Connection is not established yet, or disconnected from the remote device
break;
case BleCallback.FAILURE_SERVICE_NOT_FOUND:
// Service not found in the remote device
break;
case BleCallback.FAILURE_CHARACTERISTIC_NOT_FOUND_IN_SERVICE:
// Characteristic not found in specified service
break;
case BleCallback.FAILURE_WRITE_UNSUPPORTED:
// Characteristic not support writing
break;
case BleCallback.FAILURE_OTHER:
// Other reason (like invalid data length, or invalid package length and so on).
break;
}
}
});
```

### 7.Read
```java
bleManager.read(bleDevice, serviceUuid, writeUuid, data, new BleReadCallback() {
@Override
public void onReadSuccess(byte[] data, BleDevice device) {

}

@Override
public void onFailure(int failureCode, String info, BleDevice device) {
switch (failureCode) {
case BleCallback.FAILURE_CONNECTION_NOT_ESTABLISHED:
// Connection is not established yet, or disconnected from the remote device
break;
case BleCallback.FAILURE_SERVICE_NOT_FOUND:
// Service not found in the remote device
break;
case BleCallback.FAILURE_CHARACTERISTIC_NOT_FOUND_IN_SERVICE:
// Characteristic not found in specified service
break;
case BleCallback.FAILURE_READ_UNSUPPORTED:
// Characteristic not support reading
break;
case BleCallback.FAILURE_OTHER:
// Other reason
break;
}
}
});
```

### 7.Destroy
### 8.Destroy
You must call destroy() to release some resources after BLE communication end
```java
bleManager.destroy();
@@ -226,20 +321,22 @@ You must call destroy() to release some resources after BLE communication end
### Other api
|Method|Description|
|------|-----------|
|**read**(BleDevice bleDevice, String serviceUuid, String readUuid, BleReadCallback bleReadCallback)|Read the characteristic data|
|**readRssi**(BleDevice device, BleRssiCallback callback)|Read the remote device rssi(Received Signal Strength Indication)|
|**setMtu**(BleDevice device, int mtu, BleMtuCallback callback)|Set MTU (Maximum Transmission Unit)|
|isScanning()|Is Scanning?|
|isConnected(String address)|Check if the local bluetooth has connected to the remote device|
|isConnecting(String address)|Check if local device is connecting with the remote device|
|getConnectedDevices()|Get connected devices list|
|getDeviceServices(BleDevice device);<br>getDeviceServices(String address)|Get service information which the remote device supports,note that it may return null. you will get a **Map<ServiceInfo, List<CharacteristicInfo>>**<br>ServiceInfo: get service uuid info like *uuid*.<br>CharacteristicInfo: get characteristic info like *uuid* and *property*(readable,writable,notify,indicative).|
|getDeviceServices(BleDevice device);<br>getDeviceServices(String address)|Get service information which the remote device supports,note that it may return null. you will get a **List<ServiceInfo>**<br>ServiceInfo: it contains service uuid and CharacteristicInfo.|
|*supportBle(Context context)*|Check if this device supports ble|
|*isBluetoothOn()*|Check if local bluetooth is enabled|
|*isAddressValid(String address)*|Check if the address is valid|
|*isScanPermissionGranted(Context context)*|Check if the scan-permission is granted|
|*enableBluetooth(Activity activity, int requestCode)*|Turn on local bluetooth, calling the method will show users a request dialog to grant or reject,so you can get the result from Activity#onActivityResult()|
|*toggleBluetooth(boolean enable)*|Turn on or off local bluetooth directly without showing users a request dialog|
|*getBleRequiredPermissions()*|Get all BLE required permissions. Lower version may not require any permissions, so do not forget to check the length of permissionList|
|*allBlePermissionsGranted(Context context)*|Check if all BLE required permissions have been granted|
|*scanPermissionGranted(Context context)*|Check if scan-permission has been granted|
|*connectionPermissionGranted(Context context)*|Check if connection-permission has been granted|
|*enableBluetooth(Activity activity, int requestCode)*|Turn on local bluetooth, calling the method will show users a request dialog to grant or reject,so you can get the result from Activity#onActivityResult().<br>Note that on Android12 or higher devices, this method can work only under the condition that BLE permissions have been granted|
|*toggleBluetooth(boolean enable)*|Turn on or off local bluetooth directly without showing users a request dialog.<br>Note that this method, like *enableBluetooth(Activity activity, int requestCode)*, also requires BLE permissions. In addition, now it may not work on some devices, especially high version devices|
|getScanOptions()|Get the scan option you set or default|
|getConnectOptions()|Get the connection option you set or default|
|getBluetoothGatt(String address)|Get the BluetoothGatt object of specific remote device,it will return null if the connection isn't established|
Loading