【Android】BLE-WiFi 双模配网最佳实践
什么是双模配网?
通常我们将支持BLE、WiFi双模组的设备称为双模设备或者蓝牙双模设备。
设备重置后对外发送蓝牙广播包,App在捕获到设备的蓝牙广播包后可以显示出对应的设备,然后选择指定设备并输入WiFi配网信息,此时App会和设备建立蓝牙连接,通过蓝牙通道完成数据传输。以上这个过程我们称之为双模配网。
双模配网的优势?
WiFi设备一般的配网方式有三种:EZ配网、AP配网、双模配网
EZ配网对于用户来说只需要输入路由器的SSID和Password即可一键完成配网,但由于路由器的兼容性问题、iOS本地网络权限是否打开、设备是否成功被重置等等因素都影响着EZ配网,虽然操作简单,但如果配网失败了对于用户来说就大概率不知道怎么办了。
AP配网需要用户先重置设备到AP模式,然后在手机上切换到系统设置页连接设备发出的AP热点,再回到App进行配网。因为通过AP建立了稳定的连接,数据的传输得到了可靠的保障,所以只要进行正确的引导,配网成功率还是颇为可观的。但是AP配网的操作过程过于复杂,对于新手用户的理解成本过高。
双模配网能通过蓝牙扫描到具体的设备,明确的知道设备是否被成功重置,并且可以选择指定的待配网设备并且在配网过程能建立稳定的数据传输通道。
概念澄清
配网成功:
设备成功在云端激活成功,并且连接MQTT服务成功(成功连云上线),才认定为配网成功。
轮询:
App在向设备发送配网信息后会调用云端接口开启设备轮询,轮询到设备且设备的在线状态为true时才会触发配网成功回调。
代码示例:
1、蓝牙扫描-双模设备
Code: Select all
LeScanSetting scanSetting = new LeScanSetting.Builder()
.setTimeout(60000) // 扫描的超时时间:ms
.addScanType(ScanType.SINGLE) // 若需要扫描蓝牙设备,则只需要添加 ScanType.SINGLE
// .addScanType(ScanType.SIG_MESH) 可同时添加其他类型设备
.build();
// 开始扫描
ThingHomeSdk.getBleOperator().startLeScan(scanSetting, new BleScanResponse() {
@Override
public void onResult(ScanDeviceBean bean) {
// 回调扫描的结果
// 判断是否是双模的设备
if(bean != null && TextUtils.equals("config_type_wifi",bean.getConfigType())){
这里代表是双模的设备
}
}
});
2、开始配网
Code: Select all
// mScanDeviceBean 来自于扫描回调的 ScanDeviceBean
MultiModeActivatorBean multiModeActivatorBean = new MultiModeActivatorBean(mScanDeviceBean);
// mScanDeviceBean 来自于扫描回调的 ScanDeviceBean
multiModeActivatorBean.deviceType = mScanDeviceBean.getDeviceType(); // 设备类型
multiModeActivatorBean.uuid = mScanDeviceBean.getUuid(); // 设备 uuid
multiModeActivatorBean.address = mScanDeviceBean.getAddress(); // 设备地址
multiModeActivatorBean.mac = mScanDeviceBean.getMac(); // 设备 mac
multiModeActivatorBean.ssid = "WIFI_2.4G"; // Wi-Fi SSID;// Wi-Fi SSID
multiModeActivatorBean.flag = mScanDeviceBean.getFlag();
multiModeActivatorBean.pwd = "WIFI_PASSWORD"; // Wi-Fi 密码
multiModeActivatorBean.token = "abcd1234"; // 获取的 Token
multiModeActivatorBean.homeId = ; // 当前家庭 homeId
multiModeActivatorBean.timeout = 120000; // 超时时间
// 开始配网
ThingHomeSdk.getActivator().newMultiModeActivator().startActivator(multiModeActivatorBean, new IMultiModeActivatorListener() {
@Override
public void onSuccess(DeviceBean deviceBean) {
// 配网成功
}
@Override
public void onFailure(int code, String msg, Object handle) {
// 配网失败
}
});
3、由于双模配网的时候,很大概率取决于 Wi-Fi 是否能连接成功,而连接 Wi-Fi 成功与否很大概率取决于用户选择的 Wi-Fi 以及输入的密码是否正确,为了提高配网的效率,我们提供了双模配网错误纠正的额外功能。当出现重新路由器连接失败或者密码错误的时候,业务层可以做相应的操作来纠正并且继续配网。
// 开始配网
Code: Select all
ThingHomeSdk.getActivator().newMultiModeActivator().startActivator(multiModeActivatorBean, new IMultiModeActivatorListener() {
@Override
public void onSuccess(DeviceBean deviceBean) {
// 配网成功
}
@Override
public void onFailure(int code, String msg, Object handle) {
// 配网失败
}
public void onActivatorStatePauseCallback(PauseStateData stateData) {
//设备上报的数据,包含设备是否没有连上路由器等,具体含义见参数说明
// 这里可以做重新选择路由器,或者重新更换密码
//queryWifiList(stateData.uuid);
if (stateData == null) return;
if (stateData.configStage == 0){ // 配网阶段激活
}else if (stateData.configStage == 1){// 代理激活阶段
}else if (stateData.configStage == 2){// 联网阶段
if (stateData.status != 0){
// 可以提示重新设置路由器信息
ResumeActivatorBean resumeActivatorBean = new ResumeActivatorBean.Builder()
.setUuid(uuid)
.setResumeType(ResumeActivatorBean.RESUME_TYPE_WIFI)
.setSsid(newSsid)
.setPassword(newPassword).build();
mMultiModeActivator.resumeActivator(resumeActivatorBean);
}
}else if (stateData.configStage == 3){// 激活阶段
if (stateData.status != 0 && stateData.status != 9){
// 可以提示重新设置路由器信息
ResumeActivatorBean resumeActivatorBean = new ResumeActivatorBean.Builder()
.setUuid(uuid)
.setResumeType(ResumeActivatorBean.RESUME_TYPE_WIFI)
.setSsid(newSsid)
.setPassword(newPassword).build();
mMultiModeActivator.resumeActivator(resumeActivatorBean);
}
}
}
});
具体的重试规则可以按照业务的情况选择。具体错误码见双模设备恢复配网
以上内容基本上涵盖了双模配网的流程和常见错误,如果有任何开发使用上的问题可以下方留言或者联系我们。
若您还对多设备批量配网、先扫描WiFi列表再进行配网等功能感兴趣,请持续关注!