Android中MQTT的简单实现(只是连接到服务器,未实现发送、接受信息)

1.添加mqtt包到gradle.build

a.在project的gradle.build中添加地址(P:我下载的参考例子是不用添加的,但是我自己写的时候不添加就编译不过去)

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
        }
    }
}

b.在app的gradle.build中添加MQTT的依赖

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
}

2.在AndroidMenifest.xml中添加权限和service

(P:那个WAKE_LOCK,ACCESS_NETWORK_STATE权限和service一定要添加,之前参考网上的例子写的时候没有注意到要添加service,启动mqtt.connect一直返回连接失败,打印失败信息报cannot start service org.eclipse.paho.android.service.MqttService,然后添加了service又报WAKE_LOCK,ACCESS_NETWORK_STATE权限安全错误,所以一定要注意添加它们)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.chenss.baselib">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="org.eclipse.paho.android.service.MqttService">
        </service>
    </application>

 3.布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/host"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入URl:格式tcp://ip地址"
        android:layout_marginTop="5dp"
        android:padding="20dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/port"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入端口号"
        android:layout_marginTop="5dp"
        android:padding="20dp"
        app:layout_constraintTop_toBottomOf="@+id/host"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>

    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/clientId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入clientId"
        android:layout_marginTop="5dp"
        android:padding="20dp"
        app:layout_constraintTop_toBottomOf="@+id/port"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>
    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/userName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入用户名"
        android:layout_marginTop="5dp"
        android:padding="20dp"
        app:layout_constraintTop_toBottomOf="@+id/clientId"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>

    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/passWord"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入密码"
        android:layout_marginTop="5dp"
        android:padding="20dp"
        app:layout_constraintTop_toBottomOf="@+id/userName"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>

    <Button
        android:id="@+id/connect"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="连接"
        android:background="@color/colorAccent"
        android:layout_marginTop="5dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/passWord" />

</android.support.constraint.ConstraintLayout>

4 .实现代码:MainActivity

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @BindView(R.id.host)
    AppCompatEditText host;

    @BindView(R.id.port)
    AppCompatEditText port;

    @BindView(R.id.clientId)
    AppCompatEditText clientId;


    @BindView(R.id.connect)
    Button connect;

    @BindView(R.id.userName)
    AppCompatEditText userName;
    @BindView(R.id.passWord)
    AppCompatEditText passWord;

    private MqttAndroidClient mClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(MainActivity.this);
    }

    @OnClick(R.id.connect)
    public void onViewClicked() {
        if (check()) {
           connect();
        }
    }

    private void connect() {
       String serUrl =getServerURI(host.getText().toString(), port.getText().toString());
        connect.setText("正在连接");
        //serUrl为主机名,clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
        mClient = new MqttAndroidClient(MyApplication.getContext(), serUrl, clientId.getText().toString(),new MemoryPersistence());
        //设置回调
        mClient.setCallback(mqttCallbackExtended);

        try {
            mClient.connect(getMqttConnectOptions(), "Connect", iMqttActionListener);
        } catch (MqttException ex) {
            ex.printStackTrace();
        }
    }


    private boolean check() {
        if (TextUtils.isEmpty(host.getText().toString())) {
            Toast.makeText(MainActivity.this, "host不能为空", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (TextUtils.isEmpty(port.getText().toString())) {
            Toast.makeText(MainActivity.this, "port不能为空", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (TextUtils.isEmpty(clientId.getText().toString())) {
            Toast.makeText(MainActivity.this, "clientIds不能为空", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (TextUtils.isEmpty(userName.getText().toString())) {
            Toast.makeText(MainActivity.this, "userName不能为空", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (TextUtils.isEmpty(passWord.getText().toString())) {
            Toast.makeText(MainActivity.this, "passWord不能为空", Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

    private MqttCallbackExtended mqttCallbackExtended = new MqttCallbackExtended() {
        @Override
        public void connectComplete(boolean reconnect, String serverURI) {
            //连接丢失后,一般在这里面进行重连
            if (reconnect) {
                Log.e(TAG, "Reconnected to : " + serverURI);
                connect.setText("连接成功");
            } else {
                Log.e(TAG, "Connected to: " + serverURI);
                connect.setText("连接成功");
            }
        }

        @Override
        public void connectionLost(Throwable cause) {
            Log.e(TAG, "The Connection was lost.");
        }

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            //subscribe后得到的消息会执行到这里面
            Log.e(TAG, "Incoming message: " + new String(message.getPayload()));
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {
            //publish后会执行到这里
        }
    };

    private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
        @Override
        public void onSuccess(IMqttToken asyncActionToken) {
            Log.e(TAG, "onSuccess!");
            connect.setText("连接成功");
        }

        @Override
        public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
            Log.e(TAG, "exception: " + exception.getMessage());
            connect.setText("连接失败");
        }
    };

    public String getServerURI(String host,String port) {
        return "tcp://" + host + ":" + port;
    }

    //MQTT的连接设置
    public MqttConnectOptions getMqttConnectOptions() {
        MqttConnectOptions options = new MqttConnectOptions();
        //设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
        options.setCleanSession(true);
        // 设置超时时间 单位为秒
        options.setConnectionTimeout(10);
        // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
        options.setKeepAliveInterval(20);
        //设置连接的用户名
        options.setUserName(userName.getText().toString().trim());
        //设置连接的密码
        options.setPassword(passWord.getText().toString().trim().toCharArray());
        return options;
    }

    @Override
    protected void onDestroy() {
        try {
            if (mClient!=null&&mClient.isConnected()){
                mClient.disconnect();
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }
}

猜你喜欢

转载自blog.csdn.net/css33/article/details/82218864