Android MQTT应用控件不显示及Mosquitto Broker连接失败问题求助
问题1:Android控件无法在屏幕上显示
原因分析
布局XML中所有控件同时使用了android:layout_alignParentStart、android:layout_alignParentTop、android:layout_alignParentEnd、android:layout_alignParentBottom四个属性,导致RelativeLayout无法正确计算控件位置,控件可能重叠或被挤压到不可见区域。
修复后的布局代码
改用清晰的RelativeLayout定位逻辑,避免冲突属性:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MQTTMain"> <TextView android:id="@+id/subText" android:layout_width="202dp" android:layout_height="70dp" android:layout_centerHorizontal="true" android:layout_marginTop="204dp" android:text="@string/textview" android:visibility="visible" tools:visibility="visible" /> <Button android:id="@+id/button" android:layout_width="107dp" android:layout_height="wrap_content" android:layout_below="@id/subText" android:layout_alignParentEnd="true" android:layout_marginTop="100dp" android:layout_marginEnd="42dp" android:text="@string/subscribe" android:visibility="visible" tools:visibility="visible" /> <Button android:id="@+id/button2" android:layout_width="110dp" android:layout_height="wrap_content" android:layout_below="@id/subText" android:layout_alignParentStart="true" android:layout_marginTop="100dp" android:layout_marginStart="60dp" android:text="@string/publish" android:visibility="visible" tools:visibility="visible" /> </RelativeLayout>
问题2:应用无法连接Mosquitto Broker
原因分析
可能存在以下问题:
- 缺少必要的网络权限和MQTT服务注册
- 连接参数配置不完整
- 设备与Broker不在同一局域网,或Broker未开放外部连接
- 非主线程更新UI导致潜在异常
解决方案
1. 补充权限和服务注册
在AndroidManifest.xml中添加:
<!-- 网络权限 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 在<application>标签内注册MQTT服务 --> <service android:name="org.eclipse.paho.android.service.MqttService" />
2. 完善MQTT连接逻辑
修改Java代码,添加连接选项并修复线程问题:
package com.example.MQTTMain; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.TextView; import android.widget.Toast; import org.eclipse.paho.android.service.MqttAndroidClient; import org.eclipse.paho.client.mqttv3.IMqttActionListener; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; import org.eclipse.paho.client.mqttv3.IMqttToken; import org.eclipse.paho.client.mqttv3.MqttCallback; import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; import java.nio.charset.StandardCharsets; public class MQTTMain extends AppCompatActivity { MqttAndroidClient client; TextView subText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_m_q_t_t); subText = findViewById(R.id.subText); String clientId = MqttClient.generateClientId(); client = new MqttAndroidClient(this.getApplicationContext(), "tcp://192.168.1.7:1883", clientId); // 配置连接选项 MqttConnectOptions options = new MqttConnectOptions(); options.setCleanSession(true); // 若Broker需用户名密码,取消注释并填写 // options.setUserName("your_username"); // options.setPassword("your_password".toCharArray()); try { IMqttToken token = client.connect(options); token.setActionCallback(new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { Toast.makeText(MQTTMain.this, "CONNECTED!!", Toast.LENGTH_LONG).show(); setSubscription(); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Toast.makeText(MQTTMain.this, "CONNECTION FAILED!!: " + exception.getMessage(), Toast.LENGTH_LONG).show(); exception.printStackTrace(); } }); } catch (MqttException e) { e.printStackTrace(); Toast.makeText(this, "Connection error: " + e.getMessage(), Toast.LENGTH_LONG).show(); } client.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable cause) { Toast.makeText(MQTTMain.this, "Connection lost: " + cause.getMessage(), Toast.LENGTH_LONG).show(); } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { // 切换到主线程更新UI runOnUiThread(() -> { subText.setText(new String(message.getPayload(), StandardCharsets.UTF_8)); }); } @Override public void deliveryComplete(IMqttDeliveryToken token) {} }); } public void published(View v){ String topic = "EVENT"; String message = "the payload"; try { client.publish(topic, message.getBytes(StandardCharsets.UTF_8),0,false); Toast.makeText(this,"Published Message",Toast.LENGTH_SHORT).show(); } catch ( MqttException e) { e.printStackTrace(); } } private void setSubscription(){ try{ client.subscribe("EVENT",0); }catch (MqttException e){ e.printStackTrace(); } } public void conn(View v){ try { MqttConnectOptions options = new MqttConnectOptions(); options.setCleanSession(true); IMqttToken token = client.connect(options); token.setActionCallback(new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { Toast.makeText(MQTTMain.this,"connected!!",Toast.LENGTH_LONG).show(); setSubscription(); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Toast.makeText(MQTTMain.this,"connection failed!!",Toast.LENGTH_LONG).show(); } }); } catch (MqttException e) { e.printStackTrace(); } } public void disconn(View v){ try { IMqttToken token = client.disconnect(); token.setActionCallback(new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { Toast.makeText(MQTTMain.this,"DISCONNECTED!!",Toast.LENGTH_LONG).show(); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Toast.makeText(MQTTMain.this,"Could not disconnect!!",Toast.LENGTH_LONG).show(); } }); } catch (MqttException e) { e.printStackTrace(); } } }
3. 检查Broker与网络
- 修改Mosquitto配置文件
mosquitto.conf,添加listener 1883 0.0.0.0并注释listener 1883 127.0.0.1,允许外部连接 - 确认设备与Broker在同一局域网,用ping命令测试
192.168.1.7可达性 - 启动Broker时执行
mosquitto -v查看运行日志,确认服务正常
内容的提问来源于stack exchange,提问作者Dirk
相关产品推荐
相关产品推荐

