本系列IoT App开发笔记系b站视频教程学习笔记,视频地址:
- 【7天Java0基础速成安卓开发】Day1 Android工程代码是怎么运行的
- 【7天Java0基础速成安卓开发】Day2 常用控件和界面布局设计(上)
- 【7天Java0基础速成安卓开发】Day3 常用控件和界面布局设计(下)
- 【7天Java0基础速成安卓开发】Day4 MQTT Jar包的导入和物联网调试
- 【7天Java0基础速成安卓开发】Day5 APP物联网实战控制ESP8266
- 【7天Java0基础速成安卓开发】Day6 提前交卷(总结篇)
- 【7天Java0基础速成安卓开发】Day7 成果展示
1. 下载Jar包并导入到AS工程
jar包可以 从我的不限速下载站下载:
导入到方法非常简单,复制jar包到AS目录中的libs文件夹即可:
等待gradle同步完成,导入成功。
2. 开启网络权限
在AndroidManifest.xml文件中开启权限:
<!--允许程序打开网络套接字-->
<uses-permission android:name="android.permission.INTERNET" />
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
3. 基于MQTT Jar包编写函数
首先定义如下成员:
private MqttClient client;
private MqttConnectOptions options;
private String host = "tcp://122.51.89.94:1883";
private String userName = "android";
private String passWord = "android";
private String mqtt_id = "client-0002";
private Handler handler;
private ScheduledExecutorService scheduler;
3.1. MQTT初始化函数
//Mqtt初始化函数
private void Mqtt_init()
{
try {
//host为主机名,test为clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
client = new MqttClient(host, mqtt_id,
new MemoryPersistence());
//MQTT的连接设置
options = new MqttConnectOptions();
//设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
options.setCleanSession(false);
//设置连接的用户名
options.setUserName(userName);
//设置连接的密码
options.setPassword(passWord.toCharArray());
// 设置超时时间 单位为秒
options.setConnectionTimeout(10);
// 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
options.setKeepAliveInterval(20);
//设置回调
client.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
//连接丢失后,一般在这里面进行重连
System.out.println("connectionLost----------");
//startReconnect();
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
//publish后会执行到这里
System.out.println("deliveryComplete---------"
+ token.isComplete());
}
@Override
public void messageArrived(String topicName, MqttMessage message)
throws Exception {
//subscribe后得到的消息会执行到这里面
System.out.println("messageArrived----------");
Message msg = new Message();
if(topicName.equals("temp"))
{
//收到温度数据
msg.what = 3; //收到消息标志位
msg.obj = message.toString() + " ℃";
handler.sendMessage(msg); // hander 回传
}
else if (topicName.equals("humi"))
{
//收到湿度数据
msg.what = 4; //收到消息标志位
msg.obj = message.toString() + " %RPH";
handler.sendMessage(msg); // hander 回传
}
else if(topicName.equals("lightness"))
{
//收到亮度数据
msg.what = 5; //收到消息标志位
msg.obj = message.toString() + " Lux";
handler.sendMessage(msg); // hander 回传
}
else if(topicName.equals("gas"))
{
//收到气体数据
msg.what = 6; //收到消息标志位
msg.obj = message.toString() + " %";
handler.sendMessage(msg); // hander 回传
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
3.2. MQTT连接EMQ-X服务器函数
//MQTT连接EMQ-X函数
private void Mqtt_connect() {
new Thread(new Runnable() {
@Override
public void run() {
try {
if(!(client.isConnected()) ) //如果还未连接
{
client.connect(options);
Message msg = new Message();
msg.what = 31;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
Message msg = new Message();
msg.what = 30;
handler.sendMessage(msg);
}
}
}).start();
}
3.3. MQTT重连函数
//MQTT重连
private void startReconnect() {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (!client.isConnected()) {
Mqtt_connect();
}
}
}, 0 * 1000, 10 * 1000, TimeUnit.MILLISECONDS);
}
3.4. MQTT发布消息函数
//MQTT发布消息
private void publishmessageplus(String topic,String message2)
{
if (client == null || !client.isConnected()) {
return;
}
MqttMessage message = new MqttMessage();
message.setPayload(message2.getBytes());
try {
client.publish(topic,message);
} catch (MqttException e) {
e.printStackTrace();
}
}
4. 使用handle处理MQTT接收回调逻辑
之前编写的MQTT函数放在onCreate函数中执行:
Mqtt_init();
startReconnect();
逻辑处理代码放在onCreate函数中执行:
handler = new Handler() {
@SuppressLint("SetTextI18n")
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1: //开机校验更新回传
break;
case 2: // 反馈回传
break;
case 3: //MQTT 收到消息回传 UTF8Buffer msg=new UTF8Buffer(object.toString());
//Toast.makeText(MainActivity.this,msg.obj.toString() ,Toast.LENGTH_SHORT).show();
temp_text_view.setText(msg.obj.toString());
break;
case 4: //MQTT 收到消息回传 UTF8Buffer msg=new UTF8Buffer(object.toString());
//Toast.makeText(MainActivity.this,msg.obj.toString() ,Toast.LENGTH_SHORT).show();
humi_text_view.setText(msg.obj.toString());
break;
case 5: //MQTT 收到消息回传 UTF8Buffer msg=new UTF8Buffer(object.toString());
//Toast.makeText(MainActivity.this,msg.obj.toString() ,Toast.LENGTH_SHORT).show();
lightness_text_view.setText(msg.obj.toString());
break;
case 6: //MQTT 收到消息回传 UTF8Buffer msg=new UTF8Buffer(object.toString());
//Toast.makeText(MainActivity.this,msg.obj.toString() ,Toast.LENGTH_SHORT).show();
gas_text_view.setText(msg.obj.toString());
break;
case 30: //连接失败
Toast.makeText(MainActivity.this,"连接失败" ,Toast.LENGTH_SHORT).show();
break;
case 31: //连接成功
Toast.makeText(MainActivity.this,"连接成功" ,Toast.LENGTH_SHORT).show();
try {
//订阅温度数据
client.subscribe("temp",1);
//订阅湿度数据
client.subscribe("humi",1);
//订阅亮度数据
client.subscribe("lightness",1);
//订阅气体数据
client.subscribe("gas",1);
} catch (MqttException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
};
5. 发布JSON数据
在按钮的回调函数中,将文本框的值封装为JSON格式发送,并检测异常:
//设置温度最大按钮回调函数
max_temp_set_btn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
try{
String max_temp_str = max_temp_edittext.getText().toString();
int max_temp_value = Integer.valueOf(max_temp_str);
String max_temp_json = "{\"name\":\"max_temp\",\"max_temp\":"+String.valueOf(max_temp_value)+"}"; //{"name":"max_temp","max_temp":"23"}
publishmessageplus("sub_test",max_temp_json);
Toast.makeText(MainActivity.this, max_temp_json,Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Toast.makeText(MainActivity.this, "设置失败,请输入正确整数值",Toast.LENGTH_SHORT).show();
}
}
});
接收更多精彩文章及资源推送,欢迎订阅我的微信公众号:『mculover666』。