From 21f535bd59914f1e12f7302723cde8869f1fe9ad Mon Sep 17 00:00:00 2001 From: Christopher Date: Thu, 7 Mar 2024 23:33:24 +0100 Subject: [PATCH] Add "org.eclipse.paho" Mqtt Client --- .gitignore | 3 +- app/build.gradle.kts | 13 ++ app/src/main/AndroidManifest.xml | 18 ++- .../chrissthecoder/store/mqtt/MqttHandler.kt | 118 ++++++++++++++++++ 4 files changed, 141 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/de/chrissthecoder/store/mqtt/MqttHandler.kt diff --git a/.gitignore b/.gitignore index ab0568e..123bf59 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,8 @@ gen/ # Local configuration file (sdk path, etc) local.properties - +mqtt.properties + # Windows thumbnail db Thumbs.db diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ffb07ca..4f79d84 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,8 +1,14 @@ +import java.io.FileInputStream +import java.util.Properties + plugins { id("com.android.application") id("org.jetbrains.kotlin.android") } +val mqttProperties = Properties() +mqttProperties.load(FileInputStream(rootProject.file("mqtt.properties"))) + android { namespace = "de.chrissthecoder.store" compileSdk = 34 @@ -13,6 +19,11 @@ android { targetSdk = 34 versionCode = 1 versionName = "1.0" + + buildConfigField("String", "MQTT_USERNAME", mqttProperties.getProperty("username")) + buildConfigField("String", "MQTT_PASSWORD", mqttProperties.getProperty("password")) + buildConfigField("String", "MQTT_HOST", mqttProperties.getProperty("host")) + buildConfigField("String", "MQTT_PORT", mqttProperties.getProperty("port")) } buildTypes { @@ -36,6 +47,7 @@ android { buildFeatures { viewBinding = true + buildConfig = true } } @@ -48,4 +60,5 @@ dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0") implementation("androidx.navigation:navigation-fragment-ktx:2.7.7") implementation("androidx.navigation:navigation-ui-ktx:2.7.7") + implementation("org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index aa2e2e6..36f2f25 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,14 +1,14 @@ + xmlns:tools="http://schemas.android.com/tools"> + - + - - \ No newline at end of file diff --git a/app/src/main/java/de/chrissthecoder/store/mqtt/MqttHandler.kt b/app/src/main/java/de/chrissthecoder/store/mqtt/MqttHandler.kt new file mode 100644 index 0000000..7a84e20 --- /dev/null +++ b/app/src/main/java/de/chrissthecoder/store/mqtt/MqttHandler.kt @@ -0,0 +1,118 @@ +package de.chrissthecoder.store.mqtt + +import android.util.Log +import de.chrissthecoder.store.BuildConfig +import org.eclipse.paho.client.mqttv3.* + +class MqttHandler { + + companion object { + private const val LINE = "_________________________" + + private const val CONNECTION_TIMEOUT = 3 + private const val CONNECTION_KEEP_ALIVE_INTERVAL = 60 + private const val CONNECTION_CLEAN_SESSION = true + private const val CONNECTION_RECONNECT = true + } + + private val client: MqttClient + + init { + Log.d(this.javaClass.name, "Enter Initializer") + + val clientId: String = "Test Smartphone" + + val serverURL = "tcp://" + BuildConfig.MQTT_HOST + ":" + BuildConfig.MQTT_PORT + client = MqttClient(serverURL, clientId, null) + + Log.d(this.javaClass.name, "Set Mqtt Call-Back and Connect") + + client.setCallback(object : MqttCallbackExtended { + override fun connectionLost(cause: Throwable?) { + Log.w(this.javaClass.name, "Connection Lost") + } + + override fun messageArrived(topic: String?, message: MqttMessage?) { + Log.d(this.javaClass.name, "Message on Topic: \"" + topic + "\" Arrived") + val payload = message?.payload?.toString(Charsets.UTF_8) + } + + override fun deliveryComplete(token: IMqttDeliveryToken?) { + Log.d(this.javaClass.name, "Message successful delivered") + } + + override fun connectComplete(reconnect: Boolean, serverURI: String?) { + var message = "Successful " + if (reconnect) { message += "re" } + message += "connected to: " + serverURI?.let { Log.d(this.javaClass.name, message + it) } + } + }) + + Log.d(this.javaClass.name, "MQTT Credentials:") + Log.d(this.javaClass.name, LINE) + Log.d(this.javaClass.name, "Client ID: " + clientId) + Log.d(this.javaClass.name, "Server URL: " + serverURL) + Log.d(this.javaClass.name, "Username: " + BuildConfig.MQTT_USERNAME) + Log.d(this.javaClass.name, "Password: " + BuildConfig.MQTT_PASSWORD) + Log.d(this.javaClass.name, LINE) + + connect() + } + + private fun connect() { + try { + Log.d(this.javaClass.name, "Connecting to Broker...") + + // Set up the connection options + val mqttConnectOptions = MqttConnectOptions() + mqttConnectOptions.isAutomaticReconnect = CONNECTION_RECONNECT + mqttConnectOptions.isCleanSession = CONNECTION_CLEAN_SESSION + mqttConnectOptions.userName = BuildConfig.MQTT_USERNAME + mqttConnectOptions.password = BuildConfig.MQTT_PASSWORD.toCharArray() + mqttConnectOptions.connectionTimeout = CONNECTION_TIMEOUT + mqttConnectOptions.keepAliveInterval = CONNECTION_KEEP_ALIVE_INTERVAL + + client.connect(mqttConnectOptions) + } catch (ex: MqttException) { + handleConnectionFailure(ex) + } + } + + private fun handleConnectionFailure(cause: Throwable?) { + Log.w(this.javaClass.name,"Failed to connect: ${Log.getStackTraceString(cause)}") + } + + fun subscribe(topic: String, qos: Int = 0) { + try { + Log.d(this.javaClass.name, "Subscribe to Topic: $topic") + client.subscribe(topic, qos) + } catch (ex: MqttException) { + Log.e(this.javaClass.name,"Error on subscribing to Topic: $topic", ex) + } + } + + fun publish(topic: String, msg: String, qos: Int = 0, retained: Boolean = false) { + try { + val mqttMessage = MqttMessage(msg.toByteArray()) + client.publish(topic, mqttMessage.payload, qos, retained) + Log.d(this.javaClass.name, "Message published to topic `$topic`: $msg") + } catch (e: MqttException) { + Log.e(this.javaClass.name, "Error publishing to $topic: " + e.message, e) + } + } + + fun disconnect() { + try { + Log.d(this.javaClass.name, "Disconnecting from Broker...") + client.disconnect() + } catch (e: MqttException) { + Log.e(this.javaClass.name, "Error disconnection from Broker: " + e.message, e) + e.printStackTrace() + } + } + + fun isConnected(): Boolean { + return client.isConnected + } +} \ No newline at end of file