You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:55:16