Sonntag, 7. Oktober 2012

Smart Home mit Android und Arduino in der Theorie

Durch die Leistungsfähigkeiten und Hardware Ausstattung heutiger Tablets können diese Geräte sebst für komplexe Aufgaben verwendet werden, die einen hohen Grad an Zuverlässigkeit fordern. Geräte die in solch einem Smart Home integriert werden können am besten über das Netzwerk als Schnittstelle angestiert werden. Dies erspart aufwändige Arbeiten wie die Neuverlegung von Kabeln. Vorhandene Netzwerkkabel können verwendet werden oder im Bestfall sogar das WLAN. Wenn in der Praxis auch nicht sonderlich sinnvoll ist es theoretisch möglich auch USB als Schnittstelle zu verwenden. Dies kann nur bei Geräte welche über einen USB Host verfügen (wie z.B. Das Samsung Galaxy Note 2). Eine weitere Bedingung ist, dass das angeschlossen Gerät kompatibel zum Android Open Accessory Standard sind. Bisher sind mir allerdings keine Geräte bekannt die diese Bedingung erfüllen. Überhaupt ist der Markt an Intelligenten Geräten relative dünn gesät. Und was der Markt nicht hergibt muss man eben selbst basteln.
Dafür eignet sich am besten Arduino. Arduinos sind kleine Hardwarebausteine die sich Programmieren lassen und durch viele Module Erweiterbar sind. Es lassen sich digitale und analoge Signale senden und empfangen. Also alles was man braucht um ein Smartes Gerät selbst zu bauen. Wie man in der Praxis ein Android Gerät mit Arudino zusammen verwendet in am Besten in diesem Buch Beschreiben: Beginning Android ADK with Arduino.


Natürlich ist es sehr unpraktisch ständig das Smart Home per USB an das Tablet zu koppeln. Dafür eignen sich Geräte die Fest im der Wohnumgebung stehen also Router oder TV Boxes. Letztere werden sogar oft mit Android und USB Host zum Kauf angeboten. Hier sind zwei Beispiele:
 
Diese Geräte Ermöglichen eine Sinnvolle Architekture für ein selbst gebautest Smart Home. Auf dem Android Gerät empfiehlt es sich ein OSGi Framework laufen zu lassen da solche Systeme durchgängig laufen müssen und ein hohen Anspruch an die Arichtekture im den Punkten Wartbarkeit, Zuverlässigkeit und Erweiterbarkeit haben. Über Schnittstellen (am besten RESTful) kann mit dem System z.B. vom Smartphone aus Einstellungen im Smarthome System vorgenommen werden.

Es Folgen Artikel in dem die komplette Architekture in die Praxis umgesetzt wird.

Sonntag, 2. September 2012

Apache Felix auf Android - Problemzonen

"Warum läuft Apache Felix nicht ohne weiteres auf Android ?" Wenn ein OSGi Framework wie Apache Felix in der JavaVM läuft und ein Bundle nachgeladen wird, ist es meiste eine Jar das vom Framework nachgeladen wird. In der Jar liegen die ganzen Klassen, sie sind im *.class Format also JavaByteCode. Wer sich selbst davon überzeugen möchte kann einfach mal Folgendes versuchen:
jar tf datei.jar
Inhalt der Jar wird angezeigt. Oder:
jar xf datei.jar
Inhalt der Jar wird entpackt. (In zip umbenennen geht aber auch ;-) )

Wenn Felix auf der JavaVM läuft wird einfach nur der ByteCode aus den classfiles ausgeführt. Auch die Bundles beinhalten nur JavaByteCode.
Auf Android wird DalvikByteCode ausgeführt wie man auch in der Grafik erkennen kann. Diesen kann man sich durch die erneute Kompilierung des JavaByteCodes generieren (Bei Android werden Register benutzt - bei Java Stacks).

Wenn wir also Apache Felix auf Android laufen lassen und ein ganz normales Bundle installieren und starten wird folgendes passieren:

I/dalvikvm(6713): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory 
E/dalvikvm(6713): ERROR: defineClass(0x41198008, org.apache.felix.http.bundle.internal.CombinedActivator, 0x411912c8, 0, 1673) 
I/System.out(6713): ERROR: Bundle org.apache.felix.http.bundle [14] Error starting reference:file:mnt/sdcard/bundles/org.apache.felix.http.bundle-2.2.0.jar (org.osgi.framework.BundleException: Activator start error in bundle org.apache.felix.http.bundle [14].) 
W/System.err(6713): java.lang.UnsupportedOperationException: can't load this type of class file 
W/System.err(6713): at java.lang.VMClassLoader.defineClass(Native Method) 

Die erste Zeile drück es in etwa aus, es gibt kein dex file im Jar welches deployt werden könnte.
Die Lösung: Wir packen in jeden Jar ein Dex File. Wenn die DalvikVM dann versucht den Code während der laufzeit zu laden, so ist DalvikByteCode (in der classes.dex im root des bundles) vorhanden. Ein Beispiel: Wir wollen die Bundles org.apache.felix.http.bundle, org.apache.felix.shell, und org.apache.felix.shell.remote installieren und starten. Dazu müssen wir sie dex'en ;).
dx --dex --output=classes.dex datei.jar
Damit wird die dex generiert.
aapt add datei.jar classes.dex
So wird die dex in die jar gepackt.

OSGi Error: NoClassDefFoundError

If we look at this example
java.lang.NoClassDefFoundError: Could not initialize class com.example.MyClass

This error means that the class "MyClass" was found, but the classloader couldn't finish loading it. The Reason could be that MyClass depends on a other class which is missing.

This can happen when the bundle was compiled when the depending classes where present but they won't be in the bundle or any other exporting bundle.

To debug such an error you need to trace back through the dependencies. The problem is that the real missing dependency may be at the bottom of the dep.-stack.

By the Way: The "ClassNotFoundException" means that the given class (e.g.: MyClass) was not found.

Freitag, 25. Mai 2012

Offtopic: Mac can't resolve localhost and Eclipse Debug Mode does not work

I always had problems to run eclipse in debug mode.
Error: Invalid memory access of location 0x14 rip=0x########



After reading millions of forum posts i found out that it could be related to a other problem i had since a long time.
If i try to ping localhost, it says can't resolve localhost.


The problem is that /etc/hosts is empty.


You can check this by open the command line tool and write "sudo nano /etc/hosts" or "sudo vi /etc/hosts". If the file is blank you propably got the same problem like me. Good for you that i found a solution:


1. Open Command line
2. Copy that:

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost 
fe80::1%lo0     localhost



3. Type: "sudo nano /etc/hosts" or "sudo vi /etc/hosts"
4. If a blank file is show. Rightclick and Paste.
5. Save the File.
6. Try "Ping localhost"


Also Eclipse shoud now be able to run the Debugmode.

Troubleshooting:

You were trying to save the file but it failed because of "Error writing hosts: No such file or directory".
The Problem is that the file is a alias file and just references to nowhere.
Ok do Step 1 and 2. After that Type: "sudo nano /etc/hosts2" or "sudo vi /etc/hosts2".
Do step 4 and 5.
Than go to /etc/ and type "mv hosts hosts3" and "mv hosts2 hosts"
Go step 6. :)


OR


type: "rm /etc/hosts" and start from step1.