1 接入说明

1.1 支持环境

环境

兼容范围

备注

软件系统

目标版本: Android API 34
最低版本: Android API 21

支持BLE功能

开发工具

Android Studio

建议使用最新版本

固件SDK

支持Mesh DFU功能的杰理蓝牙产品

建议咨询SDK负责人

1.2 导入配置

1.2.1 依赖库

Important

XXX 为版本号, 请以最新发布版本为准

  1. jl_mesh_dfu_Vx.x.x-release.aar: 杰理Mesh DFU SDK

1.2.2 库导入

  1. build.gradle 方式

implementation fileTree(include: ['*.aar'], dir: 'libs')
  1. build.gradle.kts 方式

implementation(fileTree(Pair("include", "*.aar"), Pair("dir", "libs")))

1.2.3 必要权限

<-- 使用蓝牙权限 --!>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>


    <-- 定位权限,官方要求使用蓝牙或网络开发,需要位置信息 --!>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />


<-- Android 12+ 需要增加蓝牙连接权限 --!>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

1.3 SDK初始化

设备基础控制器: DeviceController ,是所有功能的基础控制类。

public DeviceController(@NonNull Device device, @NonNull IGattProxy gattProxy)

public DeviceController(@NonNull Device device, @NonNull IGattProxy gattProxy, @NonNull SnGenerator snGenerator)

功能接口请参考 3.1   设备控制接口

1.3.1 Device

设备参数配置

public class Device implements Parcelable {

     /**
      * 设备唯一标识
      */
     @NonNull
     private final String mac;
     /**
      * 服务UUID
      */
     @NonNull
     private final ParcelUuid serviceUUID;
     /**
      * 写特征UUID
      */
     @NonNull
     private final ParcelUuid writeUUID;
     /**
      * 通知特征UUID
      */
     @NonNull
     private final ParcelUuid notifyUUID;
     /**
      * 发送命令等待超时。单位是毫秒
      */
     private long cmdTimeout;
     /**
      * 重发命令的次数限制
      */
     private int cmdReSendLimit;

     public Device(@NonNull String mac){}

     public Device(@NonNull String mac, @NonNull UUID serviceUUID,
               @NonNull UUID writeUUID, @NonNull UUID notifyUUID){

               }
}

Important

  1. 公版私有协议服务UUID: 0xBD00

  2. 公版私有协议写特征UUID: 0xBD01

  3. 公版私有协议通知特征UUID: 0xBD02

1.3.2 IGattProxy

GATT代理

public interface IGattProxy {

     /**
      * 设置GATT事件监听器
      *
      * @param listener GattEventListener GATT事件监听器
      */
     void setGattEventListener(GattEventListener listener);

     /**
      * 发送数据
      *
      * @param mac         String 设备地址
      * @param serviceUUID UUID 服务UUID
      * @param writeUUID   UUID 特征UUID
      * @param data        需要发送的数据
      * @param callback    ResultCallback<Boolean> 发送数据结果
      */
     void sendData(@NonNull String mac, @NonNull UUID serviceUUID, @NonNull UUID writeUUID, @NonNull byte[] data,
               ResultCallback<Boolean> callback);
 }

Important

  1. GATT事件监听器, 1.3.2.1   GattEventListener

  2. 结果回调, 1.3.2.2   ResultCallback

1.3.2.1 GattEventListener

GATT事件监听器

public interface GattEventListener {

     /**
      * 回调设备连接状态
      *
      * @param mac    String 设备地址
      * @param status int 设备状态
      */
     void onConnection(@NonNull String mac, @DeviceState int status);

     /**
      * 回调接收到数据
      *
      * @param mac                String 设备地址
      * @param serviceUUID        UUID 主服务UUID
      * @param characteristicUUID UUID 特征UUID
      * @param data               byte[] 数据
      */
     void onDataReceive(@NonNull String mac, @NonNull UUID serviceUUID, @NonNull UUID characteristicUUID, @NonNull byte[] data);

 }

1.3.2.2 ResultCallback

结果回调

public interface ResultCallback<T> {

     /**
      * 回调操作成功
      *
      * @param result 结果信息
      */
     void onSuccess(T result);

     /**
      * 回调操作失败
      *
      * @param code    错误码
      * @param message 错误信息
      */
     void onFailure(int code, String message);
 }

1.4 蓝牙实现

1.4.1 杰理蓝牙连接库实现方式

导入对应的库

  1. jl_bluetooth_connect_Vx.x.x-release.aar: 蓝牙连接相关

  2. jldecryption_vx.x.x.aar: 加密相关

build.gradle配置

dependencies {

 implementation "androidx.room:room-runtime:2.3.0"
 annotationProcessor "androidx.room:room-compiler:2.3.0"

}

示例代码

GattEventListener gattEventListener = null;
DeviceController controller = null;
Context context = null; //上下文,不能为空
String mac = "目标设备的地址"; //设备地址
final BluetoothManager btOp = BluetoothManager.getInstance(); //new BluetoothManager(context); //单例使用
//添加蓝牙事件监听器
btOp.registerBluetoothCallback(new BluetoothEventCallback() {
    @Override
    public void onBleConnection(BluetoothDevice device, int status) {
        if (null == device || controller == null || !device.getAddress().equals(controller.getDevice().getMac())) {
            //无效条件,过滤
            return;
        }
        if (gattEventListener != null) {
            gattEventListener.onConnection(device.getAddress(), status);
        }
        if (status == BluetoothConstant.CONNECT_STATE_DISCONNECT) {
            gattEventListener = null;
            if(null != controller){
                controller.release();
            }
            controller = null;
            //如果不再监听蓝牙事件,就释放监听器
            btOp.unregisterBluetoothCallback(this);
        }
    }

    @Override
    public void onBleDataNotification(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data) {
        if (null == device || controller == null || !device.getAddress().equals(controller.getDevice().getMac())) {
            return;
        }
        if (gattEventListener != null) {
            gattEventListener.onDataReceive(device.getAddress(), serviceUuid, characteristicsUuid, data);
        }
    }
});
//初始化设备控制器
controller = new DeviceController(new Device(mac), new IGattProxy() {
    @Override
    public void setGattEventListener(GattEventListener listener) {
        gattEventListener = listener
    }

    @Override
    public void sendData(@NonNull String mac, @NonNull UUID serviceUUID, @NonNull UUID characteristicUUID, @NonNull byte[] data) {
        final BluetoothDevice device = BluetoothUtil.getRemoteDevice(context, mac);
         if (null == device) {
                DfuConstant.callbackError(TAG, "sendData", callback, ErrorCode.ERR_INVALID_PARAM);
                return;
            }
        btOp.writeDataByBleAsync(device, serviceUUID, writeUUID, data, (device1, serviceUUID1, characteristicUUID, result, data1) -> {
                if (result) {
                    if (null != callback) callback.onSuccess(true);
                } else {
                    DfuConstant.callbackError(TAG, "sendData", callback, ErrorCode.ERR_SEND_DATA_FAILED);
                }
            });
    }
});
controller.addOnDeviceStateCallback(new OnDeviceStateCallback() {
    @Override
    public void onDeviceState(@NonNull String mac, @DeviceState int status) {
        final BluetoothDevice device = BluetoothUtil.getRemoteDevice(context, mac);
        if(null == device) return;
        if (status == Device.STATE_CONNECTED) {
            //初始化成功
            //可以正常操作功能
        } else {
            //初始化失败
            btOp.disconnectBtDevice(device);
        }
    }
});

更多用法

1.4.2 第三方蓝牙库实现方式

实现步骤说明

  1. 实现 蓝牙代理 功能,例如: 发送数据,读取数据等功能

  2. 透传 蓝牙连接状态

  3. 透传 接收到的蓝牙数据

  4. 等待 SDK初始化回调

示例代码

GattEventListener gattEventListener = null;
DeviceController controller = null;
Context context = null; //上下文
String mac = "目标设备的地址"; //设备地址
//初始化设备控制器
controller = new DeviceController(new Device(mac), new IGattProxy() {
    @Override
    public void setGattEventListener(GattEventListener listener) {
        gattEventListener = listener;
    }

    @Override
    public void sendData(@NonNull String mac, @NonNull UUID serviceUUID, @NonNull UUID characteristicUUID, @NonNull byte[] data)) {
        final BluetoothDevice device = BluetoothUtil.getRemoteDevice(context, mac);
        if (null == device) {
            DfuConstant.callbackError(TAG, "sendData", callback, ErrorCode.ERR_INVALID_PARAM);
            return;
        }
        //TODO: 通过第三方蓝牙库实现
    }
});
controller.addOnDeviceStateCallback(new OnDeviceStateCallback() {
    @Override
    public void onDeviceState(@NonNull String mac, @DeviceState int status) {
        if (status == Device.STATE_CONNECTED) {
            //初始化成功
            //可以正常操作功能
        } else {
            //初始化失败
        }
    }
});
//TODO: 监听蓝牙事件
//TODO: 1. 透传蓝牙连接状态
//TODO: 2. 透传接收到的蓝牙数据