## MinewESLKit说明文档

本套SDK仅支持Minew公司出品的蓝牙ESL设备。通过SDK可以帮助开发者处理手机和ESL之间的一切工作，包括：扫描设备，连接设备，向设备写入数据，从设备接收数据等。

MinewESLKit兼容AppCompat或androidx

### 前期工作

整体框架：MinewTagBleManager为设备管理类，在APP运行时始终是单例。TagInfo是设备实例类，此套件会为每一个设备生成一个TagInfo实例，内部包含设备广播数据，该数据会随着设备不停广播而更新。

`MinewTagBleManager`：设备管理类，可以扫描周围的ESL设备，并且可以连接它们，校验它们等；

`TagInfo`：扫描时获取到的设备实例，作为在扫描阶段时期使用；

`TagModule`：在开始去连接时就能获取到，作为连接设备的实例，读写操作都会用到。

### 导入到工程

1. 将 `MinewESLKit.jar`添加到module的libs文件夹下，并在该`module`的`build.gradle`中添加如下语句（直接添加依赖）：

   ```groovy
   implementation files('libs/MinewESLKit.jar')
   implementation 'org.lucee:bcprov-jdk15on:1.52.0'
   ```
   
   或者右键该jar文件，选择`Add as Library`，添加到当前module。
   
   项目还需要添加`Java 8`支持，需要在build.gradle添加如下配置：
   
   ```groovy
   android{
       defaultConfig {
           minSdkVersion 18
           targetSdkVersion 28
       }
       
       compileOptions {
           sourceCompatibility JavaVersion.VERSION_1_8
           targetCompatibility JavaVersion.VERSION_1_8
       }
   }
   ```
   
2. 在`AndroidManifest.xml`需要以下权限，如果`targetSdkVersion`大于23，则需要做**权限管理**以获取权限。

   ```xml
   <uses-permission android:name="android.permission.BLUETOOTH" />
   <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
   ```

### 开始开发

sdk分为扫描和连接两个阶段。

#### 扫描

```java
//获取管理类单例
MinewTagBleManager tagBleManager = MinewTagBleManager.getInstance();

//在开始扫描前可以设置默认扫描时间，时间毫秒。设置扫描时间不能小于8秒
tagBleManager.setDefaultScanTime(10*1000);

//清除此前的所有扫描结果
tagBleManager.clearScanResult(10*1000);

//开始扫描并设置监听器，默认扫描10s
tagBleManager.startScan(this, new OnScanTagResultListener() {
    @Override
    public void onScanTagResult(List<TagInfo> list) {
		//在这里处理扫描结果
    }

    @Override
    public void onStopScan(List<TagInfo> list) {
		//自动停止扫描，返回扫描时间内获取到的所有设备
    }
});

//或使用：开始扫描并设置监听器，设置扫描8秒，设置扫描时间不能小于8秒
tagBleManager.startScan(this,8000， new OnScanTagResultListener() {
    @Override
    public void onScanTagResult(List<TagInfo> list) {
		//在这里扫描结果
    }

    @Override
    public void onStopScan(List<TagInfo> list) {
		//自动停止扫描，返回扫描时间内获取到的所有设备
    }
});
```

#### 连接

通过扫描方法可获取到周边tag设备，然后可连接指定Tag，在连接前需要先写入密钥，然后才能调用连接方法。连接通过调用`connect()`。

```java
TagModule tagModule = tagBleManager.setEaxKeyByAddress(tagInfo, "3141592653589793");
//setEaxKeyByAddress()会返回TagModule实例
tagBleManager.connect(tagModule)
```

连接阶段，包括后续写入操作，都需要设置监听器，以判断状态。成功后才能进行刷图，刷图成功后也可以在这里获取到回调通知。

```java
tagBleManager.setOnConnStateListener(new OnConnStateListener() {
    @Override
    public void onUpdateConnState(String s, ConnectionState connectionState) {
        switch (connectionState) {
            case Connecting:
               //开始连接
                break;
            case Connect_Complete:
                //认证成功，此时认为已经连接成功
                break;
            case BRUSH_IMAGE:
               //刷图成功后调用，连接会断开
                break;
            case Disconnect:
                //连接断开
            default:
                break;
        }
    }
});
```

#### 刷图

连接成功后，即可去刷图。首先需要获取设备屏幕信息，通过屏幕信息去获取要写入Tag里面的图像数据。由于蓝牙数据传输长度限制，如果超出限制，将会进行分包处理，然后再依次发送。

```java
//屏幕信息存储在DeviceStaticInfoFrame类中
DeviceStaticInfoFrame frame = (DeviceStaticInfoFrame) tagModule.getMinewFrame(FrameType.DEVICE_STATIC_INFO_FRAME);
//取出屏幕信息，然后根据屏幕信息去获取刷图数据
String screenInfo = frame.getScreenInfo();
tagBleManager.sendImageData(macAddress, imageBytes, new OnWriteLargeDataListener() {
    
    /**
     * 更新写入进度
     *
     * @param index 当前已写入的数量
     * @param total 总共需要写入的数量
     */
    @Override
    public void onWriteUpdate(int index, int total) {
        Log.e("tetetetete", "sendImageData " + index + " " + total);
    }

    /**
     * 写入成功
     */
    @Override
    public void onWriteSuccess() {

    }

    /**
     * 写入失败。reason作用不大，仅用来排查失败原因
     */
    @Override
    public void onWriteFailed(int i) {

    }
});
```

**注意：刷图成功后，SDK会主动断开连接，且在OnConnStateListener回调中不会返回Disconnect状态！**

### 附表

1. `DeviceStaticInfoFrame`，设备静态信息帧，在该信息帧中，screenInfo是最重要的信息之一，通过screenInfo获取到相匹配的刷图数据，才能成功刷图。

   | 名称            | 类型   | 描述     |
   | --------------- | ------ | -------- |
   | firmwareVersion | String | 固件版本 |
   | hardwareVersion | String | 硬件信息 |
   | screenInfo      | String | 屏幕信息 |
   | chipInfo        | String | 芯片型号 |

2. `DeviceRunInfoFrame`，设备运行信息帧

   | 名称           | 类型   | 描述             |
   | -------------- | ------ | ---------------- |
   | batteryVoltage | int    | 设备的电压       |
   | imageId        | String | 设备的刷图数据ID |

## 更新历史

### V1.0.0 2020/03/10

添加文档。

### V1.0.1 2020/07/01 

1. 方法变更。标记MinewTagBleManager类的方法`getScanTagManager()`与`getConnTagManager()`为`@Deprecated`,以前需要通过这两个方法来获取指定对象并通过其来完成写入数据等操作，现在可直接完成，如：

   ```java
   tagBleManager.getScanTagManager().startScan();
   //将替换为：
   tagBleManager.startScan();
   
   tagBleManager.getConnTagManager().sendImageData();
   //将替换为：
   tagBleManager.sendImageData();
   ```

   但是通过`tagBleManager.getScanTagManager().startScan();`等方法依然有效，我们更推荐直接调用`startScan()`等方法。

2. 完善刷图回调。`OnWriteLargeDataListener()`接口增加两个方法。如下：

   ```java
   public interface OnWriteLargeDataListener {
   
       /**
        * 更新写入进度
        *
        * @param index 当前已写入的数量
        * @param total 总共需要写入的数量
        */
       void onWriteUpdate(int index, int total);
   
       /**
        * 写入成功
        */
       void onWriteSuccess();
   
       /**
        * 写入失败。reason作用不大，仅用来排查失败原因
        * 写入失败会断开连接，并通过OnConnStateListener返回Disconnect状态
        */
       void onWriteFailed(int reason);
   }
   ```
   
3. 在刷图场景下，会先执行`onWriteSuccess`再通过`OnConnStateListener`返回`BRUSH_IMAGE`状态；增加写入失败后断开连接，并通过`onWriteFailed`通知刷图失败并断开连接。
4. 添加附表，增加部分广播帧属性说明。

详情看文档。