0

I'm making an android application to communicate with a bicycle security system using android studio. The application is using the MQTT protocol to talk to a remote server which will act as the broker and relay messages to the security system which has a microcontroller and a GSM module that allows for an internet connection.

The problem I'm experiencing relates to the Eclipse Paho Mqtt Android Client. This is a neat library that contains functions to implement the MQTT protocol. So far I've managed to establish a connection between the server and the application. It least that's what it looks like. See the following image which shows my logcat messages.The logcat messages in Android Studio

It definitely appears to be connected, its pinging once a minute. The only problem is that when I try to verify that the connection is there using the isConnected function, it always tells me that I'm not connected. Below you can see my code. If you need to download the library or if you want to look at it, here is a link -> https://github.com/eclipse/paho.mqtt.android

Also, I would like to explain my code a little so you know what you're looking at. Please read this carefully.

It is in Kotlin. I made a Client_MQTT class that is instantiated in the main activity. This class holds an instance of the MqttAndroidClient (this is from the paho library). This instance is instantiated in the constructor and it's named MqttClient. There is a connect function which does all the busy work and connects to the server. There's also a function called ConnectionAlive. The only thing it does is return MqttClient.isConnected().

The other portion of my code is the MainActivity where the Client_MQTT class is instantiated and the connect function is called. Most importantly, this is where I do a simple if check to see if the connection is alive. It always says no, but I know that can't be right.

Now you may see the code.

package com.chymera_security.application

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.IMqttActionListener
import org.eclipse.paho.client.mqttv3.IMqttToken
import org.eclipse.paho.client.mqttv3.MqttException
import org.eclipse.paho.client.mqttv3.MqttClient
import androidx.core.app.ComponentActivity.ExtraData
import androidx.core.content.ContextCompat.getSystemService
import android.icu.lang.UCharacter.GraphemeClusterBreak.T
import androidx.fragment.app.FragmentActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    var Client = Client_MQTT(this.getApplicationContext()) //passing in the context
    //var client = MqttAndroidClient(this.getApplicationContext(), "tcp://io.adafruit.com:1883",
    //   ConnectThis.ClientId)
    Client.connect()
    if (Client.ConnectionAlive()) {
     ViewAlarmStatus.text = "Connected to server." //You can replace this with a simple log statement
    } else {
      ViewAlarmStatus.text = "Not connected to server."
    }
  }
}

-

package com.chymera_security.application

import android.content.Context
import android.util.Log
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.*

class Client_MQTT constructor(context_param: Context){

  internal var options = MqttConnectOptions()
    internal lateinit var ClientId : String
    internal lateinit var MqqtClient: MqttAndroidClient
    internal lateinit var context : Context

    init {
      options.userName = "Put your username here"
      options.password = "password here".toCharArray()
      ClientId = MqttClient.generateClientId()
      context = context_param
      MqqtClient = MqttAndroidClient(context, "tcp://io.adafruit.com:1883", ClientId)
  }

  fun connect() {
    try {
      val token = MqqtClient.connect(options)
      token.actionCallback = object : IMqttActionListener {
        override fun onSuccess(asyncActionToken: IMqttToken) {
          Log.i("Connection", "Connected to server ")
          //connectionStatus = true
          // Give your callback on connection established here
        }
        override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
          //connectionStatus = false
          Log.i("Connection", "failure")
          // Give your callback on connection failure here
          exception.printStackTrace()
        }
      }
    } catch (e: MqttException) {
      // Give your callback on connection failure here
      e.printStackTrace()
    }

  }
  fun ConnectionAlive (): Boolean{
    return MqqtClient.isConnected()
  }
}

If you have any knowledge about this please share. Am I actually connected to the server? It looks like it but the isConnected doesn't agree. Is there some conceptual misunderstanding about how I'm using isConnected? Am I just using it wrong, or is this some crazy bug? Would love to hear from you.

Extra resources: https://medium.com/@chaitanya.bhojwani1012/eclipse-paho-mqtt-android-client-using-kotlin-56129ff5fbe7

https://www.hivemq.com/blog/mqtt-client-library-enyclopedia-paho-android-service/

1 Answer 1

0

So it turns out that the problem was not the isConnected() function. The problem was that I was checking whether it was connected too soon. The connect function is asynchronous, meaning that it executes in the background. So while it was trying to connect, I was asking it if it was connected before it was finished. To fix this, I added an onClickListener to one of my buttons and checked the status just by pressing the button a few seconds after the app started.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.