# MinewMWC05Kit 说明文档
本套 SDK 仅支持 Minew 公司出品的蓝牙设备。
通过 SDK 可以帮助开发者处理手机和蓝牙设备之间的一切工作,包括:扫描设备,广播数据、连接设备,向设备写入数据,从设备接收数据等。
目前 SDK 仅支持 智能定位工牌设备使用。
# 前期工作
整体框架:MWC05BleManager 为设备管理类,在 APP 运行时始终是单例。MWC05Model 是设备实例类,此套件会为每一个设备生成一个实例,在扫描和连接后都会使用,内部包含设备广播数据,在扫描期间该数据会随着设备不停广播而更新。
MWC05BleManager :设备管理类,可以扫描周围的设备,并且可以连接它们,校验它们等
MWC05Model :扫描时获取到的智能定位工牌设备实例,继承自 BaseBleDeviceEntity
# 导入到工程
开发环境
SDK 最低支持 Android 5.0,对应 API Level 为 21 。在 module 的
build.gradle中设置minSdkVersion为 21 或 21 以上 :android { defaultConfig { applicationId "com.xxx.xxx" minSdkVersion 21 } }1
2
3
4
5
6将 jar 包添加到 module 的 libs 文件夹下,并在该
module的build.gradle中添加如下语句(直接添加依赖):implementation files('libs/lib_ble_base.jar') implementation files('libs/lib_ble_mwc05.jar') implementation files('libs/lib_ble_nl.jar') api 'org.lucee:bcprov-jdk15on:1.52.0' api 'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.16.0' api 'com.fasterxml.jackson.core:jackson-databind:2.15.0'1
2
3
4
5
6
或者右键该 jar 文件,选择 Add as Library ,添加到当前module。
添加 .so 库文件,App 目录下 build.gradle 添加如下配置:
android {
defaultConfig {
ndk {
abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
2
3
4
5
6
7
8
9
10
11
12
在
AndroidManifest.xml需要以下权限,如果targetSdkVersion大于23,则需要做权限管理以获取权限:<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" tools:node="replace" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" tools:node="replace" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:remove="android:usesPermissionFlags" /> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" tools:remove="android:usesPermissionFlags" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:remove="android:usesPermissionFlags" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />1
2
3
4
5
6
7
8
9
10
11
12
13
# 使用
SDK 分为扫描、连接和读写三个阶段。
# Android 6.0 系统以上,进行 BLE 扫描时,需要先申请到蓝牙权限后并且打开定位开关才能进行。
# 开始扫描
Android6.0 系统以上,进行 BLE 扫描时,需要先申请到蓝牙权限后并且打开定位开关才能进行。
开启蓝牙扫描需要首先打开蓝牙,如果未打开蓝牙就去扫描,APP 会闪退。可通过 BLETool.checkBluetooth(this) 来判断蓝牙是否已经打开。如果没有打开,可以先打开蓝牙。
MWC05BleManager mBleManager = MWC05BleManager.getInstance();
switch (BLETool.checkBluetooth(this)){
case BLE_NOT_SUPPORT:
Toast.makeText(this, "Not Support BLE", Toast.LENGTH_SHORT).show();
break;
case BLUETOOTH_ON:
//设置扫描时长5分钟,sdk默认扫描时长5分钟
mBleManager.startScan(this, 5 * 60 * 1000, new OnScanDevicesResultListener<MWC05Model>() {
@Override
public void onScanResult(List<MWC05Model> list) {
}
@Override
public void onStopScan(List<MWC05Model> list) {
}
});
break;
case BLUETOOTH_OFF:
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, 4);
break;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
在扫描期间 APP 能够通过 sdk 获取到设备当前的一部分数据。如下所示通过 MWC05Model 获取设备数据,该数据保存在广播帧对象中。
SDK 提供了 BaseBleDeviceEntity 作为 MWC05Model 的基类,用于存储设备的公有数据,如下表所示:
| 名称 | 类型 | 说明 |
|---|---|---|
| macAddress | String | 设备mac |
| name | String | 设备名称 |
| rssi | int | 信号强度 |
BaseBleDeviceEntity 还保存了一个 BaseNanoLinkFrame,内部用于存储其在扫描期间获取到的设备广播数据帧,可通过如下方式取出:
MWC05Model module;
MWC05AdvFrame MWC05AdvFrame = (MWC05AdvFrame) module.getNanoLinkFrame();
if (MWC05AdvFrame != null) {
//mac 地址
String macAddress = MWC05AdvFrame.getMac();
//deviceName 设备名称
String deviceName = MWC05AdvFrame.getDeviceName();
//firmwareVersion 版本号
String firmwareVersion = MWC05AdvFrame.getFirmwareVersion();
//battery 电量百分比,默认:Integer.MIN_VALUE 表示未获取到电量
int battery = MWC05AdvFrame.getBattery();
//frequencyBand 频段
int frequencyBand = MWC05AdvFrame.getFrequencyBand();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
智能定位工牌设备有 1 种广播帧类型。
设备帧
MWC05AdvFrame
名称 类型 说明 mac String 固件mac deviceName String 设备名称 firmwareVersion String 版本号 battery int 电量百分比,默认:Integer.MIN_VALUE 表示未获取到电量 frequencyBand int enum FrequencyPlan{
EU868(1,"EU868"),
US915(2,"US915"),
AU915(5,"AU915"),
CN470(6,"CN470"),
AS923_1(7,"AS923-1"),
AS923_2(8,"AS923-2"),
KR920(10,"KR920");
}
# 连接
连接前一般需要先停止扫描 ,SDK 提供了连接和断开连接方法。
MWC05BleManager mBleManager = MWC05BleManager.getInstance();
//停止扫描
mBleManager.stopScan(context);
//连接 : module 为准备连接的设备
MWC05Model module;
mBleManager.connect(context,module);
//断开连接 :macAddress 为设备 mac
mBleManager.disConnect(macAddress);
2
3
4
5
6
7
8
注意:连接设备前,请确认是否扫描到设备,如果没扫描到设备广播,调用连接方法,将连接失败。
在调用 connect() 后,SDK 中会对连接过程会有状态监听。
//设置监听器
mBleManager.setOnConnStateListener(new OnConnStateListener() {
/*
* 连接过程中的状态回调
* @param macAddress 设备mac
* @param BleConnectionState 状态
*/
@Override
public void onUpdateConnState(String address, BleConnectionState state) {
switch (state) {
case Connecting:
//调用connect()后就会回调该状态
break;
case Connected:
//初步连接成功,作为一个过渡阶段,此时并未真正成功
break;
case Bond_None:
//设备配对回调,此处为无效配对状态
break;
case Bond_Bonding:
//设备配对回调,此处为正在配对状态
break;
case Bond_Bonded:
//设备配对回调,此处为配对完成状态
//设备配对完成,才能通过 MWC05BleManager 中提供的方法操作设备
break;
case ConnectComplete:
//设备连接完成,才能通过 MWC05BleManager 中提供的方法操作设备
break;
case Disconnect:
//连接失败或者设备断开连接会回调,主动断开不会回调该状态
break;
default:
break;
}
}
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
在连接过程中,sdk会返回多个连接状态到app中,app需要做好处理。
- BleConnectionState.Connecting,BleConnectionState.Connected: 连接设备中,在这里状态下不要做耗时操作,因为此时在连接设备发现服务,并发送认证数据等。
- BleConnectionState.Bond_None: 设备配对无效状态。
- BleConnectionState.Bond_Bonding: 设备正在配对状态。
- BleConnectionState.Bond_Bonded: 设备配对完成状态,才能通过 MWC05BleManager 中提供的方法操作设备。
- BleConnectionState.ConnectComplete: 设备已经连接成功,可以进行读写操作,比如配置广播参数、读取历史数据等。
- BleConnectionState.Disconnect: 连接失败或者设备断开连接会回调。
# 设备配置读取写入操作
设备配置读取写入操作 API 如下,使用 MWC05BleManager mBleManager = MWC05BleManager.getInstance() 对象调用完成:
/**
* 清空扫描设备列表
*/
void clearScanResult();
/**
* 设置默认扫描时长
*
* @param scanTime 扫描时长,单位为 ms
*/
void setDefaultScanTime(int scanTime);
/**
* 开始扫描设备
*
* @param context 上下文
* @param listener 监听器
*/
void startScan(Context context, OnScanDevicesResultListener listener) ;
/**
* 开始扫描设备
*
* @param context 上下文
* @param scanTime 扫描时长,单位 ms
* @param listener 监听器
*/
void startScan(Context context, int scanTime, OnScanDevicesResultListener listener) ;
/**
* 停止扫描设备
*
* @param context 上下文
*/
void stopScan(Context context) ;
/**
* 判断是否正在扫描
*
*/
boolean isScanning() ;
/**
* 恢复出厂设置
*
* @param macAddress 设备mac
* @param listener 监听器
*/
void reset(String macAddress, OnModifyConfigurationListener listener);
/**
* 关机
*
* @param macAddress 设备mac
* @param listener 监听器
*/
void powerOff(String macAddress, OnModifyConfigurationListener listener);
/**
* 重启
*
* @param macAddress 设备mac
* @param listener 监听器
*/
void reboot(String macAddress, OnModifyConfigurationListener listener);
/**
* 连接设备
*
* @param context 上下文
* @param macAddress 设备mac
*/
void connect(Context context, String macAddress);
/**
* 连接设备
*
* @param context 上下文
* @param module 设备实体
*/
void void connect(Context context, MWC03Model module);
/**
* 断开连接
*
* @param macAddress 设备mac
*/
void void disConnect(String macAddress);
/**
* 设置设备连接监听器
*
* @param listener 监听器
*/
void setOnConnStateListener(OnConnStateListener listener)
/**
* 设备固件升级
*
* @param context 上下文对象
* @param macAddress 设备mac
* @param isLinkUpgrade :true url升级,false 固件包升级。默认值false,不支持url升级方式
* @param filePath OTA文件路径,url升级时可为null
* @param upgradeData OTA数据,url升级时可为null
* @param fileUpgradeTarget 升级固件目标,OTA数据,默认 fileUpgradeTarget="main",链接升级方式无需修改,只有文件升级方式需要填入
* @param linkUpgradeTarget 升级固件目标,OTA数据,默认 linkUpgradeTarget="app",文件升级方式无需修改,只有链接升级方式需要填入
* @param listener 监听器
*/
void firmwareUpgrade(Context context, String macAddress, boolean isLinkUpgrade, String filePath, byte[] upgradeData, String fileUpgradeTarget,String linkUpgradeTarget, OnFirmwareUpgradeListener listener) ;
/**
* 查询固件版本
*
* @param macAddress 设备mac
* @param listener 监听器
*/
void getFirmwareVersion(String macAddress, OnQueryResultListener<FirmwareVersionModel> listener);
//关于 FirmwareVersionModel 类简要内容
public class FirmwareVersionModel {
List<VersionInfo> versionInfoList;
}
//关于 VersionInfo 类简要内容
public class VersionInfo {
// 固件名称
private String firmwareName;
// 固件类型
private int firmwareType;
// 固件版本
private String firmwareVersion;
// 固件插槽
private String slot;
// 固件类型对应的升级方式:img 支持镜像文件方式升级,hl 支持链接方式升级,file 支持文件方式升级
private ArrayList<String> methods;
}
/**
* 获取名称
* @param macAddress MAC 地址
* @param listener 获取名称监听器
*/
void getDeviceName(String macAddress, OnQueryResultListener<DeviceName> listener);
/**
* 设置名称
* @param macAddress MAC 地址
* @param name 设备名称(最长 7 bytes)——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置名称结果监听器
*/
void setDeviceName(String macAddress, String name, OnModifyConfigurationListener listener);
/**
* 退出模式5
* @param macAddress MAC 地址
* @param listener 监听器
*/
void setExitMode5(String macAddress, OnModifyConfigurationListener listener);
/**
* 获取指示器状态
* @param macAddress MAC 地址
* @param listener 获取指示器状态监听器
*/
void getIndicator(String macAddress, OnQueryResultListener<Indicator> listener);
public class Indicator {
// 总控开关,只有为 true时,bz,led,vm 才生效,为 false ,则全为关闭状态
private boolean en;
// 是否开启蜂鸣器,默认 null 为 true
private Boolean bz;
// 是否开启灯效,默认 null 为 true
private Boolean led;
// 是否开启振动,默认 null 为 true
private Boolean vm;
}
/**
* 设置指示器状态
* @param macAddress MAC 地址
* @param indicator 指示器状态——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置指示器状态结果监听器
*/
void setIndicator(String macAddress, Indicator indicator, OnModifyConfigurationListener listener);
/**
* 获取定位方式
* @param macAddress MAC 地址
* @param listener 获取定位方式监听器
*/
void getLocationMethod(String macAddress, OnQueryResultListener<LocationMethod> listener);
public class LocationMethod {
// 这个字段是一个数组,用于指定设备的默认定位方式。用户可以同时配置多种定位方式,并指定它们的优先级。如果设备无法使用当前的方法进行定位,它会自动切换到下一个方法;如果尝试了所有已配置的方法但都没有成功,那么定位尝试将被视为失败。
//0 Bluetooth LE Scan 蓝牙低功耗扫描
//1 Wi-Fi Scan Wi-Fi 扫描
//2 GNSS
private Integer[] meth;
// 这个字段是一个数组,用于指示当前设备支持哪些定位方式。该字段中的值与上述“meth”中的定义相同。
private Integer[] meth_cap;
// 这个字段是一个数组类型。第一个元素表示在蓝牙低功耗通信过程中,设备是基于设备的 MAC 地址来确定位置,还是基于 iBeacon 的主要标识符和次要标识符来确定位置。值为 0 时,选择设备的 MAC 地址;值为 1 时,选择 iBeacon 的 major 和 minor。
private Integer[] le;
}
/**
* 设置定位方式
* @param macAddress MAC 地址
* @param locationMethod 定位方式——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置定位方式结果监听器
*/
void setLocationMethod(String macAddress, LocationMethod locationMethod, OnModifyConfigurationListener listener);
/**
* 获取按键模式定义
* @param macAddress MAC 地址
* @param listener 获取按键模式定义监听器
*/
void getModeEntryButtons(String macAddress, OnQueryResultListener<ModeEntryButtons> listener);
public class ModeEntryButtons {
//这个字段是一个数组。其第一个元素指定了用于进入模式 4 的按钮操作;唯一有效的数值是 2,表示需要双击按钮才能进入模式 4。如果数组为空,则表示无法通过按钮进入模式 4。
private Integer[] m4;
//这个字段是一个数组,用于指定进入模式 5 时的按钮操作。有效的取值包括:1、2、3、4、5。对应的含义分别为:单次点击、双次点击、三次点击、四次点击、五次点击以及长时间点击。用户至少需要指定一种操作,最多可以同时指定五种操作。
private Integer[] m5;
}
/**
* 设置按键模式定义
* @param macAddress MAC 地址
* @param modeEntryButtons 按键模式定义——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置按键模式定义结果监听器
*/
void setModeEntryButtons(String macAddress, ModeEntryButtons modeEntryButtons, OnModifyConfigurationListener listener);
/**
* 获取定位模式
* @param macAddress MAC 地址
* @param listener 获取定位模式监听器
*/
void getLocationMode(String macAddress, OnQueryResultListener<LocationMode> listener);
public class LocationMode {
// 该设备支持 3 种基本操作模式以及 2 种辅助模式。用户可以将设备设置为运行在 3 种基本模式中的任何一种,然后通过发送特定的命令或按下特定的按钮来进入 2 种辅助模式中的任何一种。这 5 种模式的描述如下。请注意,在本文档中,这些模式将使用数字标识符来表示,而不是具体的模式名称。
//基本操作模式:
//模式 1:该设备会定期进行位置校准。
//模式 2:当设备从静止状态转换为运动状态,或者从运动状态转换回静止状态时,会进行位置校准。
//模式 3:该设备会定期进行位置校准;在从静止状态变为移动状态后,它会改变位置更新的频率。
//辅助模式:
//模式 4:在接收到指定的指令或用户按下指定的按钮后,设备会进行一次位置定位操作。
//模式 5:当用户按下指定的按钮后,设备会按照指定的间隔进行多次定位校准,之后自动退出运行状态。
// 这个字段是一个数组。第一个元素指定了设备在进入模式 5 后所处的位置间隔;第二个元素则指定了在模式 5 下需要执行的位置定位次数。第三个元素用于选择基本操作模式;有效的值包括:1 2 3 则分别对应基本操作模式。
// 当选择模式 1 时,第四个参数是可选的,它用于指定位置间隔。如果未提供该参数,则会使用默认值。
// 当选择模式 3 时,第 4 个和第 5 个元素变为可选项。第 4 个元素用于指定静止状态下的位置间隔,而第 5 个元素则用于指定运动状态下的位置间隔。位置间隔的单位是秒。如果未提供该单位,将使用默认值。
private Integer[] it;
}
/**
* 设置定位模式
* @param macAddress MAC 地址
* @param locationMode 定位模式——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置定位模式结果监听器
*/
void setLocationMode(String macAddress, LocationMode locationMode, OnModifyConfigurationListener listener);
/**
* 获取扫描过滤条件
* @param macAddress MAC 地址
* @param listener 获取扫描过滤条件监听器
*/
void getScanFilter(String macAddress, OnQueryResultListener<ScanFilter> listener);
public class ScanFilter {
//这个字段是数组类型,可以包含多个 Map 类型作为数组元素。不同 Map 元素之间的关联是或的关系,而同一个 Map 内部的元素之间则是与的关系。map 对象的 key 必须是 rssi,re_mac,re_raw
// rssi 接收信号强度指示。 范围为 -100 ~ 0
// re_mac 该字段可以接受一个正则表达式,用于过滤设备的 MAC 地址。 输入长度限制为 64
// re_raw 该字段可以接受一个正则表达式,用于过滤广告数据。 输入长度限制为 192
private LinkedList<TypeMap<String, Object>> filter;
}
/**
* 设置扫描过滤条件
* @param macAddress MAC 地址
* @param scanFilter ScanFilter——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置扫描过滤条件结果监听器
*/
void setScanFilter(String macAddress, ScanFilter scanFilter, OnModifyConfigurationListener listener);
/**
* 获取 WIFi 扫描参数
* @param macAddress MAC 地址
* @param listener 获取 WIFi 扫描参数监听器
*/
void getWiFiScan(String macAddress, OnQueryResultListener<WiFiScan> listener);
public class WiFiScan {
//该字段用于配置 Wi-Fi 扫描的超时时间,单位以秒计。范围从 1 秒到 300 秒。
private Integer to;
}
/**
* 设置 WIFi 扫描参数
* @param macAddress MAC 地址
* @param wiFiScan WiFiScan——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置 WIFi 扫描参数结果监听器
*/
void setWiFiScan(String macAddress, WiFiScan wiFiScan, OnModifyConfigurationListener listener);
/**
* 获取 Le 扫描参数
* @param macAddress MAC 地址
* @param listener 获取 Le 扫描参数监听器
*/
void getLeScan(String macAddress, OnQueryResultListener<LeScan> listener);
public class LeScan {
//扫描间隔是指扫描器在两次连续唤醒以接收广告信息之间所经历的时间长度。该单位为单位毫秒。该字段的有效取值范围为 2.5 毫秒到 10240 毫秒(10.24 秒)。任何超出此范围的值都将被视为无效。需要注意的是,即使输入的值在有效范围内,根据蓝牙规范的要求,该值必须是 0.625 的倍数,例如 2.5、3.125、3.75 等。如果输入的值不是 0.625 的倍数,程序会自动将其转换为最接近的值。例如,2.6 和 3.0 会被转换为 2.5,而 3.2 和 3.5 则会被转换为 3.125。
private Float it;
//扫描窗口决定了在每次扫描期间执行的扫描时长。单位为单位毫秒。该字段的有效取值范围为 2.5 毫秒到 10240 毫秒(10.24 秒)。任何超出此范围的值都将被视为无效。需要注意的是,即使输入的值在有效范围内,根据蓝牙规范的要求,该值必须是 0.625 的倍数,例如 2.5、3.125、3.75 等。如果输入的值不是 0.625 的倍数,程序会自动将其转换为最接近的值。例如,2.6 和 3.0 会被转换为 2.5,而 3.2 和 3.5 则会被转换为 3.125。
private Float wd;
//扫描超时时间指的是扫描操作在自动停止之前允许持续运行的最长时间,单位为单位毫秒。该字段的有效取值范围为 500 毫秒到 655350 毫秒(即 655.35 秒)。任何超出此范围的值都将被视为无效。需要注意的是,即使输入的值在有效范围内,根据蓝牙规范的要求,该值必须是 10 的倍数,例如 10、20、30 等。如果输入的值不是 10 的倍数,程序会自动将其转换为最接近 10 的倍数的值。例如,12 和 15 会被转换为 10,而 32 和 35 则会被转换为 30。在特定情况下,这可以被称为一次蓝牙低功耗通信扫描过程。
private Integer to;
//主动式扫描仪可以发送扫描请求,以从广告商处获取更多信息;而被动式扫描仪则只能接收来自广告设备的数据。
private boolean at;
}
/**
* 设置 Le 扫描参数
* @param macAddress MAC 地址
* @param leScan LeScan——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置 Le 扫描参数结果监听器
*/
void setLeScan(String macAddress, LeScan leScan, OnModifyConfigurationListener listener);
/**
* 获取 LoRaWAN
* @param macAddress MAC 地址
* @param listener 获取 LoRaWAN 监听器
*/
void getLoRaWAN(String macAddress, OnQueryResultListener<LoRaWAN> listener);
public class LoRaWAN {
//该字段用于启用 LoRaWAN 自适应数据速率功能。请注意,此功能默认是开启状态。
private Boolean adr;
//该字段表示 LoRaWAN 的频率规划,详情请参阅频率规划表格。
private Integer fq;
//这个字段是一个数组,列出了设备支持的 LoRaWAN 频率方案。详情请参阅频率方案表格。
private Integer[] fq_cap;
}
/**
* 设置 LoRaWAN 扫描参数
* @param macAddress MAC 地址
* @param loRaWAN loRaWAN——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置 LoRaWAN 结果监听器
*/
void setLoRaWAN(String macAddress, LoRaWAN loRaWAN, OnModifyConfigurationListener listener);
/**
* 获取 Notification
* @param macAddress MAC 地址
* @param listener 获取 Notification 监听器
*/
void getNotification(String macAddress, OnQueryResultListener<Notification> listener);
public class Notification {
//该字段指定了设备的心跳间隔。当设备检测到自上次数据发送以来所经过的时间超过了这个间隔时,它会自动发送一个心跳包,单位秒。
private int hb;
//这个字段是一个数组。第一个元素指定需要通知的蓝牙 MAC 地址的数量(范围:1-5);第二个元素指定每个蓝牙 MAC 地址的长度(范围:2-6 字节)。
private Integer[] le;
//这个字段是一个数组。第一个元素指定了需要通知的 Wi-Fi 设备 MAC 地址的数量(范围:1-4)。
private Integer[] wifi;
}
/**
* 设置 Notification 参数
* @param macAddress MAC 地址
* @param notification notification——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置 Notification 结果监听器
*/
void setNotification(String macAddress, Notification notification, OnModifyConfigurationListener listener);
/**
* 获取 LocationActivationCondition:该命令用于配置设备进行定位时的条件,它仅在模式 1,2 以及 3 模式下生效。
* @param macAddress MAC 地址
* @param listener 获取 LocationActivationCondition 监听器
*/
void getLocationActivationCondition(String macAddress, OnQueryResultListener<LocationActivationCondition> listener);
public class LocationActivationCondition {
//这个字段用于启用计时器条件。当该值为真时,设备仅在计时器指定的时间内才能执行定位操作。
private boolean timer;
}
/**
* 设置 LocationActivationCondition 参数:该命令用于配置设备进行定位时的条件,它仅在模式 1,2 以及 3 模式下生效。
* @param macAddress MAC 地址
* @param locationActivationCondition locationActivationCondition——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置 LocationActivationCondition 结果监听器
*/
void setLocationActivationCondition(String macAddress, LocationActivationCondition locationActivationCondition, OnModifyConfigurationListener listener);
/**
* 获取工作时间段配置
* @param macAddress MAC 地址
* @param listener 获取结果监听器
*/
void getTimer(String macAddress, OnQueryResultListener<List<Timer>> listener);
public class Timer {
//这个字段用于标识计时器 ID;请注意,不允许存在重复的 ID。
private int id = Integer.MIN_VALUE;
//这个字段用于指示一个时间段。数组中的第一个元素表示开始时间时间戳,第二个元素表示结束时间时间戳。请注意,时间格式采用 CBOR 标签 1 类型,且结束时间必须大于开始时间。10位时间戳单位到秒。
private List<Long> time;
}
/**
* 设置工作时间段参数
* @param macAddress MAC 地址
* @param timer 工作时间段参数——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置工作时间段参数结果监听器
*/
void setTimer(String macAddress, List<Timer> timer, OnModifyConfigurationListener listener);
/**
* 获取传感器配置
* @param macAddress MAC 地址
* @param listener 获取结果监听器
*/
void getSensor(String macAddress, OnQueryResultListener<Sensor> listener);
public class Sensor {
//该字段用于设置运动敏感度的等级。有效的数值为 1 或更大的整数,数值越大表示敏感度越高。一般为 1,2,3
private int sens;
//该字段用于指定设备在检测到运动后需要保持静止的时间长度(以秒为单位)。有效范围為 1 到 3600 秒。
private int idle;
}
/**
* 设置传感器参数
* @param macAddress MAC 地址
* @param sensor 传感器参数——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置传感器参数结果监听器
*/
void setSensor(String macAddress, Sensor sensor, OnModifyConfigurationListener listener);
/**
* 清空历史数据
* @param macAddress MAC 地址
* @param listener 清空历史数据结果监听器
*/
void setClearHistory(String macAddress, Boolean force, OnModifyConfigurationListener listener);
/**
* 获取支持的频段计划列表
* @param fq 设备当前频段
* @param listener 获取结果监听器
*/
void getValidateFrequencyPlanListByFrequency(int fq, OnQueryResultListener<LinkedList<FrequencyPlan>> listener);
public enum FrequencyPlan {
EU868(1,"EU868"),
US915(2,"US915"),
AU915(5,"AU915"),
CN470(6,"CN470"),
AS923_1(7,"AS923-1"),
AS923_2(8,"AS923-2"),
KR920(10,"KR920");
}
/**
* 获取WiFi扫描过滤条件
* @param macAddress MAC 地址
* @param listener 获取扫描过滤条件监听器
*/
void getWiFiScanFilter(String macAddress, OnQueryResultListener<WiFiScanFilter> listener);
public class WiFiScanFilter {
//这个字段是数组类型,可以包含多个 Map 类型作为数组元素。不同 Map 元素之间的关联是或的关系,而同一个 Map 内部的元素之间则是与的关系。map 对象的 key 必须是 rssi,re_mac
// rssi 接收信号强度指示。 范围为 -100 ~ 0
// re_mac 该字段可以接受一个正则表达式,用于过滤设备的 MAC 地址。 输入长度限制为 64
private LinkedList<TypeMap<String, Object>> filter;
}
/**
* 设置WiFi扫描过滤条件
* @param macAddress MAC 地址
* @param wiFiScanFilter wiFiScanFilter——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置扫描过滤条件结果监听器
*/
void setWiFiScanFilter(String macAddress, WiFiScanFilter wiFiScanFilter, OnModifyConfigurationListener listener);
/**
* 获取按键关机状态
* @param macAddress MAC 地址
* @param listener 获取指示器状态监听器
*/
void getButtonPowerOff(String macAddress, OnQueryResultListener<ButtonPowerOff> listener);
public class ButtonPowerOff {
//将 true 设置为允许通过按钮关闭设备的电源;或者将 false 设置为禁用此功能。
private boolean en;
}
/**
* 设置按键关机状态
* @param macAddress MAC 地址
* @param buttonPowerOff 按键关机状态
* @param listener 设置指示器状态结果监听器
*/
void setButtonPowerOff(String macAddress, ButtonPowerOff buttonPowerOff, OnModifyConfigurationListener listener);
/**
* 获取 ChannelsMask 扫描参数
* @param macAddress MAC 地址
* @param listener 获取 ChannelsMask 扫描参数监听器
*/
void getChannelsMask(String macAddress, OnQueryResultListener<ChannelsMaskGroup> listener);
/**
* 先通过 setGroupSize(int groupSize) 方法初始化该对象后进行使用
* FrequencyPlan.CN470 12组 -> setGroupSize(12)
* FrequencyPlan.US915 8组 -> setGroupSize(8)
* FrequencyPlan.AU915 8组 -> setGroupSize(8)
*/
public class ChannelsMaskGroup {
private int groupSize = 0;
private boolean[] channelStates;
public boolean isChannelGroupOpen(int channelIndex) {
if (channelStates.length==0){
LogUtilForCombineBase.e("channelStates is null");
return false;
}
if (channelIndex >= 1 && channelIndex <= channelStates.length) {
return channelStates[channelIndex - 1];
}
return false;
}
public void setChannelGroupOpen(int channelIndex, boolean isOpen) {
if (channelStates.length==0){
LogUtilForCombineBase.e("channelStates is null");
return;
}
if (channelIndex >= 1 && channelIndex <= channelStates.length) {
this.channelStates[channelIndex - 1] = isOpen;
}
}
public int getGroupSize() {
return groupSize;
}
public void setGroupSize(int groupSize) {
this.groupSize = groupSize;
this.channelStates = new boolean[groupSize];
}
public boolean[] getChannelStates() {
return channelStates;
}
public void setChannelStates(boolean[] channelStates) {
this.channelStates = channelStates;
}
}
/**
* 设置 ChannelsMask 扫描参数
* @param macAddress MAC 地址
* @param channelsMaskGroup ChannelsMask
* @param listener 设置 ChannelsMask 扫描参数结果监听器
*/
void setChannelsMask(String macAddress, ChannelsMaskGroup channelsMaskGroup, OnModifyConfigurationListener listener);
/**
* 获取广播配置参数
* @param macAddress MAC 地址
* @param listener 获取广播配置支持监听器
*/
void getAdvertising(String macAddress, OnQueryResultListener<LinkedList<Advertising>> listener);
public class Advertising {
//该字段表示当前的广告设置是否已启用。
public boolean enable;
//该字段指定了这些广告设置适用的运行模式。也就是说,当设备处于该模式时,这些设置才会被激活。
public String mode;
//该字段表示当前广告设置处于何种状态。该字段是一个数组,每个元素都是一个映射结构。
public List<Map<String, Object>> conditions;
//该字段用于描述与 LE AD 结构相关的信息。
public AdvertisingAdvStructures advStructures;
//该字段表示当前条目的广播帧内容。
public AdvertisingFrame frame;
//该字段表示当前条目的广播帧参数。
public AdvertisingParams params;
}
public class AdvertisingParams {
//该字段用于指定广告的间隔时间,单位为毫秒。范围 100ms ~ 10000ms
public Integer interval;
//广告传输功率,单位:dBm。如果设备无法直接支持该输入值,则会使用最接近的支持值来代替。
public Integer txPower;
//该字段用于指定用于广告传播的 PHY 类型。允许的值可以在“广告 PHY 值”表中找到。
public Integer phy;
//该字段指定了广告显示的超时时间,单位为毫秒。如果值为 0 或省略,则表示广告不会自动超时。
public Integer timeout;
}
/**
* 设置广播参数
* @param macAddress MAC 地址
* @param adv 设备广播参数——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置名称结果监听器
*/
void setAdvertising(String macAddress, LinkedList<Advertising> adv, OnModifyConfigurationListener listener);
/**
* 获取按键灯效参数
* @param macAddress MAC 地址
* @param listener 获取灯效参数监听器
*/
void getMode5Effects(String macAddress, OnQueryResultListener<Mode5EffectsBusiness> listener);
public class Mode5EffectsBusiness {
//按键灯效列表
private LinkedList<Mode5EffectsLed> led;
}
public class Mode5EffectsLed {
//有效的值包括 1、2、3、4、5,11分别对应单次点击、双次点击、三次点击、四次点击、五次点击,以及持续按住按钮的情况。
private int buttonAction;
//使用默认灯效
private boolean useDefaultLedEffects;
//数组第一个 灯效 颜色
private LedEffectsColor ledEffectsColor;
//数组第三个 灯效 类型
private LedEffectsType ledEffectsType = LedEffectsType.BLINK;
//数组第二个 灯效 亮度
private Integer ledLightBrightness;
//灯效 单次亮灯时长
private Integer ledOnDuration = null;
//灯效 单次灭灯时长
private Integer ledOffDuration = null;
//灯效 循环次数
private Integer ledCycleCount = null;
}
/**
* 设置按键灯效参数
* @param macAddress MAC 地址
* @param mode5EffectsBusiness 灯效参数——[注意:请尽量使用get方法中获取的对象,完成需要修改的部分后进行 set 方法配置相应的对象]
* @param listener 设置灯效参数结果监听器
*/
void setMode5Effects(String macAddress, Mode5EffectsBusiness mode5EffectsBusiness, OnModifyConfigurationListener listener);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
对部分方法进行补充说明:
给设备授予手机当前时间:
// 首先要检查蓝牙开关是否打开,只有在打开的情况下才能开启手机的 CurrentTimeService 服务,如果蓝牙开关关闭去开启,部分 Android 手机系统可能会出错。并且需要监听蓝牙开关状态,当蓝牙开关开启时候需要开启服务 startSyncTimeServer,关闭的时候需要关闭服务 closeSyncTimeServer。注意,当 activity 页面 ondestroy 时,也需要关闭该服务 closeSyncTimeServer MWC05BleManager mBleManager = MWC05BleManager.getInstance(); // 开启服务 mBleManager.startSyncTimeServer(context); // 关闭服务 mBleManager.closeSyncTimeServer(context); // 因为部分手机会偶现授时失败的情况,所以需要判断授时是否成功,建议在设备连接成功 3 秒后判断 mBleManager.isDeviceReadSyncTime(context); // 如果授时操作不成功,那么需要主动给设备发送授时指令 mBleManager.writeTimeToDevice(macAddress, onWriteTimeToDeviceListener);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15固件升级。
/** * 固件升级 * * @param macAddress 设备mac * @param upgradeData 升级包数据 * @param listener 监听器 */ mBleManager.firmwareUpgrade(mac,false,0, upgradeData, new OnFirmwareUpgradeListener() { /** * 升级包数据写入进度 */ @Override public void updateProgress(int progress) { } /** * 升级成功回调,此时设备会主动跟手机断开连接,所以会触发OnConnStateListener回调,返回 * BleConnectionState.Disconnect状态 */ @Override public void upgradeSuccess() { } /** * 升级失败 */ @Override public void upgradeFailed() { } });1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36查询历史记录
LogUtil.e("time == ${selectedStartTimeDate.time} ms ${selectedEndTimeDate.time} ms") lifecycleScope.launch(Dispatchers.IO) { StorageIndexRecordSearcher<StorageActualData>().getStorageIndexRecordsNeedSearchFile( this@MWC05HistoryDataActivity, mConnectViewModel.connectMacAddress, false, StorageIndexRecordCondition() .setStorageDataBlockType(StorageDataBlockType.Location) .setInstance(StorageIndexInstance.INSTANCE_DEFAULT) .setStartTime(when (queryAllData){ true ->0 else ->selectedStartTimeDate.time/1000 }) .setEndTime(when (queryAllData){ true ->System.currentTimeMillis()/1000 else ->selectedEndTimeDate.time/1000 }) //.setMaximumQuantityLimit(StorageIndexRecordCondition.QuantityLimit.LIMIT_10000) ) { result,exception -> lifecycleScope.launch (Dispatchers.Main) { if ( exception == null && result != null && !result!!.isEmpty() ) { dealResult(result) } else { showNoDataDialog() } LoadingDialogUtil.dismissLoadingDialog() } } } private fun dealResult(storageActualDataList: List<StorageActualData>?){ leScanEntryResultList = null wifiScanEntryResultList = null gnssResultList = null if (storageActualDataList!=null&&storageActualDataList.isNotEmpty()){ leScanEntryResultList = mutableListOf() wifiScanEntryResultList = mutableListOf() gnssResultList = mutableListOf() for (one in storageActualDataList){ when(one){ is StorageActualDataLocationLeScanEntry->{ leScanEntryResultList!!.add(one) } is StorageActualDataLocationWiFiScanEntry -> { wifiScanEntryResultList!!.add(one) } is StorageActualDataGNSS -> { gnssResultList!!.add(one) } } } } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 文档更新记录
- 2026/08/18 新增 MWC05 设备操作基本功能 API