German App im Hintergrund um MQTT Nachrichten zu empfangen

Zecke

Member
Licensed User
Longtime User
Hallo,

ich möchte eine App erstellen, die auf MQTT Nachrichten wartet. Funktioniert soweit.
Problem: Um nicht Gefahr zu gehen, dass die App von Android gekillt wird, lasse ich einen Service laufen, der alle 30 Sekunden (im Moment) etwas ins Log schreibt. Später soll da auch mal was published werden. Aber nach dem Ausschalten des Handys wird nichts mehr ins Log geschrieben. Die App läuft sogar noch, da MQTT Nachrichten reinkommen, aber der Service nicht. Ne Idee, was ich falsch mache?

Main:
#Region  Project Attributes
    #ApplicationLabel: Tablet Control
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
End Sub

Sub Activity_Create(FirstTime As Boolean)

End Sub

Sub Activity_Resume
    StartService(mqttService)
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub



Starter:
#Region  Service Attributes
    #StartAtBoot: False
    #ExcludeFromLibrary: True

#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Service_Create

    'This is the program entry point.
    'This is a good place to load resources that are not specific to a single activity.


End Sub


Sub Service_Start (StartingIntent As Intent)
    StartService(mqttService)
End Sub

Sub Service_TaskRemoved
    'This event will be raised when the user removes the app from the recent apps list.
End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub Service_Destroy

End Sub


mqttService:
#Region  Service Attributes
    #StartAtBoot:true
#End Region


'=========================================================================================================================
'DEKLARATIONEN
'=========================================================================================================================
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim myMQTT As MqttClient
    Dim Broker As String = "192.168.178.03"
    Dim port As Int      = 1883
    Dim mqttOptions As MqttConnectOptions
    Dim powerState As PhoneWakeState
End Sub


'=========================================================================================================================
'SERVICE - wird erstellt
'=========================================================================================================================
Sub Service_Create

    myMQTT.Initialize("client", $"tcp://${Broker}:${port}"$, "android_tablet")
    myMQTT.Connect
    
End Sub


'=========================================================================================================================
'SERVICE - wird gestartet
'=========================================================================================================================
Sub Service_Start (StartingIntent As Intent)
    
    'Service.StopAutomaticForeground 'Starter service can start in the foreground state in some edge cases.
    StartServiceAtExact(Me, DateTime.Now + 30000, True) 'schedule the next task to run in 30 seconds.
    Log("Service started")

    
    'Hier alles hin was regelmäßig gemacht werden muss (ersetzt Timer)

End Sub



'=========================================================================================================================
'SERVICE - wird gelöscht
'=========================================================================================================================
Sub Service_Destroy

End Sub




'=========================================================================================================================
'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
'=========================================================================================================================




'=========================================================================================================================
'EVENT - MQTT Nachricht empfangen
'=========================================================================================================================
Sub client_MessageArrived (Topic As String, Payload() As Byte)

    Dim payloadString As String
    payloadString = BytesToString(Payload,0,Payload.Length,"UTF-8")
    Log(payloadString)



End Sub




'=========================================================================================================================
'EVENT - MQTT wurde verbunden
'=========================================================================================================================
Sub client_Connected (Success As Boolean)
    
    Log(Success)
    myMQTT.Subscribe("root/irgendwas",0)

End Sub
 

DonManfred

Expert
Licensed User
Longtime User
1. Du brauchst einen Partial Wakelock
2. Du brauchst einen vordergrund Service.
3. Einen Service alle 30 Sekunden neuzustarten wird Android NICHT zulassen (zumindest nicht bei Api 29+). Setze das minimum auf 30 Minuten oder länger.

 

Zecke

Member
Licensed User
Longtime User
Danke,

das Beispiel hatte ich auch probiert und ein LOG() eingefügt. Auch da kommt nichts mehr nach dem Ausschalten im Log an. Erels Beispiel ruft den Service jedoch auch alle 30 Sekunden auf. Hmm...

Also ich muss das mit Setforground.. machen - ok. Bleibt denn mein MQTT Message_MessageArrived Event aktiv, sodass Nachrichten empfangen werden wenn die App 30 Minuten nichts macht. Auch habe ich gelesen, dass die zum Service gehörende App trotzdem von Android gekillt werden kann. Der Service wird dann nach Ablauf der Zeit neu gestartet. Das würde doch bedeuten, das ich in der Zeit keine Nachrichten mehr bekomme, da das Empfangsevent nicht auslöst...

Grüße..
 

DonManfred

Expert
Licensed User
Longtime User
Es wird von Androidversion zu Androidversion immer schwieriger eine App dauerhaft im Hintergrund laufen zu lassen. Versuche das eifach zu vergessen dies zu wollen und denk Dir ein anderes Konzept aus. Lass den Service alle 30 Minuten neustarten und verarbeite die Nachrichten alle 30 Minuten.
LIVE wirst Du - vermutlich - nicht hinbekommen.

Mit dem Konzept einer immer im Hintergrund laufenden Applikation wirst Du nicht weit kommen. Erst recht nicht, wenn die App auf den PlayStore soll und Du TargetSDK hochsetzen musst...
 

Zecke

Member
Licensed User
Longtime User
Aber auf eine MQTT Message muss ich gleich reagieren. Ist ja in meinem Falle für SmartHome. Da müssen ja Zustände sofort gemeldet werden. Beispielsweise ein Alarm.
Ok, Zumindest weiß ich jetzt erstmal, dass es nicht an grundsätzlich falschem code liegt sondern an den Eigenheiten von Android.

danke..
 

Zecke

Member
Licensed User
Longtime User
Hallo,

habe herausgefunden, warum auch Erels mylocation Beispiel nicht funktioniert. SetForegrund alleine genügt nicht allein. Jedenfalls unter neueren Android Versionen. In den Appeinstellungen muss die App-Akku-Optimierung deaktiviert werden. Dann läuft auch der Service weiter. Allerdings frisst das ganz schön Akku. Für meinen Anwendungfall ist das aber OK...

Grüße..
 
Top