Infrarot (IR) LIRC Android Application

Nachdem wir nun die fertige Infrarot Umgebung erschaffen haben: IR Sender und Empfänger können wir nun die dafür vorgesehene APP programmieren.

Inhaltsverzeichnis:

  1. Erste Schritte
  2. AsyncTask Klasse
  3. Oberfläche

1.Erste Schritte

Zuerst brauchen wir natürlich die passende Umgebung (IDE) . Ich habe alle APP’s bisher im Eclipse erstellt, aber ich habe gerade eben gesehen das Google bei AndroidStudio wohl die BETA abgeschlossen hat also habe ich mich entschieden zusammen mit euch direkt das neue Ding auszuprobieren.

Android SDK : http://developer.android.com/sdk/index.html

JAVA Development KIT (mind. v7) : http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html

Während der Installation könnt ihr entweder das SDK auf eurem Rechner auswählen (falls bereits vorhanden)  oder neu runterladen. Ich werde diese APP in der API Version 15 (Android 4.0.3) erstellen. Also wenn ihr dann die SDK auswählt bitte die Version 15 mit herunterladen. Sollte das bei der Installation nicht möglich sein kann man die gewünschte API immer mit dem SDK Manager (Tools -> Android -> SDK Manager) nachinstallieren.

Nach der Installation erstellen wir ein neues Projekt und nennen es wie wir wollen. Ich habe meins IRRemote genannt. Danach API 15 auswählen die Klasse und das ActivityLayout benennen und fertigstellen. Beim Layout habe ich mich für die FullScreen Variante entschieden.

API Auswahl

Als aller erstes sollten wir das ganze Projekt aufräumen, ich weiß ehrlich gesagt nicht wieso AndroidStudio direkt soviel in die Klasse und die Activity reinschreibt (wird wohl an dem Fullscreen Layout und der neuen Funktion das man die Statusbar bei einer Fullscreen APP nach unten ziehen kann liegen, hmmm…also ich brauche es nicht.)

Projekt aufräumen:

  1. Die erstelle activity.xml (res/layout/) löschen. Danach mit der rechten Maustaste auf den Ordner Layout -> New -> XML -> Layout XML File. Als Layoutfilename einfach <Klassennamen>_activity.xml nehmen (freiwillig). RootTag als LinearLayout lassen oder direkt RelativeLayout reinschreiben danach die Datei erstellen. Zusätzlich einfach ein Button in die Mitte platzieren.So sollte „aufgeräumtes/einfaches“ Layout aussehen:Layout
  2. In der Hauptklasse brauchen wir auch nur den Aufruf der onCreate Funktion aus der Superklasse Activity. Daher alles löschen bis auf die Methode. Ich habe dann direkt auch den Button initialisiert und die MainKlasse um einen OnClickListerner erweitert. So können wir gleich direkt testen 😉MainKlasse

2.AsyncTask Klasse

Nachdem wir das Projekt bereinigt haben, können wir uns um das Versenden der Befehle über den TCP Port kümmern. Seid Android 2.0 (so habe ich das aufgeschnappt ) können keine Funktionen in dem MainThread aufgerufen werden die eventuell das ganze Programm anhalten (Netzwerk-Tätigkeiten wie das Downloaden Hochladen usw.). Daher muss man für die Netzwerkfunktionen entweder einen neuen Thread erstellen (der solche Aufgaben im Hintergrund erledigt) oder wir nutzen die Funktionen der ziemlich coolen Klasse AsyncTask die genau für diese Zwecke bestimmt ist.

Dafür erstellen wir zuerst eine neue Klasse und nennen sie zum Beispiel „Connection“. Danach erweitern wir sie mit der Klasse AsyncTask<Params,Progress,Result>. In unserem Fall brauchen wir nur die zu übergebenden Parameter.

Connection

In Eclipse hatten wir direkt die Möglichkeit die Methoden der implementieren Klasse zu übernehmen. AndroidStudio bietet diese Möglichkeit auch an und zwar wird kann mit der Tastenkombi ALT + ENTER die „doInBackground“ Methode implementiert werden.

DoInBackground

Nun erstellen wir vier Variablen. Zum einem ein Objekt vom Typ Socket und PrintWriter. Dazu die als String hinterlegte IPAdresse des Raspberry’s und zuletzt ein Integer wo wir die Port Nummer abspeichern. Danach initialisieren wir den Socket und übergeben die IP Adresse und die Port Nummer. Der Socket muss mit try und catch geschrieben werden falls er uns ne Exception ausspuckt.

Socket

Dem Printwriter übergeben wir den OutputStreams des Sockets. Danach brauchen wir nur noch den Befehl zu schicken.

ConnectionDone

Ich würde zusätzlich den PrintWriter und danach den Socket beenden.

pw.close(); 
socket.close();

Das war’s im Grunde.Nicht so schwer oder? Am Ende müssen wir noch unserer Application das Recht auf Internetzugriff gewährleisten. Dafür  machen wir das AndroidManifest auf und schreiben die Permission rein (übrigens war Eclipse hier deutlich besser man hatte zumindest die Auswahl aller Permissions) :

manifest

3.Oberfläche

Nun müssen wir nur noch den Befehl abschicke.Dazu nutzen wir die Methode Execute aus der Klasse AsyncTask die wir nach dem Klick auf dem Button auslösen.

Done

 

Jetzt bitte die APP entweder in einem Emulator (Laaahhhmmmmm) oder direkt über Telefon starten.Funktioniert alles? Achhhh Prima!

Im weiteren Verlauf werde ich noch mehr auf die Oberfläche eingehen wie zum Beispiel Button „Volume UP“ halten -> Lautstärke wird erhöht ->Button verändert sich — Button „Volume UP“ -> loslassen die Lautstärke bleibt stehen ->Button verändert sich zurück.

Übrigens ist AndroidStudio komplett für’n Ar**h (nach den ersten 2 Stunden) daher werde ich eher, im weiteren Verlauf des Beitrags, wieder zu Eclipse wechseln.

Fortsetzung folgt… (vorherige Beitrag IR Empfänger und Sender , passender Beitrag Button’s an LIRC anpassen Android)

Kleine Vorführung 😉 :

8 Gedanken zu „Infrarot (IR) LIRC Android Application

  1. Thomas

    Hallo,
    eine kurze Frage. Warum langt es eigentlich den Pi nur über die IP und den Port anzusteuern, ohne Benutzernamen oder Passwort eingeben zu müssen?

    LG

    Antworten
    1. BoBek Beitragsautor

      Hallo Thomas,

      bin unterwegs deshalb nur kurz die Antwort über das Handy. Wir brauchen in diesem Fall kein Passwort und Benutzernamen , weil wir die Verbindung über ein Socket herstellen der ja bekanntlich nur immer die IP Adresse und Port Nummer des Servers benötigt. Was du meinst ist eine Socket Verbindung über das SSL Protokoll wo der Client und Server über entsprechende Zertifikate Verfügen müssen um miteinander kommunizieren zu können. Hilfreich um Angriffe abzuwehren wenn unser Server (RaspberryPi) über das Internet erreichbar sein würde. Da hier aber nur eine Kommunikation im LAN stattfindet und die Programmierung eines SSL Sockets deutlich aufwendiger ist habe ich in diesem Fall drauf verzichtet. Ich hoffe ich konnte dir deine Frage beantworten 😉

      Antworten
  2. Alex

    Hallo,

    erstmals danke für diese Anleitung, ist wirklich perfekt! Ich hatte in meinem Studium bisher 2 Semester Java, also verstehe grob um was es geht. Jedoch hab ich keinen Plan was „Command[0]“ ist. AndroidStudio schlägt auch nur vor, eine neue Klasse zu generieren etc. Würde mich freuen wenn du mir dort helfen könntest 🙂

    MfG Alex

    Antworten
    1. BoBek Beitragsautor

      Hallo Alex,

      vielen Dank für die positive Rückmeldung. Um dein Problem besser erklären zu können, müssen wir uns die zu übergebenden Parameter der Methode „doInBackground“ aus der Klasse „Connection“ anschauen.Du siehst ja das hier nach dem Datentyp „String“ drei Punkte … angegeben werden und dann der Variablenname „Command“. Diese drei Punkte kennzeichnen die sogenannte „variable Parameterliste“. Das heißt wir können diese Methode mit unterschiedlicher Anzahl an Parametern vom Typ String starten. Java erstellt dann daraus ein Array und wir können wir gewohnt über [] auf die einzelnen Elemente zugreifen. Das bedeutet in unserem Fall das die Variable Command[0] auf das erste Parameter der Methode zugreift. Würden wir die Methode folgendermaßen aufrufen:
      new Connection.execute(„SEND ONCE 1A“,“SEND ONCE 1B“)
      dann würde in der Klasse „Connection“ in der Methode „doInBackground“ das Element:
      command[0] den Wert „SEND ONCE 1A“ und das Element
      command[1] den Wert „SEND ONCE 1B“ haben. Wenn dir das AndroidStudio hier eine neue Klasse als Lösung vorschlägt dann hast du vermutlich die Methode „doInBackground“ mit falschen Parametern angegeben. Schau dir auch das Extends AsyncTask an und ob hier die richtigen Datentypen drin sind . Bei Fragen kannst du dich jederzeit melden.

      Viel Spaß beim basteln
      Bobek

      Antworten
      1. Alex

        Hey,
        vieln Dank für die schnelle Antwort. Ja ich hatte einen falschen Parameter übergeben, sodass java die Variable noch nicht deklariert hatte, verflixtes copy&paste :/ Jetzt klappt es aber, vielen Dank 🙂

        Schönen Abend noch
        Alex

        Antworten
  3. Thomas

    Hallo,
    danke für die tolle Beschreibung deiner Arbeit.
    Ich hätte da nur noch eine Frage. Wo hast du deinen IR Sender plaziert damit er alle Geräte gleichzeitig erwischen kann??? Ich müsste dafür ein Kabel quer durchs Wohnzimmer ziehen. Ein Betrieb des Raspbarrys mittels Batterie wird wohl eher keinen Sinn machen wenn er einen Wlan Dongle betreiben muss und den IR-Sender oder???

    Danke und Lg

    Antworten
    1. BoBek Beitragsautor

      Hallo Thomas,
      bei mir liegt der Empfänger gute 3m vor den Sachen (TV / LED’s / Anlage) entfernt, ist aber zentral drauf gerichtet und die drei Empfänger liegen einigermaßen zusammen. Die Diode ist auch bei mir mit ziemlich langen Kabel (ca.1,5m) mit dem Raspbeery verbunden. Also Entfernungen bis auf 4m sind, denke ich, machbar auch wenn die Ausstrahlung geringer wird. In den Kommentaren (Infrarot (IR) Sender und Empfänger am RaspberryPI steuern mithilfe einer Android Application) findest du auch eine Schaltung für den Gebrauch von mehreren Dioden aber wie das bei Infrarot eben so ist, der Empfänger und Sender müssen schon gut ausgerichtet sein. Wie das mit der Batterie Versorgung aussieht kann ich dir nicht genau sagen, man müsste schauen was ein Raspberry Pi maximal Verbrauchen kann (an der IR Diode soll es nicht scheitern die Verbraucht so gut wie nichts) , bei dem WLAN Stick kann ich mir vorstellen das hier bisschen mehr verbraucht wird. Hier habe ich was gefunden http://www.daveakerman.com/?page_id=1294 aber wie du selber sehen kannst sind in diesem Beispiel max. 28h Betrieb drin. Bei mir läuft der Raspi 24h/7Tage. Eventuell einfach einen zweiten Raspi holen ich meine die Dinger werden immer billiger ;). Ich wünsche dir viel Spaß beim basteln und danke für die positive Resonanz.

      Antworten
      1. Thomas

        Danke für die rasche Antwort. Da ich meinen Raspberry direkt in der HiFi Ecke platzieren möchte werde ich mal versuchen, an jedes Gerät eine extra IR-Diode anzubringen (werde sie einfach auf die Empfänger Kleben). Wenn ich mein Projekt abgeschlossen habe, werde ich meine Ergebnisse präsentieren 🙂
        Lg

        Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.