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.
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/