玩转OneNET物联网平台之MQTT服务⑦ —— 远程控制LED(数量无限制)+ Android App控制 优化第一版
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。
QQ技术互动交流群:ESP8266&32 物联网开发 群号622368884,不喜勿喷
一、你如果想学基于Arduino的ESP8266开发技术
一、基础篇
二、网络篇
- ESP8266开发之旅 网络篇① 认识一下Arduino Core For ESP8266
- ESP8266开发之旅 网络篇② ESP8266 工作模式与ESP8266WiFi库
- ESP8266开发之旅 网络篇③ Soft-AP——ESP8266WiFiAP库的使用
- ESP8266开发之旅 网络篇④ Station——ESP8266WiFiSTA库的使用
- ESP8266开发之旅 网络篇⑤ Scan WiFi——ESP8266WiFiScan库的使用
- ESP8266开发之旅 网络篇⑥ ESP8266WiFiGeneric——基础库
- ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client
- ESP8266开发之旅 网络篇⑧ SmartConfig——一键配网
- ESP8266开发之旅 网络篇⑨ HttpClient——ESP8266HTTPClient库的使用
- ESP8266开发之旅 网络篇⑩ UDP服务
- ESP8266开发之旅 网络篇⑪ WebServer——ESP8266WebServer库的使用
- ESP8266开发之旅 网络篇⑫ 域名服务——ESP8266mDNS库
- ESP8266开发之旅 网络篇⑬ SPIFFS——ESP8266 Flash文件系统
- ESP8266开发之旅 网络篇⑭ web配网
- ESP8266开发之旅 网络篇⑮ 真正的域名服务——DNSServer
- ESP8266开发之旅 网络篇⑯ 无线更新——OTA固件更新
三、应用篇
四、高级篇
1.前言
在前面的博文 玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(数量无限制)+ Android App控制 中,博主只是大体上讲述了整个小项目的构造。但是,如果作为一个产品来开发的话,还是存在不少问题。这里罗列几个我认为比较重要的问题点:
- 问题1:App作为一个特殊的设备,理论上也应该支持自注册功能,不应该由开发者或者用户额外去调用API调试工具创建设备,起码得简化这个流程;
- 问题2:App没有处理设备从在线状态切换成离线状态的过程,需要实时更新设备状态;
接下来,博主就会针对这两个重要的问题点进行解决思路以及解决步骤的讲解,请读者边思考边实验。
2.解决问题点1
App作为一个特殊的设备,理论上也应该支持自注册功能,不应该由开发者或者用户额外去调用API调试工具创建设备,起码得简化这个流程
2.1 解决思路
- 我们目的无非是为了得到一个真实存在的DeviceID,既然OneNet 平台给我们提供了 新增设备 的API,那么我们可以通过它来创建设备并且获取设备ID。

因为创建设备需要设备唯一性标识,而android手机上唯一性东西非常多,我们这里考虑用设备序列号
Android系统2.3版本以上可以通过下面的方法得到Serial Number,且非手机设备也可以通过该接口获取。
String serial= android.os.Build.SERIAL;

2.2 解决步骤
- 修改app逻辑,加上注册方法
/**
* 新增OneNet设备
*/
public class RegisterOneNetDeviceEntity extends BaseResponseEntity {
public dataModel data;
public static class dataModel{
public String device_id;
}
@Override
protected String createArgs(Object... params) {
OneNetDeviceModel model = (OneNetDeviceModel) params[0];
JSONObject object = new JSONObject();
try {
object.put("title",model.getTitle());
object.put("auth_info",model.getAuth_info());
} catch (JSONException e) {
e.printStackTrace();
}
return object.toString();
}
@Override
protected String makeUrl() {
return API_POST_REGISTER_DEVICE;
}
public String request(OneNetDeviceModel model) {
method = HttpUtilCore.Method.Post;
String json = requestJson(model);
//内部消化
return handleResponse(json, new OnResponseListener<RegisterOneNetDeviceEntity>() {
@Override
public void onSuccess(String json, RegisterOneNetDeviceEntity response) {
data = response.data;
}
@Override
public void onFailed(String reason) {
Logger.d(reason);
}
@Override
public void onTimeout() {
Logger.d("请求超时");
}
});
}
}
- 用户点击注册,加上设备序列号
@Override
public void onInitView(Bundle savedInstanceState) {
PreferenceUtil preference = PreferenceUtil.getInstance();
if(!TextUtils.isEmpty(preference.getDeviceId())){
this.onConfigConfirm();
return;
}
getDefaultNavigation().setTitle("配置智能灯");
getDefaultNavigation().getLeftButton().hide();
etDevice.setText("Android_" + android.os.Build.SERIAL);
etProduct.setText(preference.getProductId());
etApikey.setText(preference.getApiKey());
}
- 新增成功之后,存储服务器返回的device_id
@Override
public void register(Context context, final OneNetConfigDALEx config, final ICallBack<String> callBack) {
if(task != null && task.getStatus()== AsyncTask.Status.RUNNING){
task.cancel(true);
}
task = new SimpleTask() {
OneNetDeviceModel device;
RegisterOneNetDeviceEntity entity;
@Override
protected void onPreExecute() {
PreferenceUtil preference = PreferenceUtil.getInstance();
preference.writePreferences(PreferenceUtil.ApiKey,config.getApikey());
preference.writePreferences(PreferenceUtil.ProductId,config.getProductId());
entity = new RegisterOneNetDeviceEntity();
device = new OneNetDeviceModel();
device.setTitle(config.getDeviceId());
device.setAuth_info(config.getDeviceId());
}
@Override
protected Object doInBackground(String... strings) {
return entity.request(device);
}
@Override
protected void onPostExecute(Object o) {
String result = (String) o;
PreferenceUtil preference = PreferenceUtil.getInstance();
if("200".equals(result)){//保存设备id
preference.writePreferences(PreferenceUtil.DeviceId,entity.data.device_id);
callBack.onSuccess("");
}else {
callBack.onFaild(result);
}
}
};
task.startTask();
- 这样就完成了手机自注册设备功能

这种方案有个好处就是:
- 非常适合多个成员同时控制一组智能灯,并且不会产生掉线的情况。
但是,请读者注意:
如果你先注册了一次,然后卸载app,再重新注册,这个时候会失败的(原因请读者自行分析)。这个时候请到后台手动删除Android_xxxx的设备。
3.解决问题点2
- 问题点:App没有处理设备从在线状态切换成离线状态的过程,需要实时更新设备状态
3.1 解决方案
目前大概有几种方案:
- 方案a:手机端不断轮询批量获取设备列表接口,可以设置较大的时间间隔,这个方案准确性高,但是耗费流量。目前这个方案相对靠谱。
- 方案b:esp8266端发布设备状态topic和信息,手机端订阅该topic,通过mqtt来更新状态;
- 方案c:利用mqtt的遗嘱消息,但是这个博哥验证了OneNet的,感觉不好用。
- 方案d:如果mqtt的遗嘱消息比较快速实时,可以考虑方案b+c的组合,个人觉得这个是比较理想的方案。(不过,目前我还没有很好实现)
- 方案e:本项目不追求实时性,我们可以手动下拉刷新或者在activity的onshow自动刷一遍,基本上满足要求,采取该方案。
4.总结
- 问题1:App作为一个特殊的设备,理论上也应该支持自注册功能,不应该由开发者或者用户额外去调用API调试工具创建设备,起码得简化这个流程;可以解决。
- 问题2:App没有处理设备从在线状态切换成离线状态的过程,需要实时更新设备状态;赞未完美解决,只能兜底方案。
- 但是,我们离产品化越来越近了。
玩转OneNET物联网平台之MQTT服务⑦ —— 远程控制LED(数量无限制)+ Android App控制 优化第一版的更多相关文章
- 玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(设备自注册)+ Android App控制
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之MQTT服务③ —— 远程控制LED(设备自注册)
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之MQTT服务② —— 远程控制LED
1.理论基础 参考博主线上博文: 玩转PubSubClient MQTT库 玩转OneNET物联网平台之简介 玩转OneNET物联网平台之MQTT服务① 2.远程控制LED 2.1 实验材料 ...
- 玩转OneNET物联网平台之MQTT服务⑤ —— OneNet智能灯+MVP框架
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之MQTT服务① —— OneNetMqtt全方位调试
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之HTTP服务③ —— OneNet智能灯 HTTP版本
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之HTTP服务① —— 模拟上传温度(TcpClient)
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之简介
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- HelloX操作系统与中国移动OneNET物联网平台成功完成对接
HelloX成功与中国移动物联网平台对接 经过HelloX项目组同仁的努力,尤其是Tywin(@飓风)的努力下,HelloX最新版本V1.78已成功与中国移动OneNET(open.iot.10086 ...
随机推荐
- WordPress对接微信小程序遇到的问题
1.文章内容中的“<”和“>”字符显示问题 小程序是使用“wxPares工具来实现html转wxml的,如果你的文本包含了代码比如xml会携带<>符号,程序会将其转化,造成解析 ...
- 第六届蓝桥杯java b组第五题
九数组分数 1,2,3…9 这九个数字组成一个分数,其值恰好为1/3,如何组法? 下面的程序实现了该功能,请填写划线部分缺失的代码. public class A { public static vo ...
- WPF中资源的引用方法
一.引用同一个程序中的资源 1.使用相对Uri来引用资源,如下所示 img.Source=new BitmapImage(new Uri(@"d"\iamges\Backgroun ...
- Linux中安装传输的命令行工具
创建lrzsz目录: mkdir /usr/local/lrzsz 进入lrzsz目录: cd /usr/local/lrzsz 下载lrzsz压缩包: wget http://www.ohse.de ...
- Spring boot 官网学习笔记 - Spring DevTools 介绍
想要使用devtools支持,只需使用dependencies将模块依赖关系添加到你的构建中 运行打包的应用程序时,开发人员工具会自动禁用.如果你通过 java -jar或者其他特殊的类加载器进行启动 ...
- ajax跨域问题以及解决方案
转:https://blog.csdn.net/csdn_ds/article/category/6937392/3 在工作中,大家应该都遇到过ajax跨域问题,浏览器的错误如下: XMLHttpRe ...
- windows下配置多个tomcat步骤
步骤如下: 1.使用压缩版的tomcat不能使用安装版的.2.第一个tomcat的配置不变.3.增加环境变量CATALINA_HOME2,值为新的tomcat的地址:增加环境变量CATALINA_BA ...
- Java中的static(1)【持续更新】——关于Eclipse的No enclosing instance of type ... 错误的理解和改正
No enclosing instance of type SomeClass is accessible. Must qualify the allocation with an enclosing ...
- js常用Matn函数的操练
Math.PI console.log(Math.PI); 随机数以及向下取整 这是一个能实现从a-b之间随机打印一个整数 function rand_s(a, b) { var x = a + (b ...
- Angular: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as ‘standalone’ in ngModelOptions.
在Angular中,动态生成的Html控件,如果没有name属性并且在ts中要操作Model的内容.就会引发如题的错误. 解决方案两个: 加上name的属性 设置ngModelOptions [n ...