# Kommunikation im Hintergrund



## sirpacman (4. Feb 2016)

Hallo liebe Programmierer

Ich bin zuhause an einem kleinen Projekt drann. Ich kenne mich mit Android leider noch nicht so gut aus und wollte mal Fragen welche Technologie für mich die richtige ist. Ich hab eine Kommunikation zu einem Java-Server am laufen. Was ich möchte ist, das die zu kommunizierenden Daten stehts auf dem neusten Stand gehalten werden. Das heißt, wenn sich die Daten auf der Serverseite ändert, sollen diese sofort an die Android-APP geschickt werden. Genau so wenn die Android-APP was an den Daten ändert, sollen diese sofort an den Java-Server geschickt werden. Es geht hier um eine "Fernbedienung" für mein Haus, welches eine Gebäudesteuerung mittels Beckhoff hat. Vom Prinzip funktioniert das ganze auch. Ich hab schon Kommunikationsklassen geschrieben, welche genau diese Funktionen erfüllen. Ich habe es ja schon mit AsyncTask probiert und mit einen "normalen" Java Thread, aber irgendwie kommt es mir immer so vor also ich nicht die dafür vorgesehen Funktionen von Android verwenden. Natürlich müssen diese Daten auch mit dem UI-Thread ausgetauscht werden, da ich ja die Daten vom Server Visualisieren will und die "Steuerdaten" von Android an den Server schicken will.


Vom Prinzipp ist es ja ein sehr einfach Programm, Einmal meine UI-Thread wo ich als "Fernbedienung" nütze und einmal einen Thread, Asyntask, Service was auch immer, welcher mir eine stetige Verbindung zum Server aufrecht erhält um die Daten auszutauschen. Was ist hier der richtige weg?? Welche Technologie von Android sollte ich hier verwenden???


----------



## buggy84 (5. Feb 2016)

Ich würde hier einen Service installieren, der die Daten deiner Hausautomation in bestimmten Intervallen abruft. Ich kenne mich mit deinem Beckhoff System nicht aus, daher weiß ich nicht was genau Du für Daten willst.
Du musst Dir dann aber auch darüber klar werden, dass Du möglicherweise viel Traffic haben wirst, deine Akkulaufzeit wird sich eventuell verkürzen und Du musst Momente abfangen können, in denen keine Internetverbindung verfügbar ist.

Man könnte es z.B. so aussehen lassen:

Alle 60 sek. holt sich der Service die benötigten Daten und schreibt diese in eine Datenbank.
In der onResume() deiner App liest diese die notwenigen Daten aus der Datenbank und malt sie in die grafische Benutzeroberfläche. Damit hast Du beim zurückholen der App auch immer die akuellsten Daten. Bei Bedarf kann der Service dann gestoppt werden (möglicherweise in der onDestroy() deiner App ).

Das senden der Daten an deinen Server funktioniert wie gehabt übers Internet, hier hast Du keine Angaben gemacht, deswalb würde ich jetzt davon ausgehen, dass hier schon eine Lösung vorliegt.


----------



## Thallius (5. Feb 2016)

Da Du die Daten ja nur brauchst wenn Deine App läuft würde ich auch zyklisch alle paar Sekunden oder Minuten (ka wie oft sich da was relevantes ändert) in einem eigenen Thread abrufen und dann das UI aktualisieren.
Beim Start der App, must du halt einmal alle Daten nachladen die seit dem letzten Benutzen erzeugt wurden oder zumindest soviele wie Dich noch interessieren.
Dazu must du ja nur in der DB eine Spalte haben in der das Erzeugungsdatum/Uhrzeit des Datensatzes mit protokolliert wird.

Gruß

Claus


----------



## sirpacman (6. Feb 2016)

Hallo buffy, Hallo Claus

Vielen dank für deine Antwort. Eine Beckhoff-SPS ist ein Embedded PC mit, in meinem Fall, ein Windows Embedded 7 und dem Runtime für die SPS dem sogenannten TwinCAT (das läuft in Echtzeit). Das ist aber für die Android-APP egal, da ich schon eine Schnittstelle programmiert habe, in der ich die Daten aus dieser SPS rausholen und in JAVA-Datentypen umwandle (ja ein integer in einer SPS ist was anderes als ein integer in Java usw. ). Diese Daten stelle ich alle eine JAVA-Server zur Verfügung. Dieser JAVA-Server kommuniziert dann mit meiner APP.


Sobald ich Zuhause bin (ich mach kein VPN-Tunnel) und das APP starte, will ich zumindest wenn das APP im Vordergrund ist die Daten haben sobald sich etwas ändert. Also nicht nur alle paar Sekunden oder Minuten. Ich schraube ja ein 7 oder 8 zoll Tablet an die Wand, welches immer am Strom angeschlossen ist und als meine Hausvisu dient (Für Sonos, Türkamera, mein eigenes APP, usw.). Wenn ich mal meine Haussteuerung über das Smartphone bediene, denke ich sollte das mit dem Akku schon gehen.


der Grund ist halt folgender. Ich mach ja mit meiner Elektrofirma 1 - 2 soll "vollautomatische" Gebäude im Jahr. Das ich natürlich nicht wie bei meinem Haus, da ich damit Geld verdienen muss, rentiert sich dieser Aufwand mit einem eigenen Android-App nicht. Dort verwende ich ein System welches von der Firma Atvise kommt. Dort wird auf dieser Beckhoff-SPS ein Webserver installiert, welcher wie meine Java-Schnittstelle den Datenaustausch mit der SPS macht. Dann bietet Atvise für mich ein Tool an, mit welchen ich eine coole VISU zusammen bauen kann, ohne richtige Programmieren zu müssen. Das ganze läuft dann rein Webbasieren. So kann ich mich auf das Konzentrieren was ich gut kann (SPS-Programmieren) und kann trotzdem eine coole VISU Anbieten. Ich möchte aber für mich eine Native-Lösung. Das hat 2 Gründe. Erste kann ich so die Android-Plattform kennen lernen und zweitens hab ich ein Hobby ;o). Warum ich das alles schreibe ist. Die Kunden sind immer total begeistert, wenn sie die VISU offen haben und jemand fährt mit der Jalousie rauf oder runter, dimmt das Licht rauf und runter usw. und das ganze wird mehr oder weniger ohne Verzögerung im Browser dargestellt.  Mir gefällt das auch, Darum will ich ja eigentlich zumindest wenn die APP im Vordergrund ist, eine stetige Datenverbindung haben, in der der Client oder auch der Server Daten senden kann, wenn sich was ändert. Natürlich hab ich hier noch ein Sleep eingebaut, das trotz Datenänderung min. 100ms vergehen müssen bevor ich was sende. Die Kommunikation wie gesagt Funktioniert auch schon. der Server und die Android-APP kommunizieren schon. Im Moment schreibe ich aber alles nur über ein System.out.println(); raus für mich zur Kontrolle. Darum wieder zurück zur eigentlich Frage, was ist für mich die richtige Technik?? Ein Service welcher eingeschaltet wird, wenn das App in der Vordergrund kommt und ausgeschaltet/pausiert wird wenn die APP im Hintergrund ist?? Wenn ja wie stelle ich das am besten an, das ich die Daten von diesem Service in mein UI-Thread bekomme um meine VISU zu aktualisieren??


mfg

     Matthias


----------



## Thallius (6. Feb 2016)

Zur Kommunikation zwischen Thread solltest Du einen Handler benutzen:

http://developer.android.com/training/multiple-threads/communicate-ui.html

Gruß

Claus


----------



## sirpacman (6. Feb 2016)

Hallo Claus

Und wie ist es mit dem Service?? Ist das der richtige weg??

mfg

    Matthias


----------



## Thallius (6. Feb 2016)

Die Kommunikation mit dem Server würde ich über eine JSON Schnittstelle machen und in einem Thread im Hintergrund laufen lassen. Wenn das Tablet wirklich nichts anderes macht, kannst Du die Daten ja alle 100ms abholen. Das sollte dann locker reichen um eine Echtzeit zu simulieren oder?


----------



## sirpacman (7. Mrz 2016)

Hallo

Ich hab das jetzt mal so gelöst, das ich einen eigenen Communications-Thread mit Handler usw. gemacht habe, das scheint jetzt soweit gut zu funktionieren. Die Lichter schalten mal ein und aus, dimmen geht auch. Die Werte von der SPS kommen rüber. Wenn die Anwendung in den Hintergrund geht, unterbreche ich immer den Interrupt, da ich keine Kommunikation brauchen wenn da App nicht im Vordergrund ist. Auch das mit dem Thread unterbrechen und einen neuen Communications-Thread anlegen passt super.

Jetzt zu einem anderen Thema. Ich hoffe das passt, wenn ich hier nicht extra ein neues Thema anlegen. Wie ich hab oben schon beschrieben habe, will ich das ganze auch Visualisieren. Dazu hab ich eine eigene VIEW-Klasse definiert. Die Buttons und die Seekbar funktionieren. Mit den Buttons kann ich normal ein und ausschalten und mit der Seekbar kann ich auf den gewünschten Wert dimmen. Ich hab jetzt mit Canvas eine Glühbirne gezeichnet (ich weiß die VISU ist optisch noch nicht schön, aber zuerst muss mal alles laufen ). Dazu hab ich 3 Kreise gezeichnet einen "großen" Schwarzen einen um 2 pixel kleineren weißen (damit ich einen Rand bekomme) und genau über den weißen einen Gelben. Darunter ein Rechteck um den E27 Sockel darzustellen. So jetzt meine Frage. Ich würde gerne die Sichtbarkeit von diesem gelben Kreis gerne abhängig vom aktuellen Leistungswert, den krieg ich über die Kommunikation, steuern. Das heißt, wenn die Lampe 100% brennt, dann soll das gelbe voll das sein, wenn die Lampe aus ist soll das gelbe unsichtbar sein. Da zwischen logischerweise abhängig vom diesem Wert. Muss ich hier jetzt die onDraw Methode jedes mal neu Aufrufen, wenn ich das ändern will (z.B. die transparenz). Oder hab ich eine Möglichkeit auf den gelben Kreis nachträglich zu zugreifen???


mfg

    MAtthias


----------



## Thallius (7. Mrz 2016)

Mach den Kreis doch einfach als Image und setze einen schwarzen oder weissen Kreis dahinter. Dann kannst du durch das Ändern der Transparenz des Images den gleichen Effekt erzielhlen.

Gruß

Claus


----------



## sirpacman (7. Mrz 2016)

Hallo Claus

Dann müsste es doch auch möglich sein im GIMP die Lampe komplett zu zeichnen und dann einen gelben Kreis/oval, also im Endeffekt ein Bild, welches über das andere Bild/Glühlampe drüber gelegt wird und dann arbeite ich mit diesem Transparenz effekt oder??

mfg
   Matthias


----------



## Thallius (7. Mrz 2016)

Ich würde dann vielleicht die Lampe mit Transparenz zeichnen wo das gelbe hinkommt und dann das Image mit dem gelb darunter legen. Dann muss das nichtmal ein Kreis sein. 

Gruß

Claus


----------

