Intergrate Android MQTT Plugin AAR in Unity - Vordergrunddienst [geschlossen]C#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Intergrate Android MQTT Plugin AAR in Unity - Vordergrunddienst [geschlossen]

Post by Anonymous »

Ich versuche, Code im Hintergrund auf Android für ein Einheitsprojekt auszuführen. Da Unity nicht direkt Hintergrunddienste zulässt, habe ich eine Android -Bibliothek (AAR) erstellt und sie in Unity integriert. Dort funktioniert es korrekt. modules androidManifest.xml. Plugin. < /p>
Der Code und die Abhängigkeiten funktionieren in der eigenständigen App. Einheit?

Code: Select all

plugins {
alias(libs.plugins.android.library)
}

android {
namespace = "com.beezy.mqttlib"
compileSdk = 34

defaultConfig {
minSdk = 24

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}

dependencies {

implementation(libs.appcompat)
implementation(libs.material)
implementation("org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5")
implementation("org.eclipse.paho:org.eclipse.paho.android.service:1.1.1")
implementation ("androidx.localbroadcastmanager:localbroadcastmanager:1.1.0")
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
}
< /code>
Modul des Moduls < /p>
















< /code>
FORECORGMQTTService.java
package com.beezy.mqttlib;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.os.VibrationEffect;

import android.os.Vibrator;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
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.MqttCallbackExtended;
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.util.ArrayList;

public class ForegroundMqttService extends Service {

private static final String TAG = "ForegroundMqttService";
private static final String CHANNEL_ID = "MQTTServiceChannel";
private static final String BROKER_URI = "tcp://broker.hivemq.com:1883";

// Service States
private enum ServiceState { CONNECTED, DISCONNECTED, STOPPED }
private ServiceState currentState = ServiceState.STOPPED;

private MqttAndroidClient mqttClient;
private ArrayList  subscribedTopics = new ArrayList();

private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "MQTT Foreground Service", NotificationManager.IMPORTANCE_LOW);
NotificationManager manager = getSystemService(NotificationManager.class);
if (manager != null) manager.createNotificationChannel(channel);
}
}

private Notification buildNotification(String content) {
Intent stopIntent = new Intent(this, ForegroundMqttService.class).setAction("ACTION_STOP");
PendingIntent stopPendingIntent = PendingIntent.getService(this, 0, stopIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
return new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Beezy MQTT Service")
.setContentText(content)
.setSmallIcon(R.drawable.ic_notification)
.setOngoing(true)
.addAction(R.drawable.ic_notification, "Stop", stopPendingIntent)
.build();
}

private void updateNotification(String text) {
NotificationManager manager = getSystemService(NotificationManager.class);
if (manager != null) manager.notify(1, buildNotification(text));
}

private void notifyActivityStatus(String status) {
Intent intent = new Intent("MQTT_EVENTS");
intent.putExtra("subscribed", false);
intent.putExtra("statusText", status);
sendBroadcast(intent);
}

private void initMqttClient() {
if (mqttClient != null && (mqttClient.isConnected() || mqttClient.isConnected())) return;
String clientId = MqttClient.generateClientId();
mqttClient = new MqttAndroidClient(getApplicationContext(), BROKER_URI, clientId);
mqttClient.setCallback(new MqttCallbackExtended() {
@Override
public void connectComplete(boolean reconnect, String serverURI) {
currentState = ServiceState.CONNECTED;
updateNotification("Connected to broker");
notifyActivityStatus("Connected & Subscribed");
resubscribeAllTopics();
}

@Override
public void connectionLost(Throwable cause) {
if (currentState != ServiceState.STOPPED && currentState != ServiceState.DISCONNECTED) {
currentState = ServiceState.DISCONNECTED;
updateNotification("Connection lost. Reconnecting...");
notifyActivityStatus("Connection lost.  Reconnecting...");
}
}

@Override
public void messageArrived(String topic, MqttMessage message) {
String payload = new String(message.getPayload());
updateNotification("Last msg: " + payload);

handleMqttPayload(payload);

// Send broadcast to activity
Intent intent = new Intent("MQTT_EVENTS");
intent.putExtra("payload", payload);
sendBroadcast(intent);
}

private void handleMqttPayload(String payload) {
// Split into sections by %
String[] parts = payload.split("%");

// Just for debugging – you’ll see all parts
for (int i = 0; i < parts.length; i++) {
Log.d("MQTT_PART", "Index " + i + ": " + parts[i]);
}

// The "false/true" flag is always at index 2 of the last block:
// Example last block: "step0", "false", "prog0", "dates0|0", "sec-1", "2"
// So index of "false"/"true" is always parts[length-5] (based on your example).

if (parts.length > 2) {
String flag = parts[5]; // = Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(
150,  // vibration duration in ms
VibrationEffect.DEFAULT_AMPLITUDE
));
} else {
vibrator.vibrate(150);  // deprecated but works on older devices
}
}
}

@Override
public void deliveryComplete(IMqttDeliveryToken token) {}
});
}

private void connectToBroker() {
if (mqttClient == null) initMqttClient();
if (mqttClient.isConnected() || mqttClient.isConnected()) return;
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
options.setAutomaticReconnect(true);
try {
mqttClient.connect(options, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
currentState = ServiceState.CONNECTED;
updateNotification("Connected to broker");
resubscribeAllTopics();
}

@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.e(TAG, "Connection failed: " + exception.getMessage());
updateNotification("Connection failed.  Retrying...");
currentState = ServiceState.DISCONNECTED;
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}

private void resubscribeAllTopics() {
if (mqttClient != null && mqttClient.isConnected()) {
for (String topic : subscribedTopics) {
try {
mqttClient.subscribe(topic, 1);
} catch (MqttException e) {
Log.e(TAG, "Failed to subscribe to topic: " + topic);
}
}
Intent subIntent = new Intent("MQTT_EVENTS");
subIntent.putExtra("subscribed", true);
sendBroadcast(subIntent);
}
}

private void disconnectMqttOnly() {
try {
if (mqttClient != null && mqttClient.isConnected()) {
mqttClient.disconnect();
updateNotification("MQTT disconnected, service running");
notifyActivityStatus("Disconnected from MQTT");
}
} catch (MqttException e) {
e.printStackTrace();
}
}

private void stopAndDestroyService() {
currentState = ServiceState.STOPPED;
notifyActivityStatus("Service stopped");
if (mqttClient != null) {
try {
if (mqttClient.isConnected()) mqttClient.disconnect();
mqttClient.close();
} catch (Exception e) {
Log.e(TAG, "Error disconnecting MQTT client: " + e.getMessage());
}
}
stopSelf();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && intent.getAction() != null) {
// Retrieve the topics list from the intent
ArrayList topicsFromIntent = intent.getStringArrayListExtra("topics");
if (topicsFromIntent != null) {
subscribedTopics = topicsFromIntent;
}

switch (intent.getAction()) {
case "ACTION_START":
startServiceAndConnect();
break;
case "ACTION_DISCONNECT":
if (currentState == ServiceState.STOPPED) {
startServiceAndDoNotConnect();
} else if (currentState == ServiceState.CONNECTED) {
currentState = ServiceState.DISCONNECTED;
disconnectMqttOnly();
updateNotification("Service running (not connected)");
notifyActivityStatus("Service running (not connected)");
}
break;
case "ACTION_STOP":
stopAndDestroyService();
break;
case "ACTION_SUBSCRIBE":
String topic = intent.getStringExtra("topic");
if (topic != null && !subscribedTopics.contains(topic)) {
subscribedTopics.add(topic);
subscribeToTopic(topic);
}
break;
case "ACTION_UNSUBSCRIBE":
String unsubscribeTopic = intent.getStringExtra("topic");
subscribedTopics.remove(unsubscribeTopic);
break;
}
} else {
// First launch scenario or no intent data
startServiceAndConnect();
}

return START_STICKY;
}

private void startServiceAndConnect() {
initMqttClient();
connectToBroker();
startForeground(1, buildNotification("Connecting..."));
}

private void startServiceAndDoNotConnect() {
initMqttClient();
currentState = ServiceState.DISCONNECTED;
updateNotification("Service running (not connected)");
notifyActivityStatus("Service running (not connected)");
startForeground(1, buildNotification("Service running (not connected)"));
}

private void subscribeToTopic(String topic) {
try {
if (mqttClient != null &&  mqttClient.isConnected()) {
mqttClient.subscribe(topic, 1);
}
} catch (MqttException e) {
Log.e(TAG, "Failed to subscribe: " + topic, e);
}
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onDestroy() {
super.onDestroy();
stopAndDestroyService();
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post