Cordova/Phonegap Plugin als Android Service

Das Problem

App-Entwicklung mit Cordova funktioniert großartig. Beim Aufzeichnen von GPS Tracks stößt man aber an die Grenzen der Technologie, da es keine Möglichkeit gibt, einen Prozess zu starten, der nicht automatisch vom System beendet werden kann. Dazu benötigt man ein Plugin…

wpid-screenshot_2014-07-30-10-13-30.png

Ein Android Service

Mit ein wenig Java Kenntnissen ist es einfach einen Hintergrund-Dienst (Service) als Plugin für Cordova zu realisieren. Android kann den Service zwar auch beenden, startet ihn aber sofort wieder, wodurch das GPS tracking fortgesetzt wird. Einen Haken gibt es bei der Sache allerdings: Die Kommunikation zwischen Plugin und der Web-app ist schwierig. Die vorhandene Schnittstelle über den Callback-Context funkioniert (nach meinem Wissen) nicht, da der Service abgekoppelt läuft.

GPS Websocket Server

Moderne Browser unterstützen das effiziente Websocket Protokoll nativ. Der GPS-Service startet einen einfachen Websocket-Server auf einem hohen Port und die Web-app verbindet und wartet auf Messages:

    var ws = new WebSocket('ws://localhost:8887/snowhow');
    ws.onmessage = function (evt) {
      var data;
      try {
        data = JSON.parse(evt.data);
      } catch (e) {
        console.log("illegal json data via websocket", evt.data);
      }
      handleWSResopnse(data);
    }

Doch damit nicht genug: Über den Websocket Server kann das HTML-UI auch die Nachricht zum beenden des Service schicken. Natürlich steigt durch den Server und den Websocket Client der Stromverbrauch etwas, erste Tests haben aber keine dramatischen Änderungen gezeigt.

Die tolle OSMAnd-App für Android bietet ein reichhaltiges Set von Funktionen für mobile Kartenanwendungen. Unter anderem ist es auch möglich, eigene Tile-Layer einzubinden.
Hier die einfache Variante für Tiles vom mapnik Server: Im Verzeichnis /sdcard/osmand/tiles einen Ordner anlegen (hier snowhow). In diesem Ordner die Datei .metainfo mit folgendem Inhalt erzeugen:

shell@android:/sdcard/osmand/tiles/snowhow $ cat .metainfo                     
[url_template]
http://mein.tileserver.com/osm/{0}/{1}/{2}.png
[ext]
.png
[min_zoom]
1
[max_zoom]
17
[tile_size]
256
[img_density]
8
[avg_img_size]
18000

Und wenn die Tiles im TMS-Format vorliegen (also mit umgedrehter y-Achse), auch kein Problem:

shell@android:/sdcard/osmand/tiles/snowhow_slope $ cat .metainfo               
[rule]
beanshell
[url_template]
public static String getTileUrl(int z, int x, int y) {return "http://mein.tileserver.com/tms/"+z+"/"+x+"/"+((1 << z) - 1 - y) + ".png";}
[ext]
.png
[min_zoom]
1
[max_zoom]
17
[tile_size]
256
[img_density]
8
[avg_img_size]
18000

Fünf Sterne (und 5.99 EUR) für die Entwickler von OSMAnd, die Software rockt.

wpid-Screenshot_2013-08-06-01-19-43.png

Datentransfer mit rsync, openssh und cyanogenmod am Galaxy Nexus

Datentransfer

Um unter Linux Dateien auf das Galaxy Nexus zu kopieren gibt es leider keine einfache und performante Lösung. Mit Airdroid kann man wunderbar ein, zwei Dateien hin und her kopieren, der Transfer läuft über das Wlan, was von haus aus schon eine Geschwindigkeitsbeschränkung mit sich bringt. Alle meine Versuche mit mtp (auch unter Ubuntu 13.04) brachen regelmäßig ab und waren auch nicht von hohen Geschwindigkeiten gekennzeichnet.

cyanogenmod, openssh, rsync

Ganz anders verhält es sich mit rsync über ssh, getunnelt durch adb via USB. Hier erreicht man wirklich sehr zufriedenstellende Transferraten (für große Dateien lesend 15 MB/s). Eine ausführliche Anleitung dazu gibt es bei alainwolf.ch. Hier eine Kurzfassung, wie ich den Kopiervorgang starte. Voraussetzungen:

  • Android Debug Bridge am PC installieren (apt-get install android-tools-adb)
  • Handy per USB anstecken
  • am Handy:
    • Cyanogenmod 10.1 (momentan noch einen nightly build) installieren
    • Einstellungen - Entwickleroptionen: Root-Zugriff für Apps & ADB aktivieren
    • Einstellungen - Entwickleroptionen: USB debugging aktivieren

Dann am PC:

#pc:# adb root
#pc:# adb remount
#pc:# adb -d forward tcp:8090 tcp:8090
#pc:# adb shell
root@android:/ # /system/bin/sshd -D -p 8090

Mit dem letzten Kommando wird der SSH-Dienst am Handy auf Port 8090 gestartet. Der Dienst wird absichtlich nicht im Hintergrund ausgeführt, er läuft nur während die adb shell aktiv ist. Das adb -d forward tunnelt den IP port 8090 durch USB auf den PC.

Jetzt funktioniert der Zugriff via rsync. Um ein Backup der virtuellen sdcard zu machen kann man folgendes Kommando verwenden:

rsync -e 'ssh -p 8090' -rv root@127.0.0.1:/mnt/sdcard/ ./ 
  --exclude=Android/data/info.snowhow/files/tilestore/ 
  --exclude=osmand/

Update 2015

Mit dem wunderbaren gratis App SSHelper wird das etwas einfacher: SSHelper am Handy starten, den SSH-Port via adb am PC weiterleiten

bernd@pc > adb -d forward tcp:2222 tcp:2222

und schon können die Fotos mit

bernd@pc > rsync -e 'ssh -p 2222' -av localhost:~/SDCard/DCIM/Camera/ ~/handypics/

synchronisiert werden.

Das Galaxy Nexus will nicht schlafen

Das GN

Das Galaxy Nexus ist das coolste Smartphone das ich bisher hatte, was bei meinem zweijährigen Neukaufzyklus nicht weiter verwunderlich ist. Seit fast einem Jahr verwende ich es jetzt schon und bin immer noch sehr zufrieden: Es ist superdünn, hat ein großes Display und einen schnellen Prozessor. Mit cyanogenmod 10.1 experimental ist man auch mit der nicht mehr ganz akutellen Hardware softwaremäßig immer noch am Puls der Zeit.

Schlaflosigkeit

Doch seit einigen Tagen schaltete sich das Display des tollen Geräts immer wieder ungefragt ein und leerte so den Akku in weniger als der halben Zeit als gewohnt. Auch sonst zeigte mein Handy einige merkwürdige Verhaltensweisen, die ich nicht reproduzieren konnte. Jetzt habe ich das Gerät wirklich nicht sehr geschont und es wurde auch ab und zu einer gewissen Feuchtigkeit ausgesetzt. Deshalb war meine erste Vermutung, dass es sich um einen feuchtigkeitsbedingten Hardware Defekt handelt. Wie so oft, wurde ich von google eines besseren belehrt, denn das Problem ist weit verbreitet und was noch viel erfreulicher ist: es lässt sich in wenigen Sekunden beheben (zumindest in meinem Fall):gn_usb Der USB Anschluss wurde beim (schlampigen) Anstecken des Ladekabels wohl ganz leicht verbogen, auf jeden Fall reichte es den Abstand zwischen der sehr feinen Zunge (im Foto in der Mitte unten) und dem unteren Rand mit einem Zahnstocher etwas zu vergrößern. Ich hatte dazu den Akku entfernt und war sehr vorsichtig 😉

Kontaktdaten von Telefonnummern aus dem eigenen Adressbuch

Bei manchen Mobilfunk-Anbietern in Österreich bekommt man eine SMS, wenn jemand versucht hat anzurufen und man selbst gerade nicht erreichbar war. Die SMS schaut dann so ähnlich aus wie der erste Screenshot.

Aus technischen Gründen kann in der SMS nur die Nummer, nicht aber der Name des Anrufers aus meinem Telfonbuch stehen. Das wäre aber gerade recht spannend, denn ich kann mir leider nicht alle Namen zu den Nummern in meinem Adressbuch merken (dann wäre das Adressbuch ja auch umsonst). Um das so unkompliziert wie möglich zu lösen, habe ich eine winzige App geschrieben, die als Eingabe den Text der SMS nimmt und die dort enthaltenen Nummern im Adressbuch auflöst. Super simpel.

Zur Verwendung: Lange auf die SMS drücken, Text kopieren, dann die App starten, dort Einfügen, dann Knopf drücken Get Number(s). Das wars. Momentan filtert die App den Java-Regexp (\+[0-9]+),, also ein + dann Ziffern und dann einen Beistrich (manche sagen auch Komma dazu). Die 150 KB große App ist noch in keinem Appstore, sondern nur hier, oh und wer sich für das großartige Projekt interessiert kann hier das ganz Eclipse-Projekt mit Sourcecode herunterladen.