Ralph Steyer
Apps mit PhoneGap entwickelnUniverselle Web-Apps plattformneutral programmieren
VI Inhalt
3.2.1 PhoneGap für Android einrichten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563.2.1.1 Den JavaQuellcode anpassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583.2.1.2 Die Konfiguration mit XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.2.2 PhoneGap für Windows Phone einrichten . . . . . . . . . . . . . . . . . . . . . . . . 633.2.3 PhoneGap für iOS einrichten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
3.3 Alles, was recht ist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713.3.1 Allgemeines zu den Rechtesystemen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713.3.2 Individuelle Rechtevergabe unter Android . . . . . . . . . . . . . . . . . . . . . . . . 723.3.3 Rechte unter Windows Mobile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4 Webtechnologien unter PhoneGap. . . . . . . . . . . . . . . . . . . . . . . . . . . . .794.1 Die Indexseite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.1.1 Die Struktur der HTMLSeite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794.1.2 Die SkriptReferenzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 804.1.3 Style Sheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 824.1.4 Eine Standardschablone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.2 Die eigenen SkriptDateien. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 854.3 Weitere Tipps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
4.3.1 Pfadangaben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 864.3.2 Bilder und andere Multimediadateien . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
5 Wo bin ich und wo will ich hin?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .895.1 Das navigatorObjekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
5.1.1 Eigenschaften und Methoden von navigator auswerten . . . . . . . . . . . . . 905.2 Geolokalisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.2.1 Die verschiedenen Techniken zur Ortsbestimmung . . . . . . . . . . . . . . . . 955.2.2 Das Objekt navigation.geolocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 995.2.3 Die notwendigen Rechte und Plugins bei Geolocation . . . . . . . . . . . . . 1025.2.4 Die aktuelle Position –
ein konkretes Beispiel mit getCurrentPosition() . . . . . . . . . . . . . . . . . . 1035.2.5 Die Veränderung mit watchPosition() beobachten . . . . . . . . . . . . . . . . . 1095.2.6 Die Beobachtung beenden. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1105.2.7 Ein Mashup mit Kartendiensten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1105.2.8 Wie schnell bin ich? Eine TachometerApp . . . . . . . . . . . . . . . . . . . . . . . 1155.2.9 Ein grafischer Tacho mit HTML5CanvasObjekten . . . . . . . . . . . . . . . . 117
5.3 Wo geht es lang? Der Kompass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1215.3.1 Die möglichen Optionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1225.3.2 Die notwendigen Rechte und Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . 1225.3.3 Die Eigenschaften . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1235.3.4 Ein vollständiges Kompassbeispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1245.3.5 Ein Kompass unter Verwendung von HTML5CanvasObjekten . . . . . . 125
5.4 Der Beschleunigungssensor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1285.4.1 Die Methoden und Eigenschaften . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Inhalt VII
5.4.2 Die Voraussetzungen auf dem mobilen Gerät. . . . . . . . . . . . . . . . . . . . . 1295.4.3 Ein vollständiges Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
5.5 Ein Cockpit als Abschlussbeispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1315.5.1 PortraitModus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1315.5.2 Die Datei index.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
6 Erstellung in der Cloud & mehr. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1396.1 GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
6.1.1 Die Registrierung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1416.1.2 Übersetzung der Webquellcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
6.2 Konfiguration und Metadaten mit config.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . 1456.2.1 Grundlegende Eigenschaften . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1466.2.2 Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1476.2.3 Zielplattformspezifische Einstellungen . . . . . . . . . . . . . . . . . . . . . . . . . . 148
6.3 Weitergehende Themen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1486.3.1 Befehlszeilenarbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1496.3.2 PluginEntwicklung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1496.3.3 Weitere Hilfe und Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
7 Information und Rückmeldung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1517.1 Das DeviceObjekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
7.1.1 Die Eigenschaften . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1517.1.2 Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1527.1.3 Ein Beispiel zur Anzeige relevanter Informationen . . . . . . . . . . . . . . . . 152
7.2 Der Netzwerkstatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1537.2.1 Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1547.2.2 Ein Beispiel zur Auswertung des Netzwerkstatus . . . . . . . . . . . . . . . . . 1557.2.3 Ein Muster zur Entscheidung, ob eine Netzwerkverbindung besteht . 155
7.3 Notification. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1567.3.1 Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1567.3.2 Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
8 PhoneGap im Zusammenspiel mit ergänzenden Frameworks . . . . 1638.1 Verschiedene Frameworks für WebApps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
8.1.1 PhoneGapAlternativen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1648.1.2 Ergänzungen von PhoneGap. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
8.2 jQuery, jQuery UI und jQuery Mobile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1678.2.1 Das Basisframework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1688.2.2 Download von jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1698.2.3 Die Einbindung von jQuery in Webseiten . . . . . . . . . . . . . . . . . . . . . . . . 1698.2.4 Wie jQuery grundsätzlich arbeitet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1708.2.5 Vorhandenen Code mit jQuery umsetzen –
das navigatorObjekt auswerten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
VIII Inhalt
8.3 Die GUIErstellung mit jQuery Mobile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1788.3.1 Das Rollensystem und datarole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1818.3.2 Der grundsätzliche Aufbau einer mobilen Seite. . . . . . . . . . . . . . . . . . . 1818.3.3 Eine erste App mit jQuery Mobile – eine TachometerApp . . . . . . . . . . 1828.3.4 Verknüpfen von Seiten in jQuery Mobile . . . . . . . . . . . . . . . . . . . . . . . . 1848.3.5 Schaltflächen, Toolbars, Navbars und Formularelemente . . . . . . . . . . . 1858.3.6 Weiterentwicklung der ersten App mit jQuery Mobile . . . . . . . . . . . . . 1888.3.7 Das ThemenFramework und die allgemeine Gestaltung von Inhalt . . 1928.3.8 Eine Überarbeitung der FliegertachoApp . . . . . . . . . . . . . . . . . . . . . . . 1938.3.9 Support für spezielle Ereignisse in jQuery Mobile. . . . . . . . . . . . . . . . . 199
8.4 jQuery UI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2018.4.1 Unterstützung der Interaktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2018.4.2 Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2028.4.3 Das ThemenFramework samt ThemeRoller . . . . . . . . . . . . . . . . . . . . . . 2038.4.4 Wie nutzt man jQuery UI grundsätzlich? . . . . . . . . . . . . . . . . . . . . . . . . 203
9 Multimediafragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2059.1 Zugriff auf die Kamera – das navigator.cameraObjekt. . . . . . . . . . . . . . . . . . . . 205
9.1.1 Notwendige Freigabe und Voraussetzungen . . . . . . . . . . . . . . . . . . . . . . 2059.1.2 Ein Foto aufnehmen mit camera.getPicture() . . . . . . . . . . . . . . . . . . . . . 2069.1.3 Ein Beispiel – ein Bild aufnehmen, anzeigen und speichern . . . . . . . . 208
9.2 Aufnahmemöglichkeiten mit Capture & Co . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2119.2.1 Die Basisobjekte. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2129.2.2 Notwendige Freigabe und Voraussetzungen . . . . . . . . . . . . . . . . . . . . . . 2139.2.3 Konkrete Aufnahmemethoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2159.2.4 Die Optionen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2159.2.5 Erfolg und Misserfolg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2169.2.6 Konkrete Aufnahmebeispiele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
9.3 Audiowiedergabe und aufnahme mit Media . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2239.3.1 Notwendige Freigabe und Voraussetzungen . . . . . . . . . . . . . . . . . . . . . . 2249.3.2 Erzeugen von Mediaobjekten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2249.3.3 Die Parameter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2259.3.4 Methoden von Mediaobjekten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2269.3.5 Ein Mediaplayer als Beispiel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
10 Kontaktfragen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23310.1 Die Kontaktdatenbank – Contacts und Contact . . . . . . . . . . . . . . . . . . . . . . . . . . 233
10.1.1 Notwendige Freigabe und Voraussetzungen . . . . . . . . . . . . . . . . . . . . . . 23410.2 Die Objekte Contacts und Contact . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
10.2.1 Erstellen eines Datenbankobjekts mit create() . . . . . . . . . . . . . . . . . . . . 23510.2.2 Ein Kontaktbeispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
10.3 Verwalten von Daten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24310.3.1 Speichern, Duplizieren und Löschen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
Inhalt IX
10.3.2 Ein Beispiel zum Speichern, Duplizieren und Löschen von Daten. . . . 24410.3.3 Das Suchen von Daten. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24510.3.4 Ein Beispiel zum Suchen in der Datenbank . . . . . . . . . . . . . . . . . . . . . . 246
11 Ran an den Speicher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24911.1 Zugriffe auf das Dateisystem – File & Co . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
11.1.1 Vorüberlegungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24911.1.2 Notwendige Freigabe und Voraussetzungen . . . . . . . . . . . . . . . . . . . . . . 251
11.2 Die Basisobjekte unter PhoneGap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25211.2.1 Objekte vom Typ File, DirectoryEntry und FileEntry . . . . . . . . . . . . . . 25311.2.2 FileReader und FileWriter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25611.2.3 Repräsentation des Dateisystems über FileSystem
und DirectoryReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25811.2.4 LocalFileSystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25811.2.5 Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25911.2.6 FileError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25911.2.7 Ein praktisches Beispiel – Lesen und Schreiben einer Textdatei . . . . . 25911.2.8 Ein Beispiel mit Informationen zum Dateisystem . . . . . . . . . . . . . . . . . 26211.2.9 Eine KMLDatei erstellen – Tracking für die Geolocation . . . . . . . . . . . 26311.2.10 FileTransfer und FileUploadOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
11.3 Zugriff auf eine SQLiteDatenbank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26911.3.1 Was ist SQLite? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27011.3.2 Die SQLiteFeatures in PhoneGap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27011.3.3 Notwendige Freigabe und Voraussetzungen . . . . . . . . . . . . . . . . . . . . . . 27011.3.4 Die Methode openDatabase() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27111.3.5 Die Datenbankmethoden. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27111.3.6 Ein erstes Datenbankbeispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27211.3.7 Die Methode executeSql(), SQLResultSet und SQLResultSetRowList . . 27411.3.8 Die Weiterentwicklung des letzten Datenbankbeispiels . . . . . . . . . . . . 27411.3.9 Ein etwas umfangreicheres Datenbankbeispiel mit jQuery Mobile . . . 275
11.4 Local Data Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28211.4.1 Die Objekte localStorage und sessionStorage . . . . . . . . . . . . . . . . . . . . . 28211.4.2 Ein Beispiel zum Speichern von Daten im Local Storage . . . . . . . . . . . 283
12 Anhang. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28712.1 Quellangaben im Internet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28712.2 Ein Crashkurs zu JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
12.2.1 Woher kommt JavaScript? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29012.2.2 Der gemeinsame Namensraum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29112.2.3 Elementare JavaScriptGrundstrukturen. . . . . . . . . . . . . . . . . . . . . . . . . 29112.2.4 JavaScript und Objekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29512.2.5 Das DOMKonzept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29712.2.6 Zugriff auf Inhalte von Elementen in der Webseite . . . . . . . . . . . . . . . . 298
X Inhalt
12.3 Mit einer App Geld verdienen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29912.3.1 Gibt es (seriöse) Anbieter für mobile Werbekampagnen und wenn ja,
welche? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30012.3.2 Rechnet sich mobile Werbung?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30212.3.3 Wie kommt Werbung in die App? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30312.3.4 Wie implementiert man allgemein mobile Bannerwerbung in die
eigene App oder mobile Webseite?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30312.3.5 Wie bekomme ich Werbung in eine PhoneGapApp? . . . . . . . . . . . . . . . 304
Stichwortverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
XII Vorwort
Als ich dann mit dem Studium fertig war, stand ich mit meinem Diplom in Mathematik da. Und was gab es für Mathematiker für Jobangebote? Hauptsächlich als Programmierer. Aber als ich dann als Programmierer bei einer Versicherung angefangen hatte, bin ich dem Reiz dieser ehemals „verachteten“ Welt erlegen. Sowohl was den Status eines Programmierers in der Firma anging2, aber vor allen Dingen der spannenden Tätigkeit, dem Erschaffen von Dingen (wenn auch nur Programmen) und den logischen Denkweisen.Nun haben wir bei der Versicherung in meiner Abteilung anfangs prozedural mit Turbo Pascal programmiert. Das Ziel waren DOSProgramme für den Außendienst und unsere Vertriebspartner in Banken und Agenturen. Nach einiger Zeit sollten wir jedoch an einem objektorientierten Projekt arbeiten. Die OOP (objektorientierte Programmierung) kam zu dem Zeitpunkt als Hype auf. Aber diese objektorientierte Programmierung war für mich wieder so eine Neuerung, an die ich anfangs gar nicht heran wollte. Mir war der Nutzen zu dem Zeitpunkt einfach nicht klar. Vor allen Dingen, da wir in der Versicherung mit C/C++ einen hybriden Zugang zu dieser Welt gewählt hatten und man die objektorientierte Denkweise damit wunderbar umgehen konnte (und immer noch kann). Aber als ich 1996 – mittlerweile selbstständig als Freelancer – Java programmieren wollte, musste ich mich richtig auf Objektorientierung einlassen und nach einiger Zeit wurde ich zum überzeugten Vertreter der OOP.Als dann der Hype um Handys aufkam und jeder sich damit wichtigmachen wollte, war meine Aussage: „So etwas brauche ich nicht!“ Ich brauche nicht zu betonen, dass mich irgendwann auch Handys überzeugt haben. Und als alle Welt von mobilem Internet geschwärmt hat ... Soziale Netzwerke, Blogs, etc. – alles habe ich erst einmal betrachtet, um es erst dann zu nutzen, wenn ich den Sinn und die Vorteile verstanden habe.Es scheint in meinem Leben immer so zu sein, dass ich bei einem Zug erst einmal schaue, wohin er fährt und ob er nicht gleich beim Verlassen des Bahnhofs entgleist. Aber wenn er abgeht, dann springe ich auf den letzten Wagen auf und arbeite mich sehr oft sogar bis zur Lok vor. Seltsamerweise klappt das dann meist.Was nun die Programmierung von Apps angeht, ist hier die Situation aber etwas anders. Wie angedeutet, liegen meine Wurzeln in der DesktopProgrammierung mit klassischen Sprachen, aber auch vor allen Dingen in Java und zum Teil C# bzw. .NET. Mein zweites Standbein, mit dem ich seit etwa 1996 hauptsächlich gearbeitet und programmiert habe, sind Webtechnologien. Nun bot Java schon sehr früh die Möglichkeit zur Entwicklung von mobilen Applikationen – die sogenannten MIDlets. Und mit denen habe ich mich beschäftigt, bevor der eigentliche Boom der mobilen Apps und mobilen Endgeräte begonnen hat. Die Erstellung von Apps ist sozusagen eine der wenigen technischen Entwicklungen, in denen ich zu früh dran war. Denn wie Sie vielleicht wissen, ist der MIDletZug entgleist. Oder anders ausgedrückt – MIDlets und die frühen mobilen programmierbaren Geräte wurden nicht gerade ein Erfolg. Von daher war ich dann wieder vorsichtig, als die aktuellen Apps und mobilen Geräte gehypt wurden. Aber immer am Puls, denn mit Java sowie C# hatte ich die Programmiergrundlagen seit Jahren bereit. Als dann zusätzlich Webtechnologien immer mehr als Basis für Apps und mobile Seiten bzw. Applikationen propagiert wurden, fügte sich im mobilen Bereich zusammen, was ich bereits über die Jahre in allen möglichen Umfeldern genutzt hatte.
2 Jeans und Turnschuhe konnten sich bei einer Versicherung als Geschäftskleidung nur Lagerarbeiter und Program-mierer leisten.
Vorwort XIII
Und ich bin von der Verwendung von Webtechnologien im mobilen Umfeld überzeugt, obwohl ich auch native AndroidApps mit Java oder Apps für Windows Phone mit C# erstelle. Nur der Einsatz von HTML5, CSS3 und JavaScript erlaubt die Erstellung universell verwendbarer WebApps für Android, Apple, Windows Phone und andere mobile Plattformen. Und mit PhoneGap können Sie auch die speziellen Features mobiler Endgeräte ausnutzen. Sie können etwa auf GPSEmpfänger, die Orientierung, die Kamera, Datenbanken etc. direkt aus JavaScript heraus zugreifen, ohne spezielle native Programmiertechniken lernen zu müssen. Ich zeige Ihnen in diesem Buch, wie das geht.
IhrRalph Steyerwww.rjs.de
4 1 Einleitung und Grundlagen
Wenn im Buch auf Software und Bibliotheken verwiesen wird, sollten Sie ebenso die Versionsnummern beachten (das wurde oben ja schon angedeutet). Gegebenenfalls werden auch hier neue Versionen verfügbar sein und bestimmte Erklärungen nicht mehr zu 100% übereinstimmen.
■ 1.3 Was ist PhoneGap?
PhoneGap, dessen Webseite Sie unter http://phonegap.com/ finden (siehe Bild 1.1), ist ein OpenSourceEntwicklungsFramework zur Programmierung von Apps mit JavaScript und anderen clientseitigen Webtechnologien, das aus einem iPhoneDevCampEvent in San Francisco hervorging und ursprünglich von der Firma Nitobi (http://www.nitobi.com/) entwickelt wurde.
BIlD 1.1 Die zentrale Seite des PhoneGap-Projekts
1.4 Was sollten Sie bereits wissen? 7
BIlD 1.2 Die Features von PhoneGap und wie weit sie auf den verschiedenen Plattformen zur Ver-fügung stehen
■ 1.4 Was sollten Sie bereits wissen?
Klären wir nun kurz, was Sie an Kenntnissen haben sollten, damit Sie mit dem Buch effektiv arbeiten können. Da wir mit PhoneGap explizit JavaScript programmieren, sind für Sie Grundlagenkenntnisse darin sehr sinnvoll. Und da JavaScript eigentlich nur im Rahmen einer HTMLSeite verwendet wird (serverseitiges JavaScript sei außer Acht gelassen), möchte ich ebenfalls voraussetzen, dass Sie HTML kennen. Ebenso sollten Style Sheets und CSS keine Fremdwörter für Sie sein. Sie brauchen allerdings keine professionellen Kenntnisse als Basis, weder in HTML, CSS oder JavaScript noch einer anderen Programmiersprache. Zu diesen drei Themen finden Sie bei Bedarf sowohl in Kapitel 4 als auch im Anhang eine konzentrierte Einführung. Grundsätzlich handelt es sich bei diesem Buch um ein Einsteigerbuch in die
10 1 Einleitung und Grundlagen
wohl wir uns letztendlich unter PhoneGap kaum2 mit der eigentlichen JavaProgrammierung auseinandersetzen müssen.Als Entwicklungsplattform (also das Betriebssystem, auf dem Sie programmieren) für Java sind Sie in der glücklichen Situation, dass Ihnen mehrere Varianten zur Verfügung stehen – sei es Linux, Windows oder auch Mac OS in den aktuellen Varianten. Aber dort benötigen Sie für die Entwicklung von JavaApplikationen gewisse Programme und Bibliotheken. Als Erstes sei das JDK (Java Development Kit) genannt. Die gesamte JavaEntwicklung dreht sich um jenes ominöse JDK. Sie finden das JDK beispielsweise für die verschiedenen Betriebssysteme auf den offiziellen JavaSeiten (Java SE Download) von Oracle unter http://www.oracle.com/technetwork/java/javase/downloads/index.html, wie Sie in Bild 1.3 sehen können.
BIlD 1.3 Download-Möglichkeiten für Java und das JDK
2 Sie werden in dem Java-Code für eine PhoneGap-App nur wenige Codezeilen mit vorgefertigten Bausteinen austauschen müssen.
12 1 Einleitung und Grundlagen
BIlD 1.4 Die Projektseite von Eclipse
Software für die Entwicklung von Windows-Phone-AppsWie erwähnt, benötigen Sie zur Entwicklung von WindowsPhoneApps einen geeigneten WindowsPC. Um auf diesem für Windows Phone eine native App zu entwickeln, laden Sie am besten die kostenlosen Windows Phone Developer Tools von Microsoft. Damit können Sie eigene Apps entwickeln und testen – auf dem Windows Phone oder am PC. Die Windows Phone Developer Tools enthalten zur Entwicklung für Windows Phone das Visual Studio Express, Expression Blend for Windows Phone, XNA Game Studio, Silverlight und das .NETFramework. Insbesondere beinhalten die Tools einen Emulator – den Windows Phone Emulator. Diesen können Sie natürlich zum Testen der nativen Windows PhoneApps, aber auch zum Testen von beliebigen mobilen Webseiten oder WebApps unter Realbedingungen verwenden, denn der Emulator bringt den Internet Explorer als integrierten Browser mit. Das Developer Center finden Sie unter http://msdn.microsoft.com/de-de/windowsphone/, wie Ihnen der Screenshot 1.5 zeigt.
1.5 Was sollten Sie haben? 13
BIlD 1.5 Die Entwicklungs-Tools von Microsoft
Nach dem Download der Windows Phone Developer Tools führen Sie einfach die Installa tionsdatei aus. Dabei müssen Sie die Lizenzbedingungen bestätigen und etwas warten. Je nach Verbindungsgeschwindigkeit und Performance des Rechners kann die Installation einige Minuten dauern, aber das war alles.
Software für die Entwicklung von iOS-AppsDie Entwicklung von Apps für mobile AppleGeräte setzt einen geeigneten Mac voraus, auf dem Sie die Xcode Developer Tools (https://developer.apple.com/technologies/tools/ – Bild 1.6) installieren sollten.Dieses Paket bietet alles, was Sie brauchen, um Anwendungen für Mac, aber auch iPhone und iPad zu erstellen. Xcode ist eng mit den Cocoa und Cocoa TouchFrameworks verbunden. Das XcodeToolset enthält die Xcode IDE mit dem Interface Builder DesignTool und dem voll integrierten Apple LLVM Compiler sowie der üblichen weiteren unterstützenden EntwicklerTools. Von besonderer Bedeutung ist die Integration eines iOS-Simulators, auf dem Ihre Anwendung in der gleichen Weise abläuft, als wenn ein tatsächliches iOSGerät die Basis wäre.
14 1 Einleitung und Grundlagen
Apple versteht also in Hinsicht auf die Anwendung durch den Programmierer unter dem Simulator das, was Google und Microsoft mit Emulator bezeichnen. Wir werden in der Folge einheitlich nur den Begriff Emulator verwenden.
Software für die neutrale WebentwicklungGrundsätzlich sollten die bisher beschriebenen Tools alles beinhalten, was Sie zum Erstellen von Apps benötigen. Aber wir wollen ja WebApps erstellen und das bedeutet, dass wir ziemlich viel mit HTML, CSS und JavaScript arbeiten. Es kann durchaus sinnvoll sein, dass Sie zusätzliche Programme verwenden, in denen Sie diese Codefragmente extern bearbeiten, um dann erst die Webstrukturen in die eigentlichen AppsIDEs hineinkopieren. Ich mache das oft, wenn die IDEs mir zu schwergewichtig sind oder nicht das bieten, was ich gerne hätte. Ich persönlich arbeite bei reinen Websprachen sehr gerne mit Notepad++ (http://notepad-plus-plus.org/) als Editor. Aber auch Plugins wie Aptana (http://www.aptana.com/) für Eclipse können Ihnen bei Webtechnologien viel helfen, wenn Standardfunktionalitäten nicht genügen bzw. nicht optimal sind. Sehr sinnvoll ist auch ein
BIlD 1.6 Die Entwicklungs-Tools von Apple
16 1 Einleitung und Grundlagen
BIlD 1.7 Registrierung bei Google
Der Account ist derzeit kostenlos und Sie können ihn multifunktional verwenden (YouTube, Kalender, Maps, Analytics, …). Google wird allerdings beim Vertrieb von kostenpflichtigen Apps einen Anteil fordern und bei konkreten Einzelleistungen bzw. Details sollten Sie die genauen Bedingungen unbedingt nachlesen, denn diese können in manchen Fällen kostenpflichtig bzw. nicht frei sein.Betrachten wir nun noch, was sich hinter dem oft im AndroidUmfeld zu findenden Schlagwort „rooten“ verbirgt. Ein Gerät zu rooten, bedeutet, dass Sie sich als Besitzer mehr Rechte im AndroidBetriebssystem einräumen, als Sie normalerweise besitzen. Android verfügt als LinuxSystem über ein ausgefeiltes Rechtesystem mit der Rolle (Konto) Root oder Superuser als oberstem Herrn im System. Der Root hat die höchst möglichen Zugriffsrechte auf das gesamte Betriebssystem und damit auch die Hardware. Im Auslieferungszustand gewähren die Hersteller von mobilen Geräten mit Android einem Nutzer diese maximalen Rechte nicht, was äußert sinnvoll ist. Denn der Root kann die Kernfunktionen des Betriebssystems verändern und im Fehlerfall massiven Schaden anrichten sowie die Kontrolle über das Gerät übernehmen oder auch einer App die Möglichkeit einräumen ein Gerät unbemerkt auszuspionieren. Auch sollten Sie sich im Klaren darüber sein, dass mit der Änderung der Nutzerrechte bzw. dem Freischalten des RootKontos Garantieansprüche gefährdet sind.Nun stellt sich die Frage, ob Sie als Entwickler so ein gerootetes Gerät brauchen? Die Antwort ist „jain“. Für Entwicklungszwecke gibt es im Ausgleich zu den Risiken massive Vorteile gegenüber der kastrierten Anwendervariante. Durch die volle Kontrolle über das AndroidBetriebssystem können Sie etwa installierte Apps auf die SDKarte verschieben und vor allen Dingen (was in unserem Kontext wichtig ist) aus „unsicheren“ Quellen Apps installieren. Das bedeutet, dass Sie Ihre Apps ohne Umwege und irgendwelche Einschränkungen auf dem Gerät installieren und testen können. Darüber hinaus benötigen einige Apps selbst rootRechte, wenn sie auf tiefere Prozesse des Betriebssystems zugreifen wollen. Von daher kann auch für den reinen Anwender, der ein gewisses Risiko nicht scheut und sich zumindest ein wenig mit Android auskennt, das Rooten von seinem Gerät nützlich sein. Und wenn Sie als Entwickler Apps erzeugen wollen, die solche tiefen Betriebssystemfeatures nutzen wollen, müssen Sie rooten. Andererseits werden die meisten Apps gar nicht solche Betriebssystemfeatures nutzen und es ist eben auch ein Risiko, wenn Sie das Gerät weit öffnen.Wenn Sie sich allerdings dazu entschließen – der Weg zum Rooten eines Geräts ist leider nicht ganz einheitlich (ein Preis dessen, dass Android frei und kaum reglementiert ist). Es gibt aber im Internet für die meisten gängigen Geräte SchrittfürSchrittAnleitungen, die Sie über das Schlagwort Rooten und den Namen Ihres Geräts finden (Bild 1.8).Darüber hinaus gibt es diverse Programme, die gezielt einige Geräte rooten (etwa SuperOneClick für das Galaxy S2). Das ist natürlich der einfachste Weg.
1.5 Was sollten Sie haben? 17
BIlD 1.8 Diverse Anleitungen und Tools zum Rooten findet man im Internet.
Sich als Microsoft-Entwickler registrieren und das Windows Phone-Gerät freischaltenUnter Windows Phone ist es so, dass Sie Ihr Gerät explizit als Entwicklergerät freischalten müssen, damit Sie ohne Umwege Ihre Apps auf Ihrem Gerät installieren und testen können. Dazu müssen Sie sich zuerst einmal als Entwickler bei Microsoft registrieren. Das ist letztendlich auch notwendig, wenn Sie Ihre Apps im Microsoft Market irgendwann veröffentlichen wollen. Von daher bleibt Ihnen sowieso keine Wahl, wenn Sie Apps für Windows Phone entwickeln wollen – Sie müssen sich so oder so als Entwickler registrieren. Das können Sie etwa über die zentralen Entwicklerseiten unter http://create.msdn.com und dort über den Link zum Windows Phone Dev Center unter https://dev.windowsphone.com/ (Bild 1.9).Dort finden Sie einen Link zum Anmelden, wenn Sie bereits einen Account haben, und dort wiederum einen weiteren Link, über den Sie einen neuen EntwicklerAccount anlegen können. Um als Entwickler bei Microsoft registriert zu sein, müssen Sie derzeit 99 EUR im Jahr bezahlen. Sie können dann aber auch beliebig Anwendungen in den Marketplace stellen, bekommen wichtige Informationen, haben Zugang zu Foren und Hilfe und Sie können eben vor allen Dingen Ihr Gerät freischalten.
20 1 Einleitung und Grundlagen
BIlD 1.12 Zune ist umstritten, aber derzeit notwendig.
BIlD 1.13 Die angemeldeten Smartphones
Nach der Freischaltung kann man Windows PhoneApps nun direkt auf dem Gerät aufspielen, indem man die xapDatei (die kompilierte App) mit einem weiteren Tool aus dem Windows Phone SDK dorthin überspielt – dem Application Deployment (Bild 1.14). Diesen Vorgang können Sie aber auch direkt aus dem Visual Studio auslösen – auf mehrere Arten, die wir bei der konkreten Erstellung einer App im nächsten Kapitel noch behandeln. Aber auch diese Übertragung mit dem Visual Studio setzt voraus, dass Ihr Smartphone freigeschaltet, per USB angeschlossen und Zune gestartet ist.
1.5 Was sollten Sie haben? 21
BIlD 1.14 Das Application Deployment-Tool
ApfelsaftAuch wenn Sie für iOS Apps entwickeln, müssen Sie sich als Entwickler registrieren. Dazu gibt es das iOS Dev Center unter https://developer.apple.com/devcenter/ios/index.action (Bild 1.15) bzw. die Registrierungsseite unter https://developer.apple.com/programs/register/ (Bild 1.16), in der Sie sich in Ihrem Bereich einloggen und eben auch registrieren können. Sie benötigen für Ihre Apps auf jeden Fall eine Apple ID.
BIlD 1.15 Die allgemeinen iOS-Entwicklerseiten von Apple
22 1 Einleitung und Grundlagen
BIlD 1.16 Registrieren als Apple-Entwickler
Haben Sie nur eine Apple ID samt Account, können Sie Apps im Apple App Store veröffentlichen (wobei es da verschiedene Distributionsmodelle gibt – das führt hier aber zu weit) und auch auf Testgeräten installieren. Diese müssen im iPhone Developer Program unter Devices / Add Devices hinzugefügt werden. Ebenso werden Sie in der Regel ein DistributionZertifikat benötigen (Certificates / Distribution).
1.5.3 Verschiedene Wege zum Testen
Wie wir besprochen haben, stehen Ihnen also für Ihre Apps verschiedene Wege zum Testen zur Verfügung, bevor Sie diese unter die Leute bringen. Fassen wir sie zusammen.Sie werden in der Regel Ihre WebApps auf einem DesktopRechner entwickeln. Es ist sinnvoll, wenn Ihnen dort ein Satz an modernen Webbrowsern zur Verfügung steht. Diese Browser sollten die speziellen Features aus dem mobilen Umfeld unterstützen, etwa die Widgets und Effekte aus dem Framework jQuery Mobile. Damit können Sie zumindest die reinen Webfunktionalitäten einer WebApp auf die Schnelle testen. Aber das ist natürlich nicht ausreichend, wenn Sie vor allen Dingen die speziellen HardwareFunktionen testen wollen. Auf jeden Fall sind die meisten DesktopBrowser nur für einen oberflächlichen Eindruck geeignet, wie eine WebApp in der Realität (also auf einem mobilen Endgerät wie einem Tablet oder Smartphone) aussieht und wie sie sich dort verhält. Einen wirklich realistischen Test können Sie nur mit mobilen Geräten erreichen. Das bedeutet, Sie sollten die WebApps auch
26 2 Native Apps versus Web-Apps und mobile Webapplikationen
2.1.1 Webseiten
Einmal sollte man reine Webseiten als eher passive Angebote verstehen, die dem Besucher klassische Webfunktionalitäten bereitstehen. Das gilt auch für spezielle mobile Webseiten, wie sie etwa mit jQuery Mobile erzeugt werden können. Diese sind zwar auf die mobilen Gegebenheiten durch geeignete Benutzerschnittstellen hin optimiert. Es handelt sich dennoch um gewöhnliche Webseiten, die nur an den Besonderheiten mobiler Umgebungen orientiert sind. Das sind etwa die spezifischen Eingabemöglichkeiten oder die oft geringen Bildschirmgrößen und auflösungen.
2.1.2 Webapplikationen – RIA
Webapplikationen hingegen sind zuerst einmal aus Sicht des Betrachters viel interaktiver als konventionelle Webseiten. Es sind vom Verhalten her echte Applikationen, mit denen man richtig interagieren kann und die Leistungen bereitstellen, wie man sie von DesktopApplikationen kennt, auch wenn diese wie normale Webseiten in einem Browser geladen werden. Beispiele sind Routenplaner wie Google Maps, Terminverwaltung wie Google Calendar oder die zahlreichen Webspiele. Unter dem Begriff RIA (Rich Internet Application) fasst man diese Angebote meist zusammen. Diese Webapplikationen lassen sich natürlich auch gut an die Gegebenheiten auf den mobilen Endgeräten anpassen.Für unsere Situation wollen wir diese Unterschiede zwischen mobilen Webseiten und Webapplikationen aber nicht weiter ausarbeiten, denn hier sollen Apps im Fokus stehen.
2.1.3 Besonderheiten von Web-Apps
WebApps lassen sich recht deutlich von den reinen Webseiten/Webapplikationen differenzieren. Allgemein stellen mobile Webapplikationen oder mobile Webseiten Inhalte bereit, die von einem Webserver in einem – bereits auf dem mobilen Endgerät vorhandenen – Browser geladen werden und auch nur dort „leben“. Sie werden innerhalb dieses Browsers interpretiert und es wird nichts auf dem Gerät des Anwenders installiert. Dadurch, dass mobile Webseiten und Webapplikationen jedoch immer im Rahmen eines Standardbrowsers ausgeführt werden, werden sie auch durch den Browser beschränkt. Das ist ein sinnvolles Sicherheitsfeature, aber eben auch eine Einschränkung gegenüber den Möglichkeiten, die native Programme auf einer Plattform bieten. Eine WebApp arbeitet hingegen zwar auch mit gewöhnlichen Webtechnologien wie HTML oder JavaScript, wird aber über einen geeigneten Mechanismus als eigenständige App auf dem mobilen Endgerät installiert und kann – gegebenenfalls über Schnittstellen wie PhoneGap – Ressourcen des mobilen Endgeräts mehr und besser nutzen als es bei Webapplikationen möglich ist. Oder anders und ein bisschen leger ausgedrückt – eine WebApp bringt ihren eigenen Browser mit, der auf eine geeignete Weise auf dem mobilen Gerät installiert wird (bzw. den vorhandenen Browser so klont und anpasst, dass das möglich ist). Über diese Browserkomponente wird die WebApp letztendlich nativ ausgeführt. Man sollte aber dennoch noch einmal festhalten, dass der Kerncode von mobilen Webapplikationen/Webseiten und WebApps weitgehend identisch ist bzw. sein kann.
2.2 Native Apps 31
BIlD 2.2 Download des ADT Plug-ins
Installation des ADT-Plug-insDas Installieren des ADTPlugins erfolgt nun am einfachsten mit dem UpdateManager von Eclipse. � Sie wählen im ersten Schritt Help / Install New Software aus. � Nun erstellen Sie eine neue Lesezeichenseite für den URL des zu installierenden Plugins. Das geht über die AddSchaltfläche.
� Im nachfolgenden Dialog tragen Sie einen Namen (am besten ADT-Plug-in) und den URL der PluginQuelle ein. Zum Zeitpunkt der Bucherstellung ist das https://dl-ssl.google.com/android/eclipse/, aber das kann sich in neuen Versionen ändern. Auf der DownloadSeite sehen Sie aber die aktuell notwendigen Angaben. Eventuell müssen Sie statt https nur http nehmen.
� Im nächsten Schritt können Sie gezielt auswählen, welche Bestandteile der Erweiterungen für Android Sie installieren wollen. Am besten installieren Sie alles, was Ihnen angeboten wird.
Der Rest der Installation wird vom Update Manager durchgeführt. Sie müssen bloß den Fortschritt beobachten und einige wenige Fragen (etwa nach der Lizenz oder ob wirklich
2.2 Native Apps 33
BIlD 2.3 Lokalisierung des Android SDK
34 2 Native Apps versus Web-Apps und mobile Webapplikationen
BIlD 2.4 Der AVD Manager im Android SDK
2.2.1.1 Eine Android-App mit Eclipse und dem ADT-Plug-in erzeugenSofern nun alle notwendigen Ergänzungen für Eclipse vorgenommen wurden, können Sie eine AndroidApp damit erzeugen, testen und ausliefern. Die grundsätzliche Erstellung einer AndroidApp mit Eclipse und dem ADTPlugin läuft in mehreren Schritten ab.1. Zuerst werden Sie in Eclipse ein spezielles Android-Projekt anlegen. Dabei können Sie
verschiedene Angaben zu der Zielplattform etc. machen.2. Dann schreiben Sie den notwendigen JavaCode samt den ergänzenden Codestrukturen,
die etwa auf XML beruhen. Das setzt natürlich entsprechende Kenntnisse voraus. Für unseren Fall werden wir uns weitgehend auf die Vorgabecodes beschränken.
3. Eine AndroidApp können Sie wie gesagt aus Eclipse heraus in einem Emulator ausführen und testen. Das werden Sie vor einer Fertigstellung immer wieder machen. Dabei ist dieser Emulator allgemeiner zu sehen – Sie können darüber auch hervorragend mobile WebApps testen, denn der Emulator enthält – wie jedes reale AndroidSystem – einen WebBrowser, über den Sie WebApps bzw. mobile Webseiten laden und testen können.
4. Wenn die App fertig ist, werden Sie diese weitergeben wollen. Um eine App weiterzugeben, erstellen Sie ein spezielles Package. Dieses kann man mit Eclipse und den AndroidErweiterungen von Google erzeugen. Ebenso finden Sie hier Features, um Ihre App im Marktplatz von Google zu veröffentlichen, was aber im Moment unseren Rahmen sprengt.
Gehen wir es nun konkret an:Legen Sie zuerst in Eclipse ein neues AndroidProjekt an. Das finden Sie in Eclipse unter dem Menüpunkt File / New / Other / Android.
36 2 Native Apps versus Web-Apps und mobile Webapplikationen
BIlD 2.6 Den Namen des Android-Projekts festlegen – hier Eclipse 3.7
BIlD 2.7 Auswahl der Zielplattform – Eclipse 3.7
38 2 Native Apps versus Web-Apps und mobile Webapplikationen
BIlD 2.8 Angabe des Package, dem die Android-Klasse zugeordnet wird
BIlD 2.9 Im zweiten Dialogschritt können Sie ab Eclipse 4 mehr Angaben zentral festlegen.
40 2 Native Apps versus Web-Apps und mobile Webapplikationen
BIlD 2.11 Wahl der Start-Activity
BIlD 2.12 Die Angaben zur inneren Navigation der Activity bzw. App sollten ihre Vorgabe-werte behalten.
2.2 Native Apps 41
Die folgenden Details zur inneren Navigation in der Activity (Bild 2.12) sprengen unseren Rahmen. Bleiben Sie einfach bei den Vorgabewerten.Im abschließenden Schritt können eventuell notwendige Nachinstallationen durchgeführt werden (Bild 2.13). Das kann notwendig sein, wenn Sie eine Zielplattform ausgewählt haben, für die noch Bibliotheken fehlen.
BIlD 2.13 Wenn Bibliotheken fehlen, können diese nachinstalliert werden.
Sowohl bei älteren Versionen von Eclipse als auch bei neuen Versionen bestätigen Sie den gesamten Assistenten mit Finish. Nach einer Weile sehen Sie in Eclipse den generierten Code und die erzeugten Ressourcen bzw. Dateien (Bild 2.14).
42 2 Native Apps versus Web-Apps und mobile Webapplikationen
BIlD 2.14 Die erste native App ist fertig.
2.2.1.2 Eine Android-App im Emulator ausführenNun können Sie die App im Package Explorer von Eclipse mit der rechten Maustaste auswählen und aus dem folgenden Kontextmenü mit dem Befehl Run as / Android Application im Emulator ausführen (Bild 2.15).Der Start der App im Emulator kann eine Weile2 dauern – also nicht ungeduldig werden. Sie werden auch keine sonderlich spannende App sehen, denn es ist nur etwas DefaultCode generiert worden (Bild 2.16). Aber rein funktional ist die App vollständig und so unter Android lauffähig.
2 Durchaus mehrere Minuten
2.2 Native Apps 43
BIlD 2.15 Starten der App im Emulator
BIlD 2.16 Die einfache native App im Emulator
44 2 Native Apps versus Web-Apps und mobile Webapplikationen
2.2.1.3 Eine Android-App exportieren und auf einem mobilen Gerät ausführen
Um eine AndroidApp auf einem realen Smartphone oder Tablet auszuführen, muss sie dort installiert werden. Dazu kopieren Sie einfach die .apkDatei mit der App auf das Gerät und öffnen diese dort. Sofern keine Rechteprobleme bestehen, wird die App installiert und Sie können sie ausführen. Ebenso benötigen Sie so eine .apkDatei, wenn Sie die App im Marktplatz von Google veröffentlichen bzw. vermarkten wollen.Aber wie wird aus Ihrer App eine solche .apkDatei? Mit Hilfe der Android Tools, die Sie im Kontextmenü des Package Explorers von Eclipse beim Klick auf Ihr Projekt finden, können Sie die App in der Form exportieren. Dabei können Sie sowohl eine signierte als auch eine unsignierte App exportieren (Bild 2.17), was letztendlich sowohl die Akzeptanz der App als auch die Rechte für die Installation berührt.
BIlD 2.17 Exportieren einer Android-App
BIlD 2.18 Auswahl des Schlüssel-speichers
2.2 Native Apps 45
Wollen Sie die App später vertreiben, müssen Sie auf jeden Fall den Assistenten zum Signieren durchlaufen. Aber auch zum Testen ist das besser, da Sie sich sonst möglicherweise unnötige Probleme bei der Installation einhandeln. Der Assistent zum Exportieren und Signieren Ihrer App fordert von Ihnen nach der Angabe eines Namens die Spezifikation eines passwortgeschützten Schlüsselspeichers (Keystore – siehe Bild 2.18)3. Darin werden die Schlüssel für Ihre App verwaltet, über die Sie die App mit einem Zertifikat signieren können. Sie können sowohl einen vorhandenen Schlüsselspeicher verwenden als auch selbst einen neuen anlegen.In dem gewählten Schlüsselspeicher können Sie dann einen konkreten Schlüssel auswählen (Bild 2.19), über den Sie die App signieren wollen.
BIlD 2.19 Den konkreten Schlüssel auswählen
Entweder verwenden Sie einen bereits vorhandenen Schlüssel oder aber Sie legen einen neuen Schlüssel an. Bei einem neuen Schlüssel müssen Sie in einem weiteren Schritt neben einem Alias für den Schlüssel und einem Passwort einige Eckdaten wie Ihren Namen und Wohnort angeben (Bild 2.20), woraus dann ein eindeutiges Zertifikat generiert wird.Im letzten Schritt speichern Sie die zertifizierte App. Anschließend können Sie diese auf Ihr Smartphone kopieren oder im Google Markt veröffentlichen.
3 Im Hintergrund werkeln hier Tools des JDK wie der jarsigner.
46 2 Native Apps versus Web-Apps und mobile Webapplikationen
BIlD 2.20 Einen neuen Schlüssel anlegen
2.2.2 Eine native App unter Windows Phone
Ich möchte Ihnen noch einen zweiten Weg zu einer nativen App in einer anderen Welt knapp vorstellen, dieses Mal aber gezielt für Windows Phone. Sie werden sehen, dass sich die Grundschritte trotz diverser Unterschiede in den Details ähneln, da man im Grunde für alle nativen Apps ähnlich vorgehen muss – gleich welche Zielplattform man im Auge hat. Und auch hier gilt, dass wir weitere notwendige Grundlagen für WebApps mit unter PhoneGap legen.
Windows PhoneWindows Phone bezeichnet den Nachfolger von Windows Mobile, mit dem Microsoft im Zusammenhang mit Windows 8 eine weitere Fusion von mobilen und stationären Anwendungen und Geräten vorantreiben möchte. Insbesondere wird ein vereinheitlichtes Designkonzept in den Fokus gestellt. Zentraler Aspekt ist der Zwang für Hardwarehersteller, dass ihre Geräte einen Mindeststandard einhalten und eine einheitliche Benutzeroberfläche bereitstellen müssen, damit Windows Phone damit ausgeliefert werden darf. Bei der Benutzerführung geht Microsoft neue Wege und hebt sich damit sowohl im Look & Feel als auch in der Philosophie deutlich von AndroidGeräten ab.
48 2 Native Apps versus Web-Apps und mobile Webapplikationen
BIlD 2.22 Eine native Windows-Phone-App mit Blend anlegen
BIlD 2.23 Die IDE von Blend mit der generierten App
2.2 Native Apps 49
2.2.2.2 Die Ausführung im EmulatorMit F5 können Sie die App nun im Emulator des Visual Studios ausführen (Bild 2.24).
BIlD 2.24 Die App läuft im Emulator der Windows Phone Developer Tools.
2.2.2.3 Installation und Ausführen auf einem realen HandyDie Installation auf einem konkreten Smartphone erledigen Sie mit dem SDK selbst, wie es im vorherigen Kapitel beschrieben wurde, oder aber Sie laden die mit Blend erstellte Lösung in das Visual Studio für Windows Phone (das mit Blend erstellte Projekt kann da problemlos geladen werden) und führen dort die App aus. Mit Strg + F5 oder dem kleinen grünen Pfeil in der Symbolleiste neben dem Ausgabemedium (Device – Bild 2.25) können Sie die App im Emulator ausführen oder aber direkt auf ein per USB angeschlossenes und vorher als EntwicklerHandy freigeschaltetes Smartphone installieren und dort ausführen. Beachten Sie, dass Zune dabei parallel gestartet ist.
BIlD 2.25 Auswahl des Device
2.2.3 Eine native App für iOS
Die Entwicklung sowohl einer nativen als auch später einer PhoneGapApp unter iOS erfolgt in der Regel mit Xcode (siehe Bild 2.26) und ist von den Grundschritten ähnlich einfach wie der Vorgang für Windows Phone.Dazu wird nach dem Start von Xcode mit Create a new Xcode project ein neues Projekt angelegt. Aus den folgenden Templates können Sie sich eine geeignete vorgegebene Projektstruktur auswählen (etwa MasterDetailApplication – siehe Bild 2.27) und dann den folgenden Assistenten durchgehen.
50 2 Native Apps versus Web-Apps und mobile Webapplikationen
BIlD 2.26 Die Entwicklung für iOS unter Xcode
BIlD 2.27 Auswahl einer geeigneten Projektstruktur
Im so aufgerufenen Assistenten vergeben Sie die wichtigsten Daten zu dem Projekt (analog der Vorgehensweise für Android und Windows Phone – in diesem Fall Name, Organisation, Zieldevice, Speicherort etc.). Bleiben Sie ansonsten bei den Vorgaben. Wenn Sie den Assistenten beenden, haben Sie bereits eine vollständig lauffähige App (siehe Bild 2.28), die mit dem Klick auf den grünen Pfeil links oben im iOSSimulator gestartet werden kann.
2.2 Native Apps 51
BIlD 2.28 Die App ist lauffähig.
Nach einer gewissen Zeit sollte die App im iOSSimulator zu sehen sein (siehe Bild 2.29).
BIlD 2.29 Eine App im iOS-Simulator
64 3 Download und erste Anwendung von PhoneGap
Verwenden der Datei CordovaStarter-x.x.x.zipIn den älteren PhoneGapVersionen5 ist man so vorgegangen, dass Sie im unter windows-phone von Ihnen geladenen und entpackten PhoneGapVerzeichnis die Datei CordovaStarter-x.x.x.zip gesucht haben, wobei x.x.x wieder durch die konkrete Versionsangabe zu ersetzen ist.Diese Datei kann sich – je nach Version von PhoneGap – in verschiedenen Unterverzeichnissen befinden, etwa unter lib oder templates. Kopieren Sie diese Datei in das Verzeichnis \My Documents\Visual Studio 2010\Templates\ProjectTemplates\ bzw. \Eigene Dokumente\Visual Studio 2010\Templates\ProjectTemplates\. Wenn Sie wollen, können Sie die Datei auch in ein Unterverzeichnis dort (etwa Visual C#) kopieren.Starten Sie das Visual Studio über den Menüeintrag Microsoft Visual Studio 2010 / Microsoft Visual Studio 2010 for Windows Phone.Legen Sie dort mit Datei / Neues Projekt / CordovaStarterx.x.x ein neues PhoneGapProjekt an (die drei X stehen wie üblich für die Version – siehe Bild 3.7). Dabei wählen wir den Namen PhoneGapWindowsPhone1.
BIlD 3.7 Anlegen eines PhoneGap-Projekts mit dem Visual Studio
5 Es ist zwar unwahrscheinlich, aber vielleicht kehrt PhoneGap auch in neueren Versionen zu dem Weg zurück.
3.2 Die konkrete Bereitstellung für Projekte 65
BIlD 3.8 Das Projekt ist fertig für die Arbeit mit PhoneGap.
Mehr ist unter dem Visual Studio an Schritten nicht notwendig, denn der Assistent hat die PhoneGapJavaScriptDatei bereits in das wwwVerzeichnis des Projekts kopiert und auch sonst alle notwendigen Dateien angelegt (Bild 3.8).
Projekt-TemplatesMit der APIVersion 2.1 hat sich der Installationsweg von PhoneGap geändert und insbesondere ist in der Version 2.2 auch Unterstützung für Windows Phone 8 hinzugekommen. Die Einrichtung basiert nun auf Projekt-Templates, die man auch InstallationsTemplates nennen könnte6. Im Verzeichnis templates finden Sie im Unterverzeichnis standalone ein VisualStudioProjekt. Dieses stellt ein Template dar, das den vollständigen Quellcode für Windows Phone enthält. Sie brauchen bloß die SolutionDatei im Visual Studio öffnen (siehe Bild 3.9).
6 Auch für Windows Phone 8 gibt es bereits ein Standard-Template, aber wir beschreiben hier den Weg für Windows Phone 7.x.
66 3 Download und erste Anwendung von PhoneGap
BIlD 3.9 Das Projekt-Template im Visual Studio
Dann wählen Sie File → Export Template… bzw. Datei → Vorlage exportieren… (siehe Bild 3.10) und folgen den Anweisungen des Assistenten.
BIlD 3.10 Exportieren der Vorlage, die aus dem Template generiert wird
Im Assistenten geben Sie zunächst an, was für einen Vorlagetypen Sie aus welchem Projekt exportieren wollen (Bild 3.11). Bleiben Sie einfach bei den Vorgaben.
3.2 Die konkrete Bereitstellung für Projekte 67
BIlD 3.11 Der Typ der Projektvorlage
Im nächsten Schritt geben Sie eine Bezeichnung für die Vorlage an, unter der Sie diese später auch wiederfinden (siehe Bild 3.12).
BIlD 3.12 Die generierte Vorlage wird gekennzeichnet.
68 3 Download und erste Anwendung von PhoneGap
Anschließend können Sie mit der neu angelegten Vorlage ein PhoneGapProjekt anlegen (Bild 3.13).
BIlD 3.13 Mit der neuen Vorlage können Sie ein PhoneGap-Projekt anlegen.
Die generierten StrukturenUnabhängig davon, wie Sie zu einem PhoneGapProjekt für Windows Phone gekommen sind – im Verzeichnis www finden Sie die generierte HTMLDatei index.html, die im Wesentlichen ähnlich aufgebaut ist wie die HTMLDatei, die wir unter Android selbst erstellt haben. Ebenso werden Sie eine JavaScriptDatei für die CordovaBibliothek im wwwVerzeichnis finden.Wenn nun in der Symbolleiste des Visual Studio als Ziel für das Projekt der Emulator vorbelegt ist (Standardfall), können Sie die App mit F5 debuggen oder mit Shift + F5 ohne Debugmodus im Emulator ausführen (Bild 3.14). Alternativ geht auch der Klick auf den kleinen grünen Pfeil in der Symbolleiste links neben dem Ziel. Und wenn ein freigeschaltetes EntwicklerHandy mit Ihrem PC verbunden sowie Zune gestartet ist, können Sie die App auch direkt dorthin installieren und ausführen, was wir im letzten Kapitel ja schon besprochen haben.
3.2 Die konkrete Bereitstellung für Projekte 69
BIlD 3.14 Die Default-App im Emulator
3.2.3 PhoneGap für iOS einrichten
Besprechen wir abschließend, wie Sie PhoneGap für iOS verwenden können. Auch hier wird das Verfahren einfacher als unter Android sein. Dabei werden Xcode und die XcodeKommandozeilenwerkzeuge vorausgesetzt, wie sie im vorherigen Kapitel erwähnt wurden.Um ein neues PhoneGapProjekt aufzusetzen, nutzen Sie den Installer Cordova-x.x.x.pkg (x.x.x wird wieder durch die konkrete Versionsnummer ersetzt) aus dem Verzeichnis lib/ios in der entpackten DownloadDatei von PhoneGap.Kopieren Sie den binOrdner aus lib/ios auf Ihre Festplatte.
BIlD 3.15 Aufruf des Terminals über Dienstprogramme
Nun können Sie zum Beispiel konsolenbasiert ein PhoneGapProjekt anlegen. Führen Sie die Terminal.app aus (an das Terminalprogramm gelangen Sie über Gehe zu → Dienstprogramme – siehe Bild 3.15) und ziehen Sie den kopierten binOrdner auf das Terminal.appIcon in Ihrem Dock. Daraufhin sollte sich ein neues Terminalfenster öffnen. Darin geben Sie Folgendes ein:
70 3 Download und erste Anwendung von PhoneGap
lISTING 3.9 Anlegen des PhoneGap-Projekts
./create <PfadDesProjektordners> <Package-Name> <Projektname>
Die entsprechenden Angaben sind natürlich durch den Pfad des Projektordners (die Angabe muss entfallen, wenn das Verzeichnis bereits vorhanden ist), das gewünschte Paket (mit analoger Bezeichnerlogik wie in Android) und den konkreten Projektnamen zu ersetzen. Bestätigen Sie die Angabe mit Enter.Gehen Sie in das erzeugte Projektverzeichnis und führen Sie die Datei .xcodeproj aus (Bild 3.16).
BIlD 3.16 Die Xcode-Projektdatei wurde mit allen notwendigen Ordnern angelegt und kann aufgerufen werden.
Xcode sollte nun mit den Strukturen starten, die man auch aus der nativen AppEntwicklung für iOS kennt (Bild 3.17).
BIlD 3.17 Das PhoneGap-Projekt in Xcode
Um nun eine App im Simulator/Emulator auszuführen, ändern Sie das Ziel (Target) im SchemaDropdownMenü der Toolbar auf den Projektnamen, den Sie gewählt haben. Active SDK stellen Sie auf die passende Version des iOSSimulators ein (Bild 3.18).Alternativ können Sie auch im WillkommenBildschirm von Xcode nach der Installation von PhoneGap den Eintrag Create A New Xcode Project anklicken oder File → New → New Project verwenden.
3.3 Alles, was recht ist 73
besprochen – die Datei AndroidManifest.xml im Wurzelverzeichnis des Projekts (siehe Bild 3.5). Die Tags uses-permission regeln die einzelnen Anforderungen. Mit dem Attribut android:name="android.permission.VIBRATE" wird etwa gefordert, dass eine App den Vibrator des mobilen Geräts nutzen kann, android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_FINE_LOCATION und android.permission.ACCESS_LOCATION_EXTRA_COMMANDS braucht man bei Lokalisierungen, android.permission.ACCESS_NETWORK_STATE und android.permission.INTERNET sind für den Zugriff auf Netzwerk und Internet notwendig und android.permission.READ_CONTACTS und android.permission.WRITE_CONTACTS spezifizieren den Lese und Schreibzugriff auf das Kontaktbuch des Geräts. Die Bezeichner der Werte für die Rechte sind offensichtlich meist sprechend. Die genauen Festlegungen finden Sie unter http://developer.android.com/reference/android/Manifest.permission.html (Bild 3.19).
BIlD 3.19 Beschreibung der möglichen Rechte einer App unter Android
Nun lädt man in PhoneGap ja eine HTMLSeite in den Wrapper. Auch wenn man die HTMLDatei aus einer lokalen Ressource lädt, benötigt man Internetzugriff. Das ist etwas ärgerlich, weil man möglicherweise gegenüber Anwendern rechtfertigen muss, warum man auf das Internet zugreifen möchte (auch wenn man das eigentlich nicht braucht), aber das ist der Preis für den Einsatz von PhoneGap und Webtechnologien. Leider ist es in der Dokumentation sowohl von PhoneGap als auch von Android nicht ganz so klar, was man für eine PhoneGapApp sonst noch an Rechten wirklich benötigt. Die verschiedenen Quellen im Internet widersprechen sich und oft bleibt nur ausprobieren.
92 5 Wo bin ich und wo will ich hin?
BIlD 5.1 Der Windows Phone-Emulator zeigt die gleichen Eigenschaften von navigator an, die auch ein reales Gerät zur Verfügung stellt.
BIlD 5.2 Die Eigenschaften von navigator in einem realen Android-Tablet
Die Bedeutung von devicereadyMit dem Beispiel lässt sich auch die Bedeutung des Eventhandlers deviceready weiter verdeutlichen und der Bedeutung des PhoneGapAPI selbst. Wir betrachten eine kleine Abwandlung, in der wir bewusst in dem Beispiel auf den Eventhandler deviceready verzichten.
94 5 Wo bin ich und wo will ich hin?
BIlD 5.4 Opera ist weniger auskunftsfreudig.
■ 5.2 Geolokalisierung
Bei PhoneGap basiert die Geolokalisierung explizit auf der Geolocation API Specification des W3C (http://dev.w3.org/geo/api/spec-source.html) respektive der Erweiterung des DOM, der mit HTML5 einher geht. Auf diversen Plattformen (Android, BlackBerry, Bada, Windows Phone 7ff und webOS) gibt es bereits eine native Implementierung davon. Diese wird auch unter PhoneGap direkt verwendet. Für andere Plattformen ergänzt PhoneGap jedoch diese Möglichkeiten, so dass Sie einheitlich programmieren können.Die gesamte Geolokalisierung beruht in PhoneGap sowie in anderen Zugängen auf dem DOMObjekt navigator, das dafür aber bereits nativ1 um eine neue Eigenschaft erweitert wurde – navigator.geolocation. Bei geolocation handelt es sich selbst wieder um ein Objekt, über das verschiedene Methoden zur Lokalisierung bereitgestellt werden und die konkrete Technik der Lokalisierung vollkommen vor dem Anwender verborgen wird. Sie brauchen sich als Programmierer überhaupt nicht darum zu kümmern, wie konkret die Position ermittelt wird.
1 Also nicht durch PhoneGap, was Sie auch im letzten Beispiel bei der Ausgabe im normalen Webbrowser sehen können – auch da ist das navigator-Objekt bereits um die Fähigkeit zur Geolokalisierung erweitert.
96 5 Wo bin ich und wo will ich hin?
befindet), während es bei großen Funkzellen möglichweise eine Abweichung von mehreren Kilometern geben kann.
W-lANEine weitere Möglichkeit zur Lokalisierung verwendet WLANRouter, wenn deren Positionen bekannt sind. Diese Technik funktioniert bei allen Geräten, wenn diese mit dem WLANRouter verbunden sind. Das kann auch per Leitung sein, wenn der WLANRouter ebenso als normaler Router des LAN eingesetzt wird. Die Genauigkeit der Lokalisierung eines einzelnen Geräts kann auf wenige Meter genau sein, wobei in einem großen lokalen Netzwerk (etwa in einer großen Firma) durchaus große Abweichungen von der tatsächlichen Position eines einzelnen Geräts auftreten (auch wenn der Router selbst auf wenige Meter genau lokalisiert werden kann).Nun stellt sich aber die Frage, wie die Position eines WLANRouters und damit der angeschlossenen Geräte überhaupt ermittelt wird? Und wer überhaupt diese Positionen kennt?Die Beantwortung der Fragen führt unter anderem zu zwei neuen Schlagworten. Da gibt es einmal die MAC-Adresse (MediaAccessControl), die man berücksichtigen kann, und natürlich die IP-Nummer. Hinzu kommt die Angabe, wo diese gesammelt und lokalisiert werden.
MAC-Adressen und Geolocation ServicesDie MACAdresse2 ist eine eindeutige HardwareAdresse jedes einzelnen Netzwerkadapters auf der Welt3. Diese kann zur Identifizierung des zugehörigen Geräts in einem Rechnernetz verwendet werden. Und wenn so eine MACAdresse eines WLANRouters an einen Empfänger gesendet wird, kann dieser den Ort bestimmen, woher die Sendung kam.Aber woher kennt man den Ort des WLANRouters und wer kennt ihn? Es gibt spezielle GeoLocation Services, etwa von Apple den GeoLocationDienst Skyhook bzw. WiFi Access Point Database, von Nokia oder Google Gears bzw. die Google GeoLocationDienste. Diese liefern die genaue Position eines WLANRouters, wenn Sie dessen MACAdresse bei einer Anfrage zugesendet bekommen.Und woher kennen diese Dienste die Position eines WLANRouters? Da gibt es verschiedene Wege – von der manuellen Eingabe durch einen Anwender, der über den Router eine Adresse, die er in einem Webformular auf seinem angeschlossenen Rechner eingegeben hat, verschickt, bis hin zu Scannern, die die MACAdressen von Routern ausspionieren und dann samt den geografischen Positionen den GeoLocation ServicesBetreibern zukommen lassen. Und Letzteres ist nicht etwa an den Haaren herbeigezogen und ein Ausnahmefall. Im Gegenteil – das ist der Regelfall. Darüber erhalten die GeoLocation Services fast alle geografischen Positionen von WLANRoutern.Denn einmal senden viele mobile Geräte mit aktiviertem GPS und eingeschaltetem WLAN automatisch die MACAdressen aller WLANs in Reichweite und ihre aktuelle Position an die besagten GeoLocationDienste. Eine explizite Verbindung mit den jeweiligen WLANs ist dazu nicht vonnöten, denn zur Identifizierung senden die WLANRouter die MACAdressen offen
2 Bei Apple wird sie auch Ethernet-ID, Airport-ID oder Wi-Fi-Adresse genannt. Bei Microsoft finden Sie oft den Bezeichner Physikalische Adresse.Lokalisierung via MAC-Adresse.
3 Oder sollte es sein – sie kann gefälscht werden und es kann auch sein, dass Adressen durch Fehler mehrfach vorkommen. Aber im Allgemeinen kann man schon von einer weltweit eindeutigen Kennung sprechen.
98 5 Wo bin ich und wo will ich hin?
IP-AdressenWenn alle diese Quellen nicht verfügbar sind – selbst rein über IPNummern kann man Positionen bestimmen und das geht dann auch für PCs, die ganz ohne WLANRouter etc. online gehen. Die Genauigkeit ist da in der Regel zwar recht gering, aber zumindest die Region lässt sich bestimmen. Teilweise ist sogar mehr möglich, wenn bestimmte Voraussetzungen gegeben sind.Aber wie erfolgt diese Ortsbestimmung mit IPNummern? Erst einmal glauben viele Laien, dass sie vollkommen anonym im Internet surfen, da sie ja von ihren Providern dynamische IPAdressen zugeordnet bekommen. Das ist schon deswegen falsch, da – je nach aktueller Gesetzeslage – Provider die jeweilige Zuordnung einer IPAdresse protokollieren und über längere Zeit speichern müssen. Und selbst bei dynamisch zugewiesenen IPAdressen sollte man immer beachten, dass viele dynamisch vergebenen IPNummern immer wieder gleich vergeben werden und wenn eine Position einmal bekannt ist, spricht viel dafür, dass die IPAdresse wieder diese Position repräsentiert.Ebenso wäre Anonymität nicht identisch mit fehlender Information über die Position. Denn die Positionen der Einwahlknoten ins Internet sind ja bekannt. Von daher kann man leicht die Region bestimmen, woher eine Anfrage kommt. In der Regel ist zumindest die Stadt oder der Landkreis bekannt, aus der bzw. dem eine Anfrage stammt. Wenn man dann noch berücksichtigt, dass man Antwortzeiten zwischen dem Einwahlknoten und dem lokalen System messen kann, lässt sich die Entfernung zum Einwahlknoten recht genau schätzen5.Damit ist zwar nicht die Richtung aus Sicht des Einwahlknotens bestimmt, aber sollte man nun noch auf dem Client gewisse Anweisungen ausführen können (etwa mit einem Skript oder aus einer Anwendung heraus), kann man mit verschiedenen Techniken dem Inhaber einer IPAdresse doch viel näher kommen. Ein Skript kann etwa „nach Hause telefonieren“ oder Testdaten an mehrere Stationen schicken, deren Position man kennt, und dann über mathematische Verfahren wie Triangulation die genaue Position bestimmen.Im Allgemeinen ist die Lokalisierung rein über die IPAdresse jedoch recht ungenau und vor allen Dingen – und das ist wichtiger – für unsere Belange mit Apps und mobilen Geräten zu vernachlässigen.
Viel AuswahlEs gibt also mehrere Varianten, wie automatisch ein Gerät bzw. Standort mehr oder weniger genau lokalisiert werden kann. Wenn Sie einmal als Beispiel das Rechtesystem unter Android betrachten, kann man erkennen, dass der Zugriff einer App auf Standortdaten mit spezifischen Rechten eingefordert wird. Man unterscheidet hier etwa zwischen ACCESS_COARSE_LOCATION (grobe Standortbestimmung) und ACCESS_FINE_LOCATION (genaue Standortbestimmung), die oben beschriebene Techniken dann in dem mobilen Gerät nutzen.Die CoarseLocation wird mittels CellID (Positionsbestimmung über die Funkmasten für die mobile Telefonie) oder über WLAN Access Points mit Standortdaten bestimmt. Das ist wie gesagt nur eine relativ ungenaue (Funkzellen) bzw. unzuverlässige (WLAN) Bestimmung des Orts eines Geräts, die beispielsweise bei einer Navigation nicht genügt, aber zumindest interessante Orte in der Umgebung ermitteln oder lokalisierte Werbung zuordnen kann. Ebenso funktionieren diese Verfahren auch gut in geschlossenen Räumen.
5 Sie kennen vielleicht Tools wie ping oder traceroute/tracert.
102 5 Wo bin ich und wo will ich hin?
5.2.3 Die notwendigen Rechte und Plug-ins bei Geolocation
Wenn über einen Webbrowser im Rahmen einer geladenen Webseite (etwa bei Google Maps) eine Geolokalisierung vorgenommen werden soll, wird der Browser – falls die Sicherheitseinstellungen nicht unverantwortlich niedrig eingestellt werden – den Anwender vorher um Erlaubnis fragen (Bild 5.6).
BIlD 5.6 Browser sollten vor der Geolokalisierung warnen und um Erlaubnis fragen.
Im Fall von Apps wird zwar in der Regel nicht vor jedem Einsatz der Geolokalisierung die Erlaubnis eingeholt, aber bei der Installation der App werden Anwender davon in Kenntnis gesetzt. Und Sie müssen als Programmierer der App diese Permissions und unter Umständen auch das Nachinstallieren von Plugins einfordern. Wie besprochen, wird das je nach Zielbetriebssystem unterschiedlich gehandhabt.
AndroidUnter Android sollte in app/res/xml/plugins.xml Folgendes stehen:
lISTING 5.8 Das Plug-in sollte zur Geolokalisierung vorhanden sein.
<plugin name="Geolocation" value="org.apache.cordova.GeoBroker" />
In der Datei app/AndroidManifest.xml müssen – je nach gewünschter Art der Lokalisierung (siehe oben) – folgende Elemente auftauchen:
5.2 Geolokalisierung 113
der APIReferenz beschrieben sind. Sie können etwa überprüfen, ob eine Karte initialisiert und geladen wurde, die geografischen Koordinaten des Zentralpunkts der Karte setzen und abfragen oder den Zoomfaktor der Karte ermitteln oder setzen.Für eine Karte muss man verschiedene Angaben spezifizieren, was ja das einfache Beispiel schon zeigt. Sie sind teils optional, teils zwingend, etwa die Positionen, die wir aus der Geolokalisierung übernehmen und mit new google.maps.LatLng(latitude, longitude); in Form eines Koordinatenobjekts in den Optionen (in JSONNotation) verwenden. Dort wird auch die Karte über center zentriert. Daneben sehen Sie die Zoomstufe. Das bezeichnet die Auflösung der aktuellen Ansicht. Dazu geben Sie Werte zwischen 0 (die niedrigste Zoomstufe) und 19 (Maximalwert, der aber nicht für alle Orte verfügbar ist) an.Eine wichtige Möglichkeit bei einer Karte ist die Verwendung von Steuerelementen, über die ein Anwender unter anderem Kartenausschnitte verschieben und vergrößern bzw. verkleinern sowie den Typ der Karte auswählen kann. Dies wurde in alten Versionen des GoogleAPI über die Methode addControl() erledigt, aber mittlerweile erfolgt das meist alles deklarativ beim Initialisieren über die Optionen. Das sehen Sie an der Angabe mapTypeControl : true sowie der Festlegung der genauen Art des Steuerelements über navigationControlOptions : { style : google.maps.NavigationControlStyle.SMALL }. Mit mapTypeId : google.maps.MapTypeId.ROADMAP } spezifizieren Sie den Typ der Karte.Eine interessante Möglichkeit zur Ergänzung von Zusatzinformationen in einer Karte sind Overlays. Dies sind Objekte auf der Karte, die an Längen und Breitenangaben gekoppelt und sich damit beim Verschieben der Karte mit der Karte zusammen bewegen. Sie bleiben ebenso erhalten, wenn Sie den Typ der Karte verändern. Overlays werden oft nach deren Konstruktion zur Karte hinzugefügt und auch alle Overlays definieren ein OptionsObjekt, das beim Konstruieren verwendet werden kann und mit dem Sie die Karte bezeichnen können, auf der die Overlays angezeigt werden sollen. Das GoogleMapsAPI stellt unter anderem sogenannte Marker zur Verfügung, die wir in dem Beispiel verwenden. Das sind Symbole in der Karte, die spezifische Punkte in einer Karte markieren. Ein Marker ist im GoogleMapsAPI der Version 3 vom Typ google.maps.Marker. Dessen Konstruktor verwendet ein Objektliteral mit den Optionen eines einzelnes Marker, das die anfänglichen Eigenschaften der Markierung angibt. Die Position ist bei der Konstruktion einer Markierung besonders wichtig und wird üblicherweise festgelegt. Wir markieren in dem Beispiel einfach das Zentrum der Karte, weil dies ja die Position des mobilen Geräts angibt (siehe Bild 5.9).
BIlD 5.9 Die Lokalisierung und Markierung einer Position in einem realen Android-Tablet
5.2 Geolokalisierung 115
BIlD 5.10 Die Verwendung des Bing-API im Emulator mit Dummy-Koordinaten
Wenn diese App geladen wird, sehen Sie auch da die Position in der Karte mit einem Marker markiert (siehe Bild 5.10).
5.2.8 Wie schnell bin ich? Eine Tachometer-App
Eine weitere interessante Anwendung der Geolokalisierung ist die Angabe der Geschwindigkeit, mit der sich ein mobiles Gerät bewegt (siehe Bild 5.11). Wir erstellen also eine Tachometer-App (kap5/Speed1). Mit GPS und der Geolokalisierung geht das ziemlich genau7 und einfach. Von daher kann die nachfolgende App als ziemlich genauer Tacho für ein Fahrrad, Auto, Boot oder auch einen Fußgänger verwendet werden, wenn die Verdunkelung des Smartphones oder Tablets nicht zu kurz eingestellt und GPS aktiviert ist. Und natürlich muss das Smartphone geeignet befestigt sein, denn in der Hand zu halten, ist ja im Auto verboten. Selbst zur Ermittlung der Geschwindigkeit über Grund von Fluggeräten8 ist dieser Tacho geeignet. Wobei die Genauigkeit mit der Geschwindigkeit zunimmt, aber auch von diversen weiteren Randbedingungen abhängt (etwa der Empfindlichkeit des GPSSensors und natürlich auch den verfügbaren Satelliten).Der Weg führt über die Eigenschaft speed des Positionierungsobjekts und den regelmäßigen Aufruf von watchPosition(). Damit erhalten Sie die aktuelle Geschwindigkeit in Metern pro Sekunde. Und diese Angabe kann ganz einfach in die üblichen Km/h umgerechnet werden, indem Sie den Wert mit 3,6 multiplizieren.
7 In der Regel viel genauer als der normale Tacho bei einem Auto, der die Bewegung der Räder als Basis nimmt.8 Etwa einem Gleitschirm, woran ich persönliches Interesse habe.
5.2 Geolokalisierung 117
besprochen haben – frequency. Recht offensichtlich ist das die Frequenz in Millisekunden, in welchen Abständen die Position bestimmt werden soll. Diese Option ist jedoch kein Bestandteil der W3CSpezifikation und eine spezielle PhoneGapErweiterung, die auch in Zukunft vollkommen durch maximumAge ersetzt werden soll (was aber noch nicht bei allen Geräten funktioniert). Von daher ist es durchaus sinnvoll, beide Werte (identisch) zu setzen, um maximal viele Geräte zu unterstützen.
5.2.9 Ein grafischer Tacho mit HTMl5-Canvas-Objekten
Wir wollen unsere TachometerApp optisch noch ein bisschen aufpeppen (kap5/Speed2). Die Geschwindigkeit soll nicht nur als Zahl, sondern auch visuell angezeigt werden. Ein optisches Highlight von HTML5 ist sicher, dass Sie mit Hilfe von sogenannten CanvasObjekten zeichnen können. Und in modernen Smartphones und Tablets können Sie diese Zeichnenbereiche nutzen (bei älteren Systemen werden die HTML5Techniken vermutlich nicht funktionieren). Mit Hilfe von Skripten (im Wesentlichen JavaScript) kann man da zweidimensionale (später dreidimensionale) Bilder als Pixelgrafiken zeichnen.
Das Canvas-ElementAls Erstes müssen Sie ein CanvasObjekt zur Verfügung haben. HTML5 stellt dazu den neuen Tag <canvas> zur Verfügung. Das ist im Grunde ein normales Blockelement, in dem man aber über die Methoden der Objektrepräsentation zeichnen kann. Obwohl man die Breite und Höhe von Blockelementen mittels CSS festlegen soll, gibt man bei CanvasElementen derzeit die Breite und Höhe zudem mit HTMLAttributen an. Dies sorgt aktuell für einen zuverlässigeren Aufbau in Browsern.
lISTING 5.24 Beispiel für ein Canvas-Element in HTML
<canvas width="250" height="150"></canvas>
Der GrafikkontextEin CanvasObjekt stellt sogenannte Grafikkontexte zur Verfügung. Das sind erst einmal einfach die Bereiche, in denen man konkret zeichnen kann, allerdings im Sinn der Objektorientierung mit implementierten Methoden. Im Konzept von HTML5 sind sowohl zweidimensionale als auch dreidimensionale Bereiche vorgesehen, wobei aktuell nur die zweidimensionalen Bereiche richtig unterstützt werden. Der Bereich zum Zeichnen ist nach der Initialisierung erst einmal leer.Der Zugriff auf den Grafikkontext erfolgt über ein CanvasObjekt und dessen Methode getContext(). Als Parameter geben Sie die Art des Grafikkontextes an (zweidimensional oder dreidimensional). Derzeit macht nur "2d" Sinn. Etwa so:
lISTING 5.25 Selektion des Zeichnenbereichs
var zb = document.getElementById('b').getContext('2d');
118 5 Wo bin ich und wo will ich hin?
Das Koordinatensystem und das GitterGrundlage jeder grafischen Ausgabe in einem CanvasBereich ist ein Koordinatensystem, in dem mit zwei Werten ein Tupel spezifiziert werden kann, an dem eine bestimmte Ausgabe erfolgen soll, und ein unsichtbares überlagertes Gitter (Grid), das den Bereich in Einheiten skaliert und das man als Grafikkontext selektiert. In dem Koordinatensystem lässt sich durch die Angabe von zwei Werten, die vom Ursprung des Koordinatensystems ausgehen, ein beliebiger Punkt in dem Koordinatensystem eindeutig festlegen. Dies sind ein xWert und ein yWert, wie man es meist aus dem Mathematikunterricht in der Schule kennt. Die Maßeinheit ergibt sich aus dem Grid, wobei normalerweise eine Einheit im Grid mit einem Pixel im CanvasElement korrespondiert. Die obere linke Ecke des CanvasBereichs wird in der Grundeinstellung mit (0, 0) – also dem Koordinatensystemursprung – abgebildet. Dabei ist der xWert die Anzahl der Bildschirmpixel von links ausgehend, also in der Waagerechten, und y ist die Zahl der Pixel, von oben angefangen, also in der Senkrechten. Das KoordinatenTupel (4, 10) beschreibt z. B. einen Punkt, der 4 Pixel vom linken Rand des CanvasBereichs und 10 Pixel vom oberen Rand des CanvasBereichs entfernt ist.
Die Möglichkeiten zum Zeichnen über Canvas-ObjekteEin Objekt vom Typ Canvas verfügt über den Grafikkontext über verschiedene Arten von Methoden zum Zeichnen von Grafiken. Wir werden für unser Beispiel die nun folgenden verwenden: � Die Methode fillRect(x,y,breite,height) zeichnet ein gefülltes Rechteck. Die ersten beiden Parameter sind jeweils die X und YKoordinate von der linken oberen Ecke des Bereichs (relativ zum Ursprung) und die anderen beiden die Breite und Höhe des Bereichs.
� Die Methode clearRect(x,y,breite,height) dient zum Leeren eines Bereichs und macht ihn zusätzlich transparent. Das benötigen wir, da in CanvasBereichen eine einmal dort gezeichnete Form erhalten bleibt, wenn sie nicht verdeckt wird, auch wenn Sie eine neue Form in dem CanvasBereich erzeugen. Wenn Sie immer einen leeren Bereich zum Zeichnen einer neuen Form benötigen, müssen Sie sich selbst darum kümmern, dass der CanvasBereich beim Zeichnen der neuen Form leer ist.
� Die Methode fillText() gibt den Text aus, der als erster Parameter angegeben wird. Der zweite und dritte Parameter gibt die Koordinaten des linken Eckpunkts der Basislinie des Textes an.
Zusätzlich benötigen wir noch zwei Eigenschaften: � Mit der Eigenschaft font geben Sie die Details zur Schrift (Schriftgrad und Schriftart) an. � Mit fillStyle geben wir die Farbe der nachfolgenden Ausgabeaktion an.
Kommen wir zu den konkreten Quellcodes. Da dieses Beispiel den Abschluss dieses Parts und in gewisser Weise das Highlight bildet, sollen hier als eine Art Zusammenfassung alle beteiligten Quellcodes (nur die WebCodes) mit den relevanten Parts gezeigt werden. Auch die CSSDatei ist dieses Mal aufgeführt, vor allem deshalb, damit Sie das Layout der App nachvollziehen können. Sie sehen diverse Klassen und Ids sowie typische CSSFormatierungen, die nicht weiter besprochen werden.
5.3 Wo geht es lang? Der Kompass 125
BIlD 5.13 Die Angabe der Himmelsrichtung bei einem realen Windows-Phone-Gerät
5.3.5 Ein Kompass unter Verwendung von HTMl5-Canvas-Objekten
Gestalten wir auch unseren Kompass optisch etwas interessanter (kap5/Kompass2). Dazu greifen wir wieder auf CanvasElemente und deren Methoden zurück. Interessant ist hier die Methode drawImage(). Damit können Sie ein Bild zeichnen, etwa eine Kompassrose, die die Himmelsrichtung angibt (Bild 5.14). Diese zeigt in der Originalgrafik Nord wie üblich oben an.Natürlich könnten wir auch mit HTML über den imgTag oder mit reinem JavaScript ein Bild in der HTMLSeite anzeigen, aber wir wollen das Bild geschickt animieren und die Rose immer so drehen, dass sie auch wirklich die Himmelsrichtung anzeigt. Und dazu werden wir die CanvasMethoden translate() zum Verschieben und rotate() zum Rotieren verwenden.
BIlD 5.14 Die Kompassrose zeigt zusätzlich zu den Gradangaben die Richtung an.
5.5 Ein Cockpit als Abschlussbeispiel 137
In der JavaScriptDatei legen wir mehrere globale Variablen an, mit denen wir arbeiten. Bemerkenswert sind die Variablen für die zwei CanvasElemente (zb1 und zb2), denn wir benötigen zwei getrennte CanvasBereiche. Ebenso sollte Ihnen das Array beschleunigungsarray auffallen, mit dem wir das nervöse Verhalten des Beschleunigungssensors ausgleichen wollen. Dazu gibt es Variablen zum Merken eines vorherigen Zustands. Für den Winkel bei der Himmelsrichtung haben wir das ja schon besprochen und hier greifen wir für die Berechnung der Steig und Sinkwerte auf das gleiche Verfahren zurück.
GeolokalisierungWenn das Gerät fertig initialisiert ist, nehmen wir zuerst eine Geolokalisierung vor. Darüber bestimmen wir den Ort und die Geschwindigkeit. Erst einmal machen wir mit getCurrentPosition() eine Momentaufnahme und dann beobachten wir die Veränderung dieser Position mit watchPosition(). Im Erfolgsfall wird in der Funktion successgeo() wie bekannt mit dem BingAPI eine Karte samt Marker angezeigt. Beachten Sie, dass wir dieses Mal die Karten und nicht die Satellitendarstellung verwenden. Und wir legen auch noch einmal explizit mit JavaScript und dem styleObjekt den Anzeigebereich der Karte in der Höhe und Breite fest. Denn ohne diese Maßnahme kann es sein, dass sich die Höhe und/oder Breite ungewollt ändern. Der Rest ist bekannt. Ebenso wird in der Funktion die Geschwindigkeit ermittelt. Aber auch diese Schritte kennen wir. Hier ist nur zu beachten, dass wir dieses Mal jedoch die Maßeinheit mit ausgeben, da wir diese Information aus Platzgründen nicht in einer zusätzlichen Zeile anzeigen wollen.
Steig- und SinkwerteDer Zugriff auf den Beschleunigungssensor erfolgt auch wieder mit zwei Methoden. Mit getCurrentAcceleration() bestimmen wir die aktuelle Beschleunigung in ZRichtung mit einer anonymen CallbackFunktion, also die aktuell wirkende Schwerkraft im Fall eines ruhenden Geräts. Diese beträgt zwar näherungsweise 9,81 m/s2, aber wie wir schon besprochen haben, ändert sich dieser Wert etwa mit der Höhe, in der Sie sich befinden. Zudem ist es sehr unwahrscheinlich, dass das Gerät wirklich ruht, wenn die App initialisiert ist. Wahrscheinlicher wird es in der Hand gehalten oder sonst bewegt, was sich auf den aktuell gemessenen Wert der Beschleunigung auswirken kann. Diese erste Momentaufnahme fixiert den tatsächlichen Wert in einer globalen Variablen beschleunigungalt, die wir in der CallbackFunktion successbeschleu() für den Erfolgsfall bei der folgenden Methode watchAcceleration() brauchen.In der Funktion watchAcceleration() bestimmen wir wieder die Beschleunigung in ZRichtung und speichern den Wert in der lokalen Variablen beschleu. Und nun kommt ein kleiner Trick, um die schon angedeutete nervöse Reaktion des Beschleunigungssensors mit einem mathematischen Algorithmus „glattzubügeln“. Die nachfolgende ifAnweisung sorgt dafür, dass unser globales Array zur Aufnahme von Messwerten des Sensors bei jedem Aufruf der CallbackFunktion gefüllt wird. Erst wenn fünf Messwerte da sind, kann der Programmfluss diese ifAbfrage überspringen. Wenn Sie noch die Optionen bei watchAcceleration() beachten, erkennen Sie, dass wir alle 400 Millisekunden eine Messung durchführen. Das bedeutet, wir haben dann über zwei Sekunden fünf Messwerte erhoben. Und von denen wollen wir den Mittelwert bilden (beschleu = beschleu / beschleunigungsarray.length;), was einen einigermaßen vernünftigen Messwert darstellen sollte. Das Array wird danach
6.1 GitHub 141
Das wird alles von der Wolke bereitgestellt. Dazu müssen Sie sich allerding mit einer Adobe ID oder einem GitHubAccount einloggen (Bild 6.2).
BIlD 6.2 Zur Nutzung brauchen Sie eine Adobe ID oder einen Github-Account.
6.1.1 Die Registrierung
Falls Sie bei GitHub noch nicht registriert sind, können Sie sich für OpenSourceProjekte einen kostenlosen Account einrichten. Die kommerzielle Nutzung ist je nach Leistungsumfang preislich gestaffelt (Bild 6.3). Den Link zur Registrierung finden Sie auch auf der Webseite zum Einloggen (Bild 6.2).Zur Registrierung eines freien Accounts benötigen Sie nur Ihren Namen und eine EMailAdresse (Bild 6.4).
142 6 Erstellung in der Cloud & mehr
BIlD 6.3 Es gibt auch einen freien Account bei Github.
BIlD 6.4 Anlegen eines Accounts
6.1 GitHub 143
6.1.2 Übersetzung der Webquellcodes
Wenn Sie einen GitHubAccount haben, können Sie sich einloggen und Ihre Apps durch den Dienst erstellen lassen. Dazu laden Sie deren Webquellcodes zum Beispiel mit dem entsprechenden UploadDialog auf der Webseite hoch. Am einfachsten packen Sie Ihr gesamtes Verzeichnis www in eine ZipDatei und schicken diese in die Wolke. Nach kurzer Zeit sollten die Apps kompiliert sein (Bild 6.5). Eine Aktualisierung ist jederzeit möglich.
BIlD 6.5 Die Apps sind fertig.
Derzeit können mit GitHub aus einem Quellcode zeitgleich Apps für Android, WebOS, Windows Phone, BlackBerry, Symbian und iOS erstellt werden, wobei Sie für die Entwicklung von iOSApps eine AppleID benötigen (siehe Bild 6.6). Ebenso sollten Sie beachten, dass nicht alle Features von PhoneGap in sämtlichen Zielplattformen verfügbar sind und dann bei deren Verwendung die Erstellung der App für Zielsysteme ohne passende Unterstützung natürlich nicht klappen kann.Für alle Zielsysteme, für die die Erstellung funktioniert hat, bekommen Sie die nativen Installa tionsdateien zum Download angeboten (Bild 6.7).Nun sind die speziellen Konfigurationen und Metadaten einer App normalerweise in einem Projekt an verschiedenen Stellen verteilt und diese sind je nach Entwicklungssystem und Zielplattform zudem noch ganz unterschiedlich. Aber auch für die Konfiguration der Metadaten Ihrer App gibt es eine universelle Lösung – Sie verwenden die Datei config.xml.
144 6 Erstellung in der Cloud & mehr
BIlD 6.6 Für iOS ist kein Schlüssel angegeben und deshalb hat die Erstellung für das Zielsystem nicht funktioniert.
BIlD 6.7 Die nativen Installationsdateien für die Apps stehen zum Download bereit.
6.2 Konfiguration und Metadaten mit config.xml 147
BIlD 6.9 GitHub verwendet die Metainformationen und Konfigurationseinstellungen über config.xml.
Wenn diese Datei im wwwVerzeichnis enthalten war, das Sie zu GitHub hochgeladen haben, finden Sie die Metainformationen dort an verschiedenen Stellen wieder (Bild 6.9).
6.2.2 Preferences
Über das optionale Element preference können Sie diverse Eigenschaften spezifizieren, die ansonsten mit Vorgabewerten zum Tragen kommen. Dazu müssen Sie als zwingende Attribute den Namen der Eigenschaft (name) und den konkreten Wert (value) angeben. Beachten Sie, dass nicht alle Eigenschaften in allen Zielplattformen verfügbar sind bzw. alle erlaubten Werte unterstützt werden.
Die PhoneGap-VersionAngabe der Version von PhoneGap, die Sie in Ihrer App verwenden.
lISTING 6.3 Die PhoneGap-Version
<preference name="phonegap-version" value="2.0.0" />
148 6 Erstellung in der Cloud & mehr
Angaben zur AusrichtungÜber orientation können Sie die mögliche Ausrichtung der App festlegen. In der Grundeinstellung (Wert default) dreht sich die App mit, wenn das mobile Gerät gedreht und dies vom Sensor bemerkt wird. Ebenso verhält es sich, wenn das Element fehlt. Sie können aber auch explizit landscape oder portrait angeben und damit eine Ausrichtung fixieren.
lISTING 6.4 Angabe der Ausrichtung
<preference name="orientation" value="landscape" />
Angabe einer speziellen ZielhardwareÜber target-device können Sie die Werte handset, tablet oder universal setzen, was die entsprechenden geplanten Zielgeräte festlegt.
lISTING 6.5 Zielgerät ist ein Tablet.
<preference name="target-device" value=" tablet" />
VollbildmodusÜber das boolesche Attribut fullscreen können Sie einstellen, ob ein Vollbildmodus (ohne Statuszeile) verwendet werden soll. Der Vorgabewert ist false.
lISTING 6.6 Verwendung des Vollbildmodus
<preference name="fullscreen" value="true" />
6.2.3 Zielplattformspezifische Einstellungen
Für die verschiedenen Zielplattformen gibt es noch diverse weitere Einstellungsmöglichkeiten über die Datei config.xml, etwa zur Anzeige von Steuerelementen, Stilen, Icons oder des Startbildschirms. Dazu sei aber auf die Dokumentation unter https://build.phonegap.com/docs/config-xml verwiesen.
■ 6.3 Weitergehende Themen
Abschließend für das Kapitel möchte ich noch kurz auf einige weiterführende Themen rund um PhoneGap eingehen, die ich im Buch nicht intensiv vertiefen werde, aber der Vollständigkeit halber erwähnen will.
7.2 Der Netzwerkstatus 153
Der Quellcode sollte selbsterklärend sein.
BIlD 7.1 Der Emulator vom Visual Studio äußert sich so.
■ 7.2 Der Netzwerkstatus
Als Erweiterung von navigator stellt PhoneGap das Unterobjekt network zur Verfügung. Dieses wiederum besitzt als Eigenschaft ein Objekt connection und dessen Unterobjekt type repräsentiert die Art der Netzwerkverbindung, die aktuell der App zur Verfügung steht. Der gesamte Ausdruck für die Auswertung des Netzwerkstatus lautet also navigator.network.connection.type. Nun gibt es in PhoneGap noch zusätzlich die ConnectionSchnittstelle mit Konstanten, welche die Werte der Eigenschaft type – je nach Verbindungstyp – als Wert repräsentieren: � Connection.UNKNOWN
� Connection.ETHERNET
� Connection.WIFI
� Connection.CELL_2G
� Connection.CELL_3G
� Connection.CELL_4G
� Connection.NONE
164 8 PhoneGap im Zusammenspiel mit ergänzenden Frameworks
Das gilt aber nicht für alle Kandidaten. Wir wollen die nachfolgend kurz vorgestellten Frameworks in verschiedene Gruppen aufteilen, die sich auf Grund der Ausrichtung ergeben. Dabei erfolgt die Aufteilung durchaus subjektiv aus Sicht des Autors.
8.1.1 PhoneGap-Alternativen
PhoneGap bzw. Cordova ist natürlich nicht allein auf dem umkämpften Markt der WebApps. Betrachten wir zuerst zwei Frameworks, die weniger auf das Zusammenspiel mit PhoneGap ausgelegt sind, sondern durchaus eine Konkurrenz dazu darstellen.
jQTouchEin sehr interessantes Plugin unter der MITLizenz für jQuery bzw. Zepto (siehe unten), das speziell auf Mobilgeräte mit dem WebKitBrowser angepasst ist, nennt sich jQTouch (http://www.jqtouch.com/). Das Projekt ist schon sehr lange online, allerdings nur in einer (ungewöhnlich langen) Betaphase. Das Plugin konkurriert vom Einsatzzweck her ein wenig mit PhoneGap, denn es bietet auch Zugriff per JavaScript auf die Hardware eines mobilen Geräts selbst. Dazu kommen aber auch rein inhaltsorientierte Effekte wie Seitenübergänge oder die Verarbeitung spezieller Eingaben des Anwenders wie MultiTouchGesten über passende Events und spezielle CSSSelektoren. Daher finden Sie in diesem Framework auch eine Unterstützung zum Aufbau einer grafischen Benutzerschnittstelle, was PhoneGap (derzeit) fehlt.
Sencha TouchKeinesfalls unerwähnt bleiben darf Sencha Touch, denn das Framework gehört zu den popu lären Vertretern (http://www.sencha.com/), um Apps auf Basis von HTML5 zu erstellen. Als Zielplattformen werden explizit iPhone, Android und BlackBerry angegeben. Es steht – zumindest auf den Plattformen – ebenfalls in direkter Konkurrenz zu PhoneGap, denn auch hier wird ein Wrapper bereitgestellt, um aus Webtechnologie heraus auf die Hardware von einem mobilen Gerät zuzugreifen. Sencha Touch ist Teil einer übergeordneten Infrastruktur mit visuellem AppDesigner, Animationstools und einem umfangreichen JavaScriptBasisframework, das die MVCArchitektur (Model View Controller) unterstützt. Von daher ist das Framework sehr schwergewichtig.
8.1.2 Ergänzungen von PhoneGap
Betrachten wir nun ein paar Frameworks, die explizit in Verbindung mit PhoneGap2 ihre Leistungsfähigkeit zeigen oder zumindest in Verbindung damit eingesetzt werden können.
Zepto.jsZepto (http://zeptojs.com/) ist eine modulare, stark minimierte JavaScriptBibliothek (derzeit weniger als 10 KByte) unter der MITLizenz, die sich in ihrer Funktionalität explizit auf
2 Sie können aber auch ohne PhoneGap verwendet werden.
8.1 Verschiedene Frameworks für Web-Apps 165
moderne Browser beschränkt und dort die Unterstützung von fortgeschrittenen JavaScript, DOM und CSSKonzepten voraussetzt. Damit kann sie sehr schlank gehalten werden, da sie nicht durch diverse Workarounds für alte oder nichtstandardkonforme Browser aufgebläht ist (der Internet Explorer wird ausdrücklich nicht unterstützt). Zepto nutzt explizit jQuery als Grundlage und ist auch nach Angaben in der Dokumentation des Frameworks ausdrücklich für die Zusammenarbeit mit PhoneGap gedacht. Die Möglichkeiten von jQuery, die fast ausschließlich syntaktischer Natur sind, werden von Zepto um spezielle Elemente erweitert, die die Bedienung von mobilen Geräten unterstützen.
xui.jsEin weiteres Framework unter der MITLizenz, das rein auf die Manipulation des DOM ausgelegt ist und explizit HTML5 nutzt, finden Sie unter http://xuijs.com/. XUI ist sehr klein (um die 10 KByte), was gerade im Umfeld mobiler Apps wichtig ist, und beschränkt sich auf die Unterstützung von WebKit, IE Mobile und BlackBerry.Das Framework gibt es bereits seit 2008 und wurde nach eigenem Bekunden vom Auftauchen von PhoneGap motiviert. Von daher eignet es sich ebenfalls sehr gut für das Zusammenspiel mit PhoneGap. Ziel ist eine solide DOMManipulation, die gezielt die Bedürfnisse des mobilen Webs berücksichtigt (insbesondere in Hinsicht von Initialisierungen). Die Struktur und das Aussehen der Oberfläche werden aber ausdrücklich nativem HTML und CSS übertragen. Oder anders ausgedrückt – hierzu bietet das Framework keine eigenen Features.
Web 2.0 TouchWeb 2.0 Touch (http://web20boom.com/web/touch.php) ist eine spezielle OpenSourceJavaScriptBibliothek für TouchDevices (iPhone, iPad, Android) oder andere Endgeräte, auf denen die WebKitEngine ausgeführt wird. Das Framework arbeitet mit HTML5 und CSS3 samt CSSThemen, dynamisch geladenen Seiten, nativ aussehenden Layouts und hardwarebezogenen Übergängen.
DHTMlX TouchEin sehr umfangreiches, freies und mächtiges JavaScriptFramework für mobile WebApps auf Basis von HTML5 ist DHTMLX Touch (http://dhtmlx.com/touch/). Dieses Framework ist im Vergleich zu den anderen in diesem Abschnitt kurz vorgestellten Frameworks ein Schwergewicht, denn es beinhaltet eine große Menge an UIWidgets und Komponenten (Calendar, Chart, Dataview, GoogleMap, Grid, Accordion, List, Popup, Scrollview, Toolbar, Button, Datepicker, Tabbar etc.) und erlaubt die Erstellung robuster WebApps, die unter iOS, Android und anderen mobilen Plattformen laufen. Das Framework stellt dazu eine eigne Syntax und Objektphilosophie auf Basis von JSON zur Verfügung. Diese Objekte können auch angepasst und sogar erweitert werden. Dazu unterstützt DHTMLX Touch explizit clientseitige Datenspeicherung, wie sie mit HTML5 eingeführt wird, und das Zusammenspiel mit dem Server via AJAX.Bemerkenswert sind die Entwicklungstools, die mit dem Framework verbunden sind. Ein Visual Designer erlaubt als Onlinetool die visuelle Erstellung der Oberfläche einer mobilen WebApp über Drag&Drop (Bild 8.1).Dazu gibt es einen Online Skin Builder, über den Sie das Aussehen Ihrer App anpassen können (Bild 8.2).
166 8 PhoneGap im Zusammenspiel mit ergänzenden Frameworks
BIlD 8.1 Der Visual Designer
BIlD 8.2 Der Skin Builder
8.2 jQuery, jQuery UI und jQuery Mobile 167
BIlD 8.3 For Chrome only – der Touch UI Inspector
Touch UI Inspector ist hingegen eine freie Erweiterung für Google Chrome, um mit einem visuellen Tool den inneren Status spezieller DHTMLXTouchJavaScriptKomponenten auf einer Seite zu überwachen (Bild 8.3).
■ 8.2 jQuery, jQuery UI und jQuery Mobile
Nun dürften manche Leser bei der Aufzählung der ergänzenden Frameworks für PhoneGap jQuery (http://jquery.com) vermisst haben. Dieses Framework habe ich im vorherigen Abschnitt bewusst weggelassen. Aber nicht weil es unwichtig ist oder hier nicht beachtet werden soll, sondern im Gegenteil – die jQueryFamilie werden wir intensiver behandeln, denn derzeit ist jQuery im Web das populärste Framework und die Basis diverser Erweiterungen. Im Rahmen des jQueryProjekts selbst gibt es nun auch eigene ErweiterungsFrameworks speziell für die Erstellung von grafischen Oberflächen, etwa jQuery UI, um Webseiten/Webapplikationen mit Widgets und Komponenten aufzupeppen, oder jQuery Mobile speziell für mobile Webseiten und Webapplikationen. Und dieses Habitat rund um jQuery werden wir als Ergänzungen zu PhoneGap im Buch etwas genauer betrachten und teilweise auch
8.3 Die GUI-Erstellung mit jQuery Mobile 179
Die speziellen Features von jQuery MobileDas jQuery MobileFramework bietet verschiedene Arten an Unterstützung zum Aufbau einer grafischen Oberfläche für Ihre App. Es gibt einmal Widgets (Komponenten), aus denen Sie eine grafische Oberfläche zusammensetzen können. Diese Widgets sind auf eine berührungsgesteuerte Benutzerführung über Touchscreens optimiert. Dazu existieren auch einige spezielle Events, die nur im mobilen Bereich sinnvoll sind. Ebenso gibt es ein spezielles CSSFramework, das das Aussehen der Benutzerschnittstelle an die Bedürfnisse einer mobilen Zielplattform anpasst. Mobile jQuery arbeitet dazu intensiv mit CSS3, was auf alten Geräten bzw. Plattformen etwas kritisch sein kann.
Der DownloadDas jeweils aktuelle Release des Frameworks erhalten Sie über http://jquerymobile.com/download/. Dort stehen Ihnen verschiedene Dateien zur Verfügung. Da gibt es einmal die reinen JavaScriptRessourcen, die sowohl in einer lesbaren Version als auch in einer minimierten Version (mit min gekennzeichnet), die für die Auslieferung gedacht ist, vorliegen. Dabei wurden alle überflüssigen Zeichen (Kommentare, nicht notwendige Leerzeichen, Umbrüche etc.) entfernt. Zum Framework zählen aber auch CSSRessourcen, die es in verschiedenen Versionen gibt. Im Allgemeinen ist es am sinnvollsten, wenn Sie die minimierte Version des Frameworks inklusive der CSSRessourcen laden. Und wie schon bei dem Basisframework gilt, dass Sie besser die Ressourcen lokal bereitstellen, als sie über ein CDN zu laden.
Die EinbindungDa jQuery Mobile explizit auf dem Kernframework jQuery aufsetzt, müssen Sie neben jQuery Mobile auch die KernJavaScriptDatei von jQuery einbinden. Dabei sollten Sie unbedingt eine passende Version von jQuery verwenden. „Passend“ bedeutet, dass sie nicht zu niedrig sein darf. Für jQuery Mobile 1.1.0 sollten Sie etwa mindestens die Version 1.6.4 von jQuery selbst verwenden. Allerdings kann auch eine zu neue Version von jQuery gefährlich werden, denn wenn dort inkompatible Umstrukturierungen vorgenommen wurden, muss man diese möglicherweise auch in jQuery Mobile berücksichtigen. Von daher sollte man immer in der Dokumentation nachsehen, welche Versionen von jQuery als Basis empfohlen werden.Nun werden Sie fast immer in Ihrer PhoneGapApp mit externen Style Sheets arbeiten, die Sie in Ihrem HTMLCode referenzieren. Diese sollten immer vor den Skripten eingebunden werden, was mehrfach schon erwähnt wurde. Nun kommen aber auch weitere CSSDateien ins Spiel – die CSSThemes von jQuery Mobile. Dies erzwingt auch eine Reihenfolge, wie Sie die CSSDateien in eine HTMLSeite einbinden. Zuerst notieren Sie immer die CSSDatei(en) von jQuery und dann erst Ihre eigenen CSSDateien. Der Grund ist, dass die später eingebundenen Regeln bei gleicher Priorität vorher definierte Regeln überschreiben. So können Sie sicher sein, dass Ihre eigenen CSSRegeln in so einem Fall Vorrang haben.Da auch alle JavaScriptDateien im gleichen Namensraum arbeiten, müssen wir hier ebenfalls wieder mit der Reihenfolge aufpassen. Das bedeutet, dass Sie Dinge, die Sie in einer JavaScriptDatei definiert haben, in der anderen unbeschränkt verwenden können, wenn sie bereits geladen wurden. Und da jQuery Mobile mit Deklarationen aus jQuery arbeitet und die zu dem Zeitpunkt vorhanden sein müssen, werden Sie zuerst auf jQuery referenzieren. Sie arbeiten im eigenen JavaScriptCode gegebenenfalls mit Elementen aus jQuery und jQuery Mobile und diese müssen zu dem Zeitpunkt definiert sein. Deshalb müssen Sie auch alle
188 8 PhoneGap im Zusammenspiel mit ergänzenden Frameworks
BIlD 8.8 Verschiedene Formularelemente
Einem Widget wollen wir uns etwas genauer widmen, da wir es in den folgenden Beispielen verwenden wollen – der Schieberegler oder Slider. Bei diesem geben Sie in der Regel einen Vorgabe, Minimal und Maximalwert vor, den der Schieberegler annehmen kann. Dieses Widget wird mit input und einem speziellen Wert von type (range) erzeugt (siehe Bild 8.8).
lISTING 8.26 Ein Beispiel für einen Slider
<input type="range" id="slider" value="50" min="0" max="100" />
Mit weiteren Attributen wie data-highlight oder data-mini können Sie das Aussehen des Slider weiter konfigurieren. Nun ist bemerkenswert, dass wir hiermit einen Schieberegler umsetzen, der eben nicht ein natives HTML5Widget darstellt, sondern vom Framework gerendert wird. Das sorgt für eine breite Unterstützung und eine weitgehende einheitliche Darstellung und Verhaltensweise.
8.3.6 Weiterentwicklung der ersten App mit jQuery Mobile
Wir wollen nun die letzte Version der App zur Anzeige der Geschwindigkeit (kap8/Speed2.1) weiterentwickeln und dabei Widgets von jQuery Mobile verwenden (kap8/Speed2.2). Beachten Sie wieder, dass die verwendeten Techniken HTML5, CSS3 und jQuery Mobile auf verschiedenen (älteren) Plattformen nicht einwandfrei funktionieren und die App als Spielwiese und nicht als Praxislösung zu sehen ist. Derzeit zeigt die App die Geschwindigkeit mit dem Balken in einem festen Tachobereich von 0 bis 270 Km/h an. Das ist wenig sinnvoll, wenn man etwa die Geschwindigkeit eines Radfahrers oder gar eines Fußgängers so darstellen will.
192 8 PhoneGap im Zusammenspiel mit ergänzenden Frameworks
der Geschwindigkeit (speed) durch die Maximalgeschwindigkeit (vmax) und multiplizieren dies mit der Breite des Canvas (zb.fillRect(0, 45, speed / vmax * 250, 55);). Damit passt das Verhältnis wieder für alle gewählten Skalierungen.In der CallbackFunktion des Schiebereglers rufen wir nicht nur das Neuzeichnen des CanvasBereichs auf. Wir füllen auch das Array varray mit sechs Werten, die sich auf Grund der gewünschten Maximalgeschwindigkeiten ergeben. Die Logik ist recht einfach. Der erste Wert ist immer 0 und der letzte ist die gewünschte Maximalgeschwindigkeit. Dazwischen muss es fünf Intervalle gleichen Abstands geben und deshalb dividieren wir die Höchstgeschwindigkeit durch den Wert 5. Zur besseren Anzeige werden die Ergebnisse noch abgerundet (var skal = Math.floor(vmax / 5);).
8.3.7 Das Themen-Framework und die allgemeine Gestaltung von Inhalt
Grundsätzlich versucht man in jQuery Mobile, die Gestaltung von Inhalten möglichst weit dem Browser zu überlassen und möglichst wenig Layoutoverhead zu übertragen oder gar ein einheitliches Design zu erzwingen. In der Vorgabeeinstellung verwendet das Framework die Standardstile und größenangaben von HTML. Im Grunde fügt das Framework auf der Ebene nur ein paar Stile für Tabellen und Fieldsets hinzu, um sie etwas besser handhabbar zu machen. Alles andere wird in schlanke CSSKlassen verlagert.Unter jQuery Mobile gibt es dazu ein reichhaltiges ThemenFramework. Die zentrale Zuordnung von CSSRegeln erfolgt über das data-themeAttribut. Dieses kann jedem Widget zugewiesen werden, um die Darstellung dort anzupassen. In der Dokumentation des Frameworks wird empfohlen, dass das Attribut am besten global pageSegmenten zugewiesen wird. Grundsätzlich trennt das mobile Themensystem Farbe und Text von Strukturstilen wie Dimensionen und Pufferung. Damit können diese Regeln einmal definiert und beliebig gemischt bzw. kombiniert werden. Die Vorgabethemen in jQuery Mobile sind einfach alphabetisch durchnummeriert (a, b, c, d, e). Dabei verwendet a den maximalen Kontrast und e die meisten Farben.Die Themen in jQuery Mobile sind CSSBibliotheken, ohne die die Komponenten und Widgets des Frameworks nicht vernünftig dargestellt werden. Diese Themen können Sie selbst verändern, um ein eigenständiges Layout zu schaffen. Aber das ist von Hand mühselig, weil viele Details explizit festgelegt werden müssen. Um die Erstellung und Anpassung von CSSRegeln zu vereinfachen, gibt es im Framework ein webbasiertes visuelles ThemeRollerTool (http://jquerymobile.com/themeroller/ – siehe Bild 8.10).Wenn Sie sich auf der Webseite des ThemeRoller umsehen, sehen Sie eine Benutzerschnittstelle zum Designen aller Elemente, die vom Framework verwendet werden. Sie können jedes Standardthema anpassen oder auch ein eigenes, neues Thema hinzufügen. Sie sehen unmittelbar bei den Beispielen der verschiedenen Komponenten, wie sich Ihre Änderungen auf das aktuelle Design auswirken werden. Wenn Ihr Design fertig ist, müssen Sie es nur noch laden und in Ihrer App einbinden. Zum Download sehen Sie rechts oben in der Webseite des ThemeRoller eine entsprechende Schaltfläche.
8.3 Die GUI-Erstellung mit jQuery Mobile 193
BIlD 8.10 Der ThemeRoller von jQuery Mobile
8.3.8 Eine Überarbeitung der Fliegertacho-App
Wir wollen in dem abschließenden Beispiel für den Umgang mit jQuery Mobile das explizite Auszeichnen mit Themen demonstrieren sowie mehrere pageSegmente einsetzen. Konkret werden wir unsere Spielwiese für experimentelle Techniken mit der Positionsbestimmung in einer Karte, der Anzeige der Himmelsrichtung, der horizontalen Beschleunigung und der Geschwindigkeit überarbeiten – unsere FliegertachoApp. Neu wird sein, dass die App anpassbar sein soll. Zudem werden wir in einem umfangreicheren Quellcode diverse jQueryErleichterungen verwenden, die wir bisher gesehen haben (kap8/Cockpit1.2).Hier ist zuerst die BasisHTMLSeite, in der Sie zwei pageSegmente sowie das gezielte Theming von einzelnen Passagen sehen. Dazu verwenden wir im HeaderBereich eine Navbar, in der wir allerdings (derzeit) jeweils nur eine Schaltfläche anzeigen (siehe Bild 8.11).Über den Button im Header gelangt ein Anwender zur zweiten Seite, in der man mit Formularelementen auswählen kann, wie die Geschwindigkeitsanzeige skaliert (ein Schieberegler) und ob die Karte mit der Position angezeigt werden soll (ein Kontrollkästchen). Das sind also klassische Optionen. Über eine Navbar im Header des zweiten pageSegments gelangt man zurück zum ersten pageSegment (siehe Bild 8.12).
8.3 Die GUI-Erstellung mit jQuery Mobile 199
b) Die Funktion zeigeKarte() wird zusammen mit der Funktion zeichneAnzeige() zum dynamischen Zeichnen der Geschwindigkeitsanzeige bei jeder Änderung der Optionen aufgerufen. Nach der Fertigstellung des DOMBaums wird an die Schaltfläche zum Rücksprung von dem zweiten pageSegment zum ersten pageSegment ein Klickereignis gebunden ($("#retur").bind("click", function() { …}))9. Beide Funktionen verwerten die gewählten Optionen. Die Funktion zum Zeichnen der Geschwindigkeitsanzeige wird ebenfalls nach der Initialisierung der App bei erfolgreicher Geolokalisierung aufgerufen, während der explizite Aufruf für die Funktion zeigeKarte() nach der Initialisierung der App nicht notwendig ist. Denn der Anzeigebereich der Karte wurde in der Voreinstellung einfach auf sichtbar gesetzt und wird nicht dynamisch generiert, wie es bei der Geschwindigkeitsskala der Fall ist.
c) Die Überwachung der verschiedenen Sensoren erfolgt analog der bisherigen Beispiele. Nur sind alle Callbacks in externe Funktionen verlagert worden, da wir diese teils mehrfach benötigen. Etwa zur Positionsbestimmung als auch der Überwachung der Positionsänderung. Ebenso wird der Code mittlerweile so umfangreich, dass anonyme Funktionen leicht unübersichtlich werden können.
d) In der Funktion successcomp(heading) wird die Ausrichtung des Kopfs vom Smartphone bestimmt und diese mit einer numerischen Angabe sowie einer Kompassrose angezeigt – das Verfahren kennen wir. Nur zeigen sich mit dem alten Code in jQuery einige seltsame Probleme. Die Maskierung der Gradangabe ° über ° macht bei der direkten Verwendung in der Methode html() über die Verknüpfung mit dem StringOperator in einigen Versionen des Frameworks Probleme10. Von daher verknüpfen wir die Entität separat mit dem numerischen Wert des Winkels und speichern das Resultat als String in einer neuen lokalen Variablen (var anzwinkel = Math.floor(heading.trueHeading) + " °";), die wir zur Anzeige des numerischen Werts samt Einheit (als HTMLString) in der Methode html() verwenden ($('#kompass').html(anzwinkel);). Für die Beobachtung der Drehung der Kompassrose benötigen wir jedoch einen reinen numerischen Wert und für den verwenden wir eine weitere lokale Variable (var winkel = Math.floor(heading.trueHeading);). Der Rest ist wie gehabt und auch die anderen Callbacks enthalten – bis auf die neue jQuerySyntax – keine Neuerungen oder Besonderheiten.
8.3.9 Support für spezielle Ereignisse in jQuery Mobile
Berühren wir nun noch kurz die Unterstützung für die spezielle Reaktion auf mobile Ereignisse unter jQuery Mobile. Im Rahmen von mobilen Anwendungen im Allgemeinen gibt es weit mehr Ereignisse, als es bei einer Anwendung für einen Desktop üblich und notwendig
9 Die Bindung erfolgt hier nicht mehr – wie vorher – an die Wertänderung des Schiebereglers. Das würde schon deswegen keinen Sinn machen, weil ja zusätzlich auch das Kontrollkästchen ausgewertet wird.
10 Leider ein übliches Problem in der Webprogrammierung – denn im Grunde machen wir hier ja Webprogrammierung. Oft sollte etwas von der reinen Syntax funktionieren, aber der interpretierende Browser steigt aus unerklärlichen Gründen aus. Dann muss man in der Praxis halt tricksen und einen Workaround bauen. Es gilt einfach „Probieren geht über studieren“.
202 8 PhoneGap im Zusammenspiel mit ergänzenden Frameworks
diese Vorgänge erheblich vereinfacht. Allerdings haben diese Methoden bei Apps nur begrenzt Sinn, denn die meisten dieser Interaktionen beißen sich mit nativen Verhaltensweisen bei Touchscreens. Gerade Verschiebeaktionen sind ja im Grundkonzept von Touchscreens bereits mit Vorgabeverhaltensweisen vorbelegt.
8.4.2 Widgets
Die Widgets von jQuery UI sind auch für Apps ganz interessant, denn in jQuery Mobile fehlen derzeit einige dieser Widgets, die man in manchen Fällen gut gebrauchen kann12. So gibt es etwa ein Accordion (Ziehharmonikakomponente – siehe Bild 8.13), einen Datepicker (Datumseingabe mit visueller Auswahl von Kalenderdaten – siehe Bild 8.14) oder Tabs (Anordnungs komponente mit überlappenden Tabellenreitern – siehe Bild 8.15).
BIlD 8.13 Inhalte in einem Akkordeon anordnen
BIlD 8.14 Eine Datumskomponente
12 Wobei es auch einige Widgets in beiden Konzepten gibt und dann würde ich auf Widgets aus jQuery Mobile zu-rückgreifen.
8.4 jQuery UI 203
BIlD 8.15 Inhalte in Tabellenreitern
Aber wie mehrfach gewarnt – die Verwendung solcher Widgets sollte gut getestet werden und Sie sollten sie auch nicht zu komplex verschachteln.
8.4.3 Das Themen-Framework samt ThemeRoller
Ein weiterer Bestandteil von jQuery UI ist wie bei jQuery Mobile ein umfangreiches ThemenFramework auf Basis von CSS. Dazu gibt es ein ThemeRollerTool zur Auswahl, Anpassung und Übernahme vorgefertigter Designs und eine Galerie mit vorgefertigten Designs für die verfügbaren Komponenten des Frameworks (http://jqueryui.com/themeroller/). Dieses Tool war das Vorbild für den ThemeRoller bei jQuery Mobile.
8.4.4 Wie nutzt man jQuery UI grundsätzlich?
Der grundsätzliche Weg zum Einsatz von jQuery UI erfolgt wie üblich über den Download der Bibliothek. Wie jQuery Mobile ist jQuery UI wie schon erwähnt nicht in der normalen jQueryBibliothek enthalten. Von der Homepage des jQuery UIProjekts selbst können Sie die Bibliothek über den Link Download laden. Wenn Sie den Download durchgeführt haben, erhalten Sie eine komprimierte ZIPDatei, die Sie extrahiert zur Verfügung stellen und dann in Ihre HTMLSeite einbinden.Bezüglich der Versionen sollten Sie beachten, dass die jQuery UIVersionen immer mit einer konkreten Version von jQuery selbst zusammenarbeiten und es zu Inkompatibilitäten kommt, wenn die Versionen nicht zusammenpassen. Beachten Sie unbedingt die Hinweise auf der Webseite zur spezifischen Version von jQuery UI. Allerdings ist in der ZIPDatei auch immer eine passende Version von jQuery selbst integriert.Aus der extrahierten Bibliothek benötigen Sie die Inhalte der Verzeichnisse css und js. Unter development-bundle finden Sie Beispiele. In der HTMLDatei müssen Sie die mitgelieferte CSSDatei referenzieren, denn die meisten Komponenten von jQuery UI funktionieren nur dann korrekt, wenn eine konforme CSSDatei zur Verfügung steht. Und natürlich müssen Sie neben der Referenz auf die normale jQueryBibliothek die zusätzliche JavaScriptDatei von jQuery UI einbinden.
218 9 Multimediafragen
BIlD 9.2 Die Anzeige der aufgenommenen Bildinformationen im Windows-Phone-Emulator
In der JavaScriptDatei reagieren wir im Wesentlichen auf die Betätigung der drei Schaltflächen durch den Anwender. Dazu registrieren wir drei Reaktionsmethoden, die jeweils eine der drei Aufnahmemethoden aufrufen. Dabei spielen wir beim Aufruf zwar ein bisschen mit den spezifischen Optionen, aber im Grunde ist der jeweilige Aufruf an allen drei Stellen identisch. Und wir kommen mit einer gemeinsamen CallbackFunktion für den Erfolgsfall aus. Ebenso gibt es nur einen FehlerCallback. Es sollte Ihnen im folgenden Listing auch auffallen, dass wir in dem Beispiel auf die Behandlung des devicereadyEvents verzichten. Das geht deshalb, weil die App erst einmal nur DOMElemente anzeigt. Die spezifischen nativen Komponenten werden erst dann aufgerufen und übernehmen bis zu deren expliziter Beendigung die Kontrolle (siehe Bild 9.3), wenn der Anwender eine der Schaltflächen auswählt. Und da sollte die App auf jeden Fall bereits fertig initialisiert sein.Nun wurde an verschiedenen Stellen schon ausgeführt, dass die Unterstützung der verschiedenen Aufnahmemethoden von der Plattform und dem konkreten Gerät abhängt. In der Theorie sollte es so sein, dass bei einem erfolgreichen Aufruf einer der Aufnahmemethoden der Callback für den Erfolgsfall aufgerufen wird und im Fehlerfall der FehlerCallback. Leider stürzt aber unter manchen Plattformen im Fehlerfall oft die gesamte App ab, statt den FehlerCallback auszulösen. Es wird dabei in der Regel eine sogenannte Ausnahme geworfen, die man in der Programmierung im Grunde behandeln kann, um die App am Laufen zu halten. Dazu wird eine kritische Anweisung in JavaScript in eine trycatchKonstruktion eingeschlossen, wie Sie es in der Folge sehen. Ist ein Aufruf einer potenziell kritischen Anweisung (wie einer Aufnahmemethode) erfolgreich, wird einfach die Anweisung ausgeführt. Sonst passiert nichts weiter. Im Fall einer Ausnahme wird jedoch die Maßnahme im catchTeil ausgeführt und die App läuft weiter.Soweit die Theorie!
240 10 Kontaktfragen
In der folgenden Schleife iterieren wir über das so angelegte Kontaktobjekt kontakt und zeigen dessen Eigenschaften und Methoden im Ausgabebereich der App an.
BIlD 10.2 Ein Datensatz wurde erzeugt und wird angezeigt.
Bei der Ausgabe dürften Ihnen zwei Dinge auffallen. Bei einigen Eigenschaften wird der Wert null angezeigt. Das sind dann die Eigenschaften, deren Werte selbst wieder Objekte sind. Und Sie sehen auch Eigenschaften wie remove oder save. Das sind eigentlich Methoden. Nur werden Methoden in JavaScript als Callback bzw. Funktionsreferenzen an Eigenschaften von Objekten gebunden und von daher tauchen sie hier auch auf.Nun haben Sie also gesehen, dass wir bisher nur Daten in dem Adressbuch verwenden können, die in der „obersten“ Ebene des Kontaktobjekts verwendet werden. Für emails oder phoneNumbers könnten wir weder sinnvolle Werte eingeben noch würden wir mit dem derzeitigen Listing eine sinnvolle Ausgabe erhalten. Wir müssen also die verschachtelten Strukturen mit den Unterobjekten in der Programmierung explizit berücksichtigen und sollten vielleicht auch etwas intelligenter an die Auswertung des Kontaktobjekts gehen. Das bedeutet, wir sollten keine leeren Felder anzeigen und schon gar nicht den Wert null. Betrachten wir dazu eine Abwandlung des ersten Beispiels.
Eine Weiterentwicklung des BeispielsHier ist die neue Webseite als Basis (kap10/Kontaktverwaltung2):
250 11 Ran an den Speicher
In konventionellen Techniken bilden die Ein und Ausgabe von Daten (also u. a. das konkrete Lesen und Schreiben von Dateien) sowie die Operation auf dem Dateisystem ein recht kompliziertes Thema, denn ein Programmierer muss sehr viel von der Quelle zum Lesen oder dem Ziel zum Schreiben wissen. Insbesondere die objektorientierten Sprachen wie C# oder Java haben jedoch die Ein und Ausgabe von Daten sowie die Navigation auf Dateisystemen grundsätzlich vereinfacht, da passende Objekte viel Hintergrundarbeit abnehmen. Dennoch ist der Umgang mit diesen Techniken etwas anspruchsvoller.
DatenströmeDer Ansatz zum Dateimanagement in diesen höher angesiedelten Sprachen arbeitet in der Regel mit sogenannten Datenströmen, die eine Folge von Bits abbilden, welche an einer gewissen Stelle vorbeikommen. Ein Datenstrom kann von jeder beliebigen Quelle kommen, d. h., der Ursprungsort von Daten spielt überhaupt keine Rolle. Ob Internet, lokaler Server oder lokales System, ist egal. Das gilt auch für das Ziel der Daten. Dies mag im ersten Moment als nicht sonderlich wichtig erscheinen, ist jedoch für den Umgang und das Verständnis der beteiligten Objekttypen von entscheidender Bedeutung.
Grundsätzliches zu StrömenAlle Ströme in objektorientierten Ansätzen repräsentieren wie gesagt eine Folge von Bits und besitzen grundsätzlich einige charakteristische Methoden, um damit umgehen zu können. Es gibt in verschiedenen Programmiersprachen zwar meist Ströme mit ein paar speziellen Methoden, aber dennoch existieren immer ähnliche Methoden, die in Strömen immer zur Verfügung stehen. Zum Einlesen von Daten gibt es irgendwelche read()Methoden, von denen es diverse Variationen und spezialisierte Erweiterungen geben kann. Die einfachste Form liest einfache einzelne Bytes aus dem Eingabestrom und stellt sie zur Verfügung. Wenn der Strom das Dateiende erreicht, wird eine charakteristische Reaktion erfolgen. Etwa erfolgt die Rückgabe von einem Wert wie −1 oder es wird eine Ausnahme ausgeworfen. Wenn Sie mit der Verarbeitung eines Stroms fertig sind, wird man ihn in der Regel mit einer close()Methode wieder explizit schließen.Anders als der Eingabestrom, der eine Datenquelle darstellt, ist der Ausgabestrom ein Empfänger für Daten. Man findet Ausgabeströme meist in Verbindung mit Eingabeströmen. Führt eine Methode eines Eingabestroms eine Operation aus, wird die zugehörige umgekehrte Operation von einer Methode des Ausgabestroms durchgeführt. Die grundlegendste Methode eines Ausgabestroms ist eine write()Methode zum Erzeugen eines Ausgabestroms.Nun gibt es auch Ströme, die nicht nur ein Lesen und Schreiben von Daten, sondern auch ein Navigieren auf dem Datenstrom gestatten, etwa das Positionieren an einer bestimmten Stelle im Datenstrom, um ab da gezielt zu lesen oder zu schreiben.
Grundsätzliches zu DateisystemoperationenZusätzlich zu Datenströmen sind Mechanismen zum Umgang mit Dateien und Verzeichnissen wichtig, also das Finden, Erstellen, Löschen oder Kopieren von Dateien und Verzeichnissen. Es geht hier um die Verwaltung der Dateien und Ordner. Solche Dateioperationen sehen im ersten Moment losgelöst von dem eigentlichen Einlesen und Schreiben von Daten aus.
11.3 Zugriff auf eine SQLite-Datenbank 271
11.3.4 Die Methode openDatabase()
Die entscheidende Methode, um mit einer SQLiteDatenbank zu arbeiten, ist openDatabase(). Damit geben Sie den Datenbanknamen, die Datenbankversion, den Anzeigenamen und die Datenbankgröße vor. Die Methode wird vom PhoneGapAPI direkt als Erweiterung von window bereitgestellt und liefert als Rückgabe ein neues Datenbankobjekt, über das die konkrete Manipulation der Datenbank dann in der Folge abläuft.
lISTING 11.13 Beispiel für die Erzeugung einer SQLite-Datenbank
var meinedb = window.openDatabase("testDB", "1.0", "Test DB", 1000000);
11.3.5 Die Datenbankmethoden
Wenn Sie mit openDatabase() ein Datenbankobjekt erhalten haben, stehen Ihnen zwei Methoden darüber zur Verfügung.
Versionsänderung mit changeVersion()Die Methode changeVersion() bekommt als ersten Parameter die alte Versionsnummer und als zweiten Parameter die neue Versionsnummer übergeben. Damit wird die neue Versionsnummer der Datenbank gesetzt.
lISTING 11.14 Beispiel für das Ändern einer Versionsnummer
meinedb.changeVersion("1.0", "1.1");
Konkrete Transaktionen durchführen mit transcation(), SQlTransaction und executeSql()Wichtiger dürfte die Methode transaction() sein, denn damit wird eine Datenbanktrans-aktion ausgeführt. Diese besitzt drei Parameter:
1. Der erste Parameter ist ein Callback mit SQLAnweisungen, die auf der Datenbank ausgeführt werden sollen. Der Standardparameter dieses Callbacks ist vom Typ SQLTransaction und ein Objekt dieses Typs besitzt die Methode executeSql(). Damit können Sie explizite SQLAnweisungen ausführen – gleich welcher Art. Für mehrere Schritte rufen Sie die Methode im Callback einfach mehrfach mit unterschiedlichen SQLAnweisungen auf.
2. Der zweite Parameter ist der FehlerCallback mit einem Standardparameter vom Typ SQLError. Ein Objekt dieses Typs stellt die Eigenschaften code (eine der vordefinierten Fehlercodes SQLError.UNKNOWN_ERR, SQLError.DATABASE_ERR, SQLError.VERSION_ERR, SQLError.TOO_LARGE_ERR, SQLError.QUOTA_ERR, SQLError.SYNTAX_ERR, SQLError.CONSTRAINT_ERR oder SQLError.TIMEOUT_ERR) sowie message mit einer Fehlerbeschreibung zur Verfügung.
3. Der dritte Parameter ist der ErfolgsCallback ohne Parameter.
276 11 Ran an den Speicher
Wir wollen eine Art Notiz-App bzw. eine Memo-App programmieren (kap11/Datenbank2). Dabei greifen wir auf jQuery und jQuery Mobile zurück, um sowohl den JavaScriptCode als auch die optische Gestaltung zu vereinfachen. Zudem wird die Benutzerschnittstelle so gestaltet, wie man es von nativen Apps her kennt (siehe Bild 11.8).Die App soll dem Anwender maximal einfach und schnell das Erstellen und Löschen von Notizen erlauben, ganz ohne lästiges „Sind Sie sicher?“ in den Weg zu stellen. Gerade beim Löschen wird bewusst in Kauf genommen, dass ein Anwender sicher ist und genau weiß, was er damit tut. Der Fokus der App liegt darauf, dem Erstellen und Verwalten von Notizen möglichst wenige Schritte in den Weg zu stellen.Die Eingabe von Notizen erfolgt einfach wieder mit einem Texteingabefeld. Der Anwender selektiert das Eingabefeld und gibt dort eine Notiz ein. Wenn ein Gerät es unterstützt, kann man auch per Spracheingabe die Notiz erstellen! Unterhalb des Texteingabefelds wird eine Schaltfläche mit einer Grafik mit einem Haken angezeigt. Wenn dieser selektiert wird, wird die Notiz in der Datenbank gespeichert.Das Löschen der Notizen soll auf zwei Arten möglich sein. Das Löschen aller Notizen erfolgt über das Klicken auf den Totenkopf im Kopfbereich der App. Das gezielte Löschen einer Notiz erfolgt durch Klicken auf den Totenkopf direkt unterhalb einer Notiz.Ein weiteres Feature der App ist die Mehrsprachigkeit. Der Anwender kann durch einen Klick auf die deutsche oder englische Fahne auswählen, ob die App eine deutsche oder englische Benutzerschnittstelle bereitstellt (siehe Bild 11.9).
BIlD 11.8 Eine Notiz-App mit einer gestalteten Benutzeroberfläche
290 12 Anhang
12.2.1 Woher kommt JavaScript?
JavaScript ist seit seiner ersten Vorstellung durch Netscape im Jahre 1995 durch mehrere Versionszyklen gegangen. Grundsätzlich muss dabei beachtet werden, dass für nahezu alle neu eingeführten Sprachzyklen von JavaScript kaum ein zeitnah aktueller Browser den offiziellen Standard vollständig unterstützt hat und es immer geraume Zeit dauerte, bis die nächsten Browserversionen einen vollständigen Sprachzyklus verdaut hatten! Das gilt bis heute. Im November 1996 taten sich aber Netscape und die internationale Industrievereinigung Organisation ECMA (European Computer Manufactures Association) mit Sitz in Genf/Schweiz (http://www.ecma-international.org/ – siehe Bild 12.1) zusammen und beschlossen, JavaScript zu standardisieren.Aus dem Projekt entstand ECMAScript, was der Name für das von ECMA standardisierte JavaScript ist. Alle neueren JavaScriptVersionen versuchen mit ECMAScript soweit wie möglich kompatibel zu sein.
BIlD 12.1 Die Webseite von ECMA, die vor kurzem von http://www.ecma.ch nach http://www.ecma-international.org/ umgezogen ist
12.2 Ein Crashkurs zu JavaScript 291
12.2.2 Der gemeinsame Namensraum
Sie können in einer Webseite sowohl mehrere verschiedene externe JavaScriptDateien als auch interne Skripts sowie InlineReferenzen gemeinsam verwenden. Im Buch wird das ständig genutzt. Sie sollten aber beachten, dass es dann in den verschiedenen Dateien und Bereichen keine Funktionen oder Variablen mit gleichen Namen gibt. Im Konfliktfall wird meist die zuletzt definierte Funktion oder Variable (im Sinn der Abarbeitung der Webseite von oben nach unten) verwendet. Aber darauf können Sie sich nicht verlassen und Sie sollten tunlichst eine solche Konfliktsituation vermeiden. Der Grund ist, dass alle JavaScripts in einem gemeinsamen Namensraum operieren. Das hat die sehr nützliche Folge, dass Sie an der einen Stelle Definitionen vornehmen und an anderen Stellen (auch in anderen Dateien, wenn diese in der gleichen Webseite referenziert werden) darauf zugreifen können.
12.2.3 Elementare JavaScript-Grundstrukturen
In den folgenden Abschnitten wollen wir kurz über die elementaren Grundstrukturen von JavaScript sprechen. Dies sind logische Strukturen, die Sie in fast jeder Skript und Programmiersprache so finden. Im Einzelnen umfasst das Variablen, Arrays, Datentypen, Operatoren, Ausdrücke, Anweisungen und Kommentare sowie Unterprogramme in JavaScript. Dazu besprechen wir die verschiedenen Möglichkeiten, aus HTML heraus JavaScriptAnweisungen aufzurufen. Aber das soll keine elementare Einführung sein, sondern wichtige Details werden herausgepickt.JavaScript ist bezüglich seiner Grundstrukturen der Programmiersprache C angelehnt. Sie werden zwar nicht alle Elemente und Grundstrukturen, die es in C gibt, in JavaScript wiederfinden. Aber nahezu alle syntaktischen Elemente und Grundstrukturen, die Sie in JavaScript vorfinden, stammen aus C. Deshalb werden JavaScriptEinsteiger mit einem CBackground oder Kenntnis einer syntaktisch verwandten Sprache wie Java, C#, Perl oder PHP sich in der Syntax gleich zurechtfinden. Das Problem ist aber, dass die syntaktische Ähnlichkeit zwischen den Sprachen insbesondere bei JavaScript den Blick darauf verstellen kann, dass die konzeptionellen Gemeinsamkeiten sehr gering sind und die Funktion von JavaScripts von zig Dingen (das diffizile Verhalten der Browser, verschiedene automatische Verhaltensweisen des Interpreters, die Stelle der Einbindung eines Skripts in eine Webseite, die Art des Aufrufs einer Funktion, der unterschiedliche Aufbau des DOM in verschiedenen Browsern etc.) beeinflusst werden kann, die in vielen anderen Sprachen keine Rolle spielen. Wir wollen uns in dem Abschnitt auf diese Besonderheiten von JavaScript konzentrieren.
Groß- und KleinschreibungJavaScript unterscheidet Groß und Kleinschreibung. Alle Schlüsselwörter in JavaScript werden vollständig klein geschrieben und auch Bezeichner werden bezüglich der Groß und Kleinschreibung unterschieden.
292 12 Anhang
Datentypen, Variablen und literaleJavaScript besitzt natürlich genauso Variablen wie alle anderen Programmiersprachen. Variablen sind benannte Stellen im Hauptspeicher eines Computers, denen zur Laufzeit eines Programms/Skripts temporär Werte zugeordnet werden können. Angesprochen werden diese Variablen über Namen, die sie vorher zugewiesen bekommen haben. Und neben dem Bezeichner dieses Hauptspeicherbereichs ist die Art des Inhalts von Bedeutung. Es ist bei einer Programmierung sogar elementar wichtig zu wissen, von was für einem Typ eine Variable ist. Die Wahl des Typs einer Variablen (auch Datentyp genannt) hängt unter anderem davon ab, was man mit der Variablen machen möchte. Umgekehrt legt die Art des Datentyps fest, was man dann mit der Variablen machen kann. Eine Variable mit Text als Inhalt ist beispielsweise von einem ganz bestimmten Datentyp. Sie werden mir sicher Recht geben, dass die Division von zwei Texten ziemlich sinnlos ist. Es gibt aber auch Datentypen, in denen man Zahlen darstellen kann. Damit würde eine Division schon eher Sinn machen. Warum ein Programmierer also wissen sollte, was für ein Typ von Wert in einer Variablen drin steht, wird damit deutlich. Auf der technischen Seite gibt es ebenfalls diverse Gründe, warum eine Variable einen Datentyp benötigt. Im Wesentlichen muss das System wissen, wie viel Speicher für eine Variable oder eine direkte Information wie eine Zahl eingeplant werden muss. Es ist nun sowohl Segen als auch Fluch von JavaScript, dass Sie als JavaScriptProgrammierer Details zu Datentypen gar nicht so genau wissen müssen, denn JavaScript verfolgt bei der Zuweisung von Werten an Variablen das Konzept der sogenannten losen Typisierung (loose typing).Dies bedeutet, dass von einem JavaScriptProgrammierer zwar die Namen von Variablen festgelegt, dabei jedoch die Datentypen nicht deklariert werden (können!). Dadurch bekommt eine Variable erst dann einen bestimmten Datentyp zugewiesen, wenn ihr der Wert eines bestimmten Typs zugewiesen wurde. Dies erfolgt vollkommen automatisch und ohne explizites Zutun des Programmierers.Ein wesentlicher Vorteil der losen Typisierung ist neben der einfachen Einführung einer Variablen, dass Sie den Datentyp jederzeit ohne Aufwand ändern können. Ein explizites Typumwandeln (Casting, wie es in der Fachsprache heißt) ist nicht notwendig. Wenn Sie beispielsweise einer Variablen den Wert einer Zeichenkette zuweisen, können Sie ihr später eine Zahl zuweisen und verändern damit automatisch ihren Typ. Welcher Wert auch immer in der Variablen enthalten ist, er definiert den Datentyp. Dies ist bei vielen konventionellen Programmiersprachen (wie C und C++ und Java) anders. Dort muss der Programmierer auf jeden Fall den Datentyp festlegen, bevor in einer Variablen ein Wert gespeichert werden kann. In der so festgelegten Variablen kann dann auch nur ein Wert des einmal fixierten Typs gespeichert werden. Jede Wertzuweisung eines anderen Datentyps wird einen Fehler erzeugen. Man nennt so etwas dann statische Typisierung von Variablen.JavaScript ist zwar lose typisiert und hält den Programmierer von der konkreten Angabe und dem Zugriff auf Datentypen fern. Das bedeutet aber nicht, dass nicht intern mit Datentypen gearbeitet wird. JavaScript besitzt vier Haupt und zwei Sonderdatentypen, die aber eben in JavaScript implizit verwaltet werden. JavaScript unterstützt die vier Grundtypen Boolean, Number, Object und String. Dazu gibt es die Sondertypen undefined und null.
12.2 Ein Crashkurs zu JavaScript 293
Datenfelder und ObjekteIn JavaScript sind Objekte grundsätzlich genauso wie Arrays aufgebaut. Ein Array ist im Grunde eine Sammlung von Variablen, die alle über einen gemeinsamen Namen und einen Index angesprochen werden können. Ein Array wird in JavaScript etwas anders erzeugt als eine normale Variable. Sie müssen neben dem Namen, über den das Array zugänglich ist, dem System auch erkennbar machen, dass eine ganze Sammlung an Variablen vorliegt. Es gibt dazu verschiedene Wege in JavaScript. Einmal geht eine Deklaration mit einem Konstruktor (new Array()), denn ein Array ist in JavaScript wie erwähnt als Objekt zu verstehen und umgekehrt werden auch Objekte intern als Arrays verwaltet – als Listen mit einer Auflistung über Schlüssel-Werte-Paare. Dann geht auch die Deklaration mit einem Array-Literal. Dazu verwendet man in JavaScript beim Literal eckige Klammern – das kennzeichnet ein ArrayLiteral. Sie weisen bloß einer Variablen bei der Deklaration in eckigen Klammern eine Reihe von Werten zu. Die eckigen Klammern können auch leer bleiben. Und dann gibt es noch die Array- bzw. Objektnotation – JSON. Dazu notiert man in geschweifte Klammern eine kommagetrennte Liste aus SchlüsselWertePaaren als Literal, das einer Variablen zugewiesen wird. Das erlaubt sprechende Indizes.Der Zugriff auf ArrayElemente geht in JavaScript auf mehrere Arten. Auf ArrayElemente greift man in der Regel über den Bezeichner und den Index in eckigen Klammern zu. Bei einem assoziierten Array verwenden Sie als Index einfach den Datentyp String als Schlüssel. Dementsprechend muss der Index in Hochkommata notiert werden. Sie können aber auch die Punktnotation für einen Zugriff verwenden.
Funktionen und MethodenAllgemein versteht man unter Funktionen eine Reihe von Anweisungen im Quelltext, die zusammengefasst werden und (meist) einen Namen bekommen. Damit müssen Sie diese Folge von Anweisungen nicht jedes Mal in den Quelltext schreiben, wenn Sie diese Anweisungen benötigen. Sie werden nur einmal geschrieben und dann jedes Mal über die Angabe des Namens aufgerufen, wenn diese Folge von Anweisungen benötigt wird. So als Funktionen definierte JavaScriptAnweisungen werden beim Laden der Webseite respektive des Skripts nicht direkt ausgeführt, sondern erst, wenn sie explizit aufgerufen werden.Eine spezielle Form einer Funktion ist eine Methode. Methoden sind in JavaScript normale Funktionen, die einem Objekt zugeordnet sind und nur in Verbindung mit diesem vorkommen. Sie können in JavaScript – wie Eigenschaften eines Objekts – nur über die vorangestellte Angabe des Objekts angesprochen werden (die sogenannte Dot-Notation oder Punktnotation).
Standardfunktionen in JavaScriptJavaScript besitzt eine ganze Reihe von vorgefertigten Funktionen, die Sie direkt verwenden können, indem Sie sie an einer beliebigen Stelle im Quellcode einfach aufrufen (eventuell mit geforderten Parametern). Interessanterweise ist jedoch die Anzahl der in JavaScript automatisch implementierten Funktionen recht gering. Die meiste Funktionalität, die Ihnen von JavaScript direkt oder indirekt bereitgestellt wird, steht über Objekteigenschaften und Objektmethoden und nicht Funktionen zur Verfügung.
12.2 Ein Crashkurs zu JavaScript 295
lokale Variablen in FunktionenKommen wir noch einmal zum Begriff der lokalen Variablen. Wie gerade erwähnt, sind Parameter an Funktionen (und auch Methoden) innerhalb des Funktionskörpers als lokale Variablen verfügbar. Außerhalb des Funktionskörpers sind sie nicht sichtbar. Aber Sie können auch selbst innerhalb des Funktionskörpers weitere lokale Variablen definieren. Das Verfahren zum Deklarieren einer lokalen Variablen ist einfach. Lokale Variablen werden innerhalb von Funktionen beziehungsweise vergleichbaren Konstruktionen explizit mit var deklariert und können dann nur dort benutzt werden. Eventuell außerhalb der Funktion vorhandene Variablen gleichen Namens werden temporär verdeckt. Genau genommen werden diese zeitweilig auf undefined gesetzt, aber diese Spitzfindigkeit spielt keine Rolle.
RekursionJavaScript unterstützt auch sogenannte Selbstaufrufe. Dies nennt man auch Rekursion oder einen rekursiven Aufruf. Dabei ruft sich eine Funktion einfach im Laufe der Abarbeitung selbst wieder auf.
FunktionsreferenzenIm Gegensatz zu einem Funktionsaufruf werden bei einer Funktionsreferenz erst einmal rein formal die Klammern fehlen. Eine solche Funktionsreferenz stellt dann aber auch nur einen Verweis auf die Funktion und keinen Aufruf dar. Funktionsreferenzen werden in der Regel an JavaScriptEventhandler gekoppelt, die bei einem bestimmten Ereignis die referenzierte Funktion aufrufen. Das nutzen wir im Buch sehr intensiv.
Anonyme FunktionenBei der Deklaration einer Funktion kann der Funktionsname in einigen Situationen entfallen. Man redet dann von einer anonymen Funktion (im Gegensatz zu einer benannten Funktion). Eine anonyme Funktionsdeklaration ist dann sinnvoll, wenn sie nur an dieser Stelle verfügbar sein muss. Und dann braucht man auch keinen Funktionsbezeichner. Besonders interessant ist, dass eine solche anonyme Funktion einer Variablen zugewiesen oder an eine Methode weitergereicht werden kann. Und diese Zuweisung zu einer Variablen ist genau im Fall einer Funktionsreferenz gegeben.
12.2.4 JavaScript und Objekte
Kommen wir noch einmal auf Objekte unter JavaScript zurück. JavaScript fehlen zwar wichtige Features einer vollständig objektorientierten Sprache (Polymorphismus, echte Vererbung …), aber der wesentliche (wenn nicht gar ausschließliche) Nutzen von JavaScript besteht darin, dass Sie damit aus dem Browser des Besuchers heraus browser und computerbezogene Objekte im Rahmen einer Webseite abfragen und manipulieren können.Um in JavaScript selbst Objekte zu erzeugen, benötigen Sie im Allgemeinen eine Objektdeklaration bzw. Klasse als Bauplan für das zu erzeugende Objekt und seine Eigenschaften sowie Methoden sowie einen Mechanismus, der mit Hilfe dieses Bauplans ein konkretes Objekt erstellt.
296 12 Anhang
Alle Methoden und Eigenschaften eines spezifischen Objekts sind erst dann verfügbar, wenn Sie zuvor eine Objektinstanz des zugehörigen Objekts erzeugt haben oder – was im Umgang mit JavaScript oft der Fall ist – vom Browser automatisch eine Instanz erzeugt wurde, wenn der Interpreter eine bestimmte Struktur innerhalb der Webseite vorfindet. Man redet in diesem Fall von sogenannten Instanzelementen.
KonstruktorenJavaScript stellt nun eine Reihe interner Klassen bereit, aus denen Sie auf diese Weise Objekte erzeugen können. Um solche Objekte zu erzeugen, greifen Sie auf einen sogenannten Konstruktor (auch Konstruktormethode genannt) zurück, eine Funktion liefert ein Objekt oder Sie erzeugen ein Objekt deklarativ, was wir beispielsweise bei Datenfeldern mit der ArrayNotation schon gesehen haben. Eine ganz typische Aktion, bei der Sie manuell ein Objekt generieren wollen, ist eben besagtes Erzeugen eines Datenfelds bzw. Arrays, was Sie ja schon kennen, oder das Erzeugen eines Datumsobjekts. Auch eine Zeichenkette (ein String) wird als Objekt verstanden.Um aus einer Objektdeklaration (Klasse) explizit mit einem Konstruktor eine neue Objektinstanz anzulegen, stellt man in einer Anweisung das reservierte JavaScriptSchlüsselwort new voran, gefolgt von dem Bezeichner der Objektdeklaration und anschließend einem Klammerpaar (eventuell mit Parametern darin). Dies sieht von der Syntax her schematisch so aus:
lISTING 12.2 Schema für das Erzeugen einer Objektinstanz
new [Objektdeklaration]([optionale Parameter]);
Der Konstruktor hat in JavaScript immer den gleichen Bezeichner wie die Objektdeklaration (d. h. Klasse). Die einzige Aufgabe eines Konstruktors ist die Erzeugung eines Objekts. Dabei werden bei Bedarf Initialisierungen vorgenommen, sonstige notwendige Schritte ausgeführt und vor allen Dingen Speicherplatz für das Objekt reserviert.Sofern ein Objekt seine Arbeit nicht dadurch vollständig erledigt hat, dass es erzeugt wurde und unmittelbar dabei einige Arbeitsschritte durchgeführt hat, weist man einer Variablen eine Referenz auf das Objekt zu. Über den Namen der Variablen können Sie dann bei Bedarf auf das Objekt zugreifen. Die Zuweisung erfolgt in einem Schritt mit der Erzeugung.Um Eigenschaften und Methoden von Objekten nutzen zu können, muss man wie gesagt allgemein zuerst eine Objektinstanz auf dem beschriebenen Weg erzeugen. Danach kann man über die Objektinstanz die verfügbaren Eigenschaften und Methoden verwenden. Dies nennt man dann Instanzelemente.
KlassenelementeEs gibt aber auch das Konzept sogenannter Klassenelemente. Hierbei wird eine Methode oder eine Eigenschaft direkt von einer Klasse zur Verfügung gestellt. Dies bedeutet mit anderen Worten, dass Sie solche Elemente nutzen können, ohne vorher mit einem Konstruktor eine konkrete Instanz erzeugt zu haben. Bei der Botschaft stellen Sie stattdessen die Klasse als Adressat voran. Solche Elemente werden bei JavaScript zur Verfügung gestellt, wenn die konkrete Erzeugung einer Objektinstanz wenig Sinn macht oder zu aufwendig wäre.
12.2 Ein Crashkurs zu JavaScript 297
Im Fall der Klasse Object gibt es etwa die Eigenschaft prototype. Weitere Beispiele stehen über die Klasse Math zur Verfügung. Diese stellt mathematische Konstanten und Methoden für mathematische Vorgänge bereit.Um ein Klassenelement zu verwenden, stellen Sie einfach den Namen der Klasse voran und greifen dann wie bei einem Objekt mit der Punktnotation auf das Element zu.
12.2.5 Das DOM-Konzept
Es wird oft vorkommen, dass Sie in Ihren JavaScripts selbst Objekte erzeugen oder Klassenelemente verwenden. Aber so gut wie immer werden Sie in Ihren JavaScriptCodes Objekte nutzen, die Ihnen automatisch vom Browser zur Verfügung gestellt werden. Und diese Objekte basieren auf einem Objektmodell, das nicht zu JavaScript oder auch (X)HTML zählt, sondern die Strukturen von weitgehend beliebigen baumartig aufgebauten Dokumenten beschreibt. Dieses nennt sich DOM –Document Object Model – und wird beim W3C standardisiert. Diese Objektbibliothek kann mittels diverser Techniken genutzt werden, sowohl aus Programmier und Skriptsprachen als auch aus Anwendungen heraus. Dem Zugriff auf eine Webseite unter diesem Objektgesichtspunkt liegt mit DOM ein globales Konzept zugrunde, das sowohl eine plattform als auch programmiersprachenübergreifende Schnittstelle bezeichnet.Diese Struktur für den Zugang ist eine Art dynamischer Baum im Hauptspeicher des Rechners. Ähnliche Elemente werden dabei bei der Indizierung vom Browser auf gleiche dynamische Datenstapel (sogenannte Stacks) für die Seite abgelegt. Auf diese Weise hat der Browser nach dem Laden der Webseite genaue Kenntnis über alle relevanten Daten sämtlicher eigen ständig für ihn ansprechbarer Elemente (Objekte) in der Webseite. Welche das jedoch sind und was er damit anstellen kann, das hat sich in der Vergangenheit je nach Browser erheblich unterschieden. Diese Unterschiede nehmen zwar ab, aber so ganz sind sie immer noch nicht verschwunden.Aber lassen Sie uns noch eine andere Sicht auf den Baum einer Webseite diskutieren. Gerade wenn Sie bereits XML kennen, wird Ihnen der Begriff der Knoten (nodes) vertraut sein. Diese bezeichnen in Hinsicht auf den Baum die enthaltenen Elemente. Knoten erlauben es auch, Arten von Beziehungen zu anderen Knoten zu definieren. Jeder Baum entspringt einem Wurzelknoten. Auch ein Teilbaum hat für diese Teilstruktur jeweils einen entsprechenden Wurzelknoten, etwa bei einer Tabelle das tableElement oder bei einer Aufzählungsliste das Element ul. Untergeordnete Knoten werden als Kinder (children) bezeichnet. Knoten auf derselben Ebene sind Geschwister (siblings), übergeordnete Elementknoten sind Eltern (parent). Ausgehend vom Wurzelknoten ist der Weg zu jedem anderen Knoten im Baum über diese Verwandtschaftsbeziehungen beschreibbar.Die meisten ansprechbaren Elemente einer Webseite können bei Bedarf auch während der „Lebenszeit“ der Webseite aktualisiert werden, etwa wenn mittels eines Skripts die Position eines Elements in der Webseite oder dessen Inhalt verändert oder über Style Sheets nach dem vollständigen Laden der Webseite das Layout eines Elements dynamisch umgewandelt wird.Viele Objekte im DOMKonzept sind in Form einer Objekthierarchie verfügbar. Wenn ein Objekt einem anderen untergeordnet ist, notiert man das in der Punktnotation, indem man erst den Namen des oberen Objekts und dann den des darunter angesiedelten Objekts notiert.
298 12 Anhang
Wenn man beispielsweise eine Webseite nimmt, ist sie über das Objekt document verfügbar. Da sich die Webseite in einem Browserfenster befindet und dieses im Rahmen des DOMKonzepts als window ansprechbar ist, erfolgt der Zugriff über window.document. Damit ist window Parent von document und document umgekehrt Child von window. Ein Formular in einer Webseite ist über ein document untergeordnetes Objekt (oder genauer einem Datenfeld aus Objekten – ein sogenanntes Objektfeld) mit Namen forms und einem Index verfügbar. Damit ist es ein Kindelement von document. In der Punktnotation schreibt man das dann (für das erste Formular der Webseite) beispielsweise so:
lISTING 12.3 Zugriff auf das erste Formular in einer Webseite
window.document.forms[0]
Formularelemente sind nun wieder über das dem formsObjektfeld untergeordnete Objektfeld elements verfügbar. Also sind alle Elemente in dem Datenfeld Kinder von einem Formular.Das Verfahren setzt sich analog auf Eigenschaften und Methoden der Formularelemente fort. Vollkommen analog der Situation bei selbst erzeugten Objekten stellt jedes Objekt im DOM seine spezifischen Eigenschaften und objektgebundenen Methoden über die Punktnotation bereit.Der Zugriff über Bestandteile einer Webseite auf diese Weise ist ideal, wenn Sie mit einer Schleife auf mehrere Elemente gleichen Typs zugreifen wollen. Das ist ja sowieso ein Vorteil von Datenfeldern. Aber der Zugriff auf ein bestimmtes Element wird nicht mehr funktionieren, wenn Sie die Webseite vor diesem Element signifikant umstrukturieren. Wenn Sie etwa ein Eingabefeld vor dem so angesprochenen Eingabefeld einfügen oder entfernen, wird der Index nicht mehr passen und muss entsprechend angepasst werden. Das Risiko ist groß, dass hier Fehler entstehen.Es gibt in der modernen Ausprägung des DOMKonzepts noch andere Zugriffsmöglichkeiten auf Elemente der Webseite. So existieren neben den gerade behandelten Zugriffen über einen Objektnamen oder ein Objektfeld noch die folgenden Methoden: � getElementById()
� getElementsByTagName()
� getElementsByName()
Die verschiedenen Zugriffsmethoden können problemlos gemischt werden, wenn das sinnvoll ist und alle Zielbrowser den Weg unterstützen.
12.2.6 Zugriff auf Inhalte von Elementen in der Webseite
Der Zugriff auf den Inhalt von Elementen in einer Webseite lässt sich im Wesentlichen in drei Kategorien unterscheiden: � Zugriff auf Textinhalte � Zugriff auf Werte von Formularfeldern � Zugriff auf klassische HTMLAttribute über deren DOMRepräsentation
12.3 Mit einer App Geld verdienen 299
Zugriff auf TextinhalteSie können bei jedem Element in der Webseite, das einen Text als Inhalt hat, diesen Textinhalt per JavaScript ansprechen und austauschen, sofern Sie den zugehörigen Knoten selektiert haben. Dazu gibt es innerHTML.
Zugriff auf FormularinhalteDer Zugriff auf Formularelemente per JavaScript ist eine immens wichtige Anwendung. Der Inhalt von Formulareingabefeldern steht über die Eigenschaft value zur Verfügung. Diese ist in der Regel sowohl zu lesen als auch zu schreiben.
Zugriff auf klassische HTMl-AttributeDie per DOM verfügbaren Elemente verfügen in der Regel über die gleichen Eigenschaften, die als Attribute bei dem zugrunde liegenden HTMLTag vorhanden sind. Indem Sie die Namen der Eigenschaften angeben, können Sie lesend und meist auch schreibend darauf zugreifen.
■ 12.3 Mit einer App Geld verdienen
AppEntwicklung als Selbstzweck und ohne Gewinnstreben ist durchaus nicht ungewöhnlich. Ganz in der Tradition von OpenSource gibt es die unterschiedlichsten Beweggründe, warum man das tut. Aber dennoch werden viele Programmierer hoffen, mit ihrer Leistung und Mühe auch Geld zu verdienen. Im Grunde sind die verschiedenen AppStores der großen Anbieter Google, Apple und Microsoft sowie von Partnern wie Nokia eine gute Verteilungsplattform (wenn nicht die einzig relevante, wie unter Apple oder Microsoft), um Apps auch zu verkaufen.Leider (aus Sicht der Entwickler) hat es sich auch bei Apps immer mehr verbreitet, dass es für die unterschiedlichen Plattformen viele (gute) Apps umsonst oder für ganz kleines Geld gibt. Und das führt zu dem Umstand, dass viele Nutzer nur noch selten bereit sind, für mobile Inhalte oder Apps Geld zu bezahlen. Von daher bleibt für die Erwirtschaftung des Lebensunterhalts durch Apps für Entwickler nur der Glücksfall von riesigen DownloadZahlen, um bei den lächerlich geringen üblichen Preisen von wenigen Euro für eine kommerzielle App eine Kostendeckung oder gar einen Gewinn zu erzielen. Im Fall einer kostenlosen App ist sowieso klar, dass weder der Aufwand gedeckt wird noch irgendwelcher Gewinn erzielt werden kann. Für Entwickler von Apps bleibt im Grunde oft nur die mobile Werbung (Advertising) als (kleine) Einnahmemöglichkeit. Dabei stellen sich ein paar grundsätzliche Fragen.
300 12 Anhang
12.3.1 Gibt es (seriöse) Anbieter für mobile Werbekampagnen und wenn ja, welche?
Grundsätzlich gibt es einige Unternehmen, die auch Kampagnen für mobile Seiten und Apps anbieten und Entwicklern dafür ein Honorar zahlen (Advertising). Dabei sind die üblichen Verdächtigen natürlich dabei. Ich möchte explizit keine Empfehlung für einen bestimmten Anbieter geben, aber ein paar Möglichkeiten nennen. Google stellt etwa mit dem AdmobDienst (http://www.google.de/ads/admob/ – Bild 12.2) ein mobiles Angebot bereit, das in die gesamte Werbeinfrastruktur von Google voll integriert ist.
BIlD 12.2 Google ist als einer der größten Advertising-Anbieter auch im mobilen Markt präsent.
Direkt bei den Tools von PhoneGap (http://phonegap.com/tool) finden Sie einen Hinweis auf das SellAring Mobile Ad Network, worüber Sie ebenfalls Werbung in Android bzw. PhoneGapApps integrieren können (https://portal.sellaring.com/developer/signup.php – Bild 12.3). Eine weitere Alternative ist madvertise (http://www.madvertise.de/ – Bild 12.4). Es steht auch zu erwarten, dass das Angebot an AdvertisingPartnern immer mehr zunehmen wird und dass sich die Qualität bei der Einbindung von Werbebannern in eigene Apps verbessern wird.Die Vergütungsmodelle der meisten Anbieter sind recht ähnlich, können sich aber immer wieder ändern, weshalb konkrete Ausführungen dazu in einem Buch keinen Sinn machen. In den FAQ oder den Dokumentationen der Anbieter finden Sie meist Hinweise auf die Abrechnungsmodelle und wir besprechen gleich ein paar grundsätzliche Wege bzw. Kennzahlen, auf die Sie achten sollten.
12.3 Mit einer App Geld verdienen 301
BIlD 12.3 Auf dieses Angebot wird sogar in den Tools von PhoneGap verwiesen.
BIlD 12.4 Auch mit madvertise können Sie in einer App Werbung schalten.
304 12 Anhang
12.3.5 Wie bekomme ich Werbung in eine PhoneGap-App?
Die meisten AdvertisingPartner gehen (noch) davon aus, dass die Werbung in einer nativen App geschaltet wird. Von daher haben wir bei PhoneGap ein Problem. Denn in der Regel müssen Sie im nativen Code Anweisungen des API vom AdvertisingPartner für eine native Plattform integrieren, über die in einem Bereich des nativen Benutzerinterface der App dann Werbung angezeigt wird.Nun haben wir bei PhoneGap aber das Problem (oder im Allgemeinen den Vorteil – nur hier ist das ein Problem), dass wir kein natives Benutzerinterface, sondern eine Webseite anzeigen. Oder anders ausgedrückt – es gibt keinen Platz in der Oberfläche der App für die nativen Werbeplatzhalter! Dazu kann eine native Funktion nicht so einfach den Inhalt des Webbereichs scannen und damit keine sinnvolle angepasste Werbung generieren. Und das führt dazu, dass die Anwender noch weniger als ohne die Banner auswählen würden.Das Problem kann man auf zwei Weisen lösen:1. Sie integrieren Werbebanner für mobile Webseiten in Ihre App. Das bedeutet, dass Sie
in den HTMLCode (die Datei index.html) Referenzen auf den AdsenseServer und/oder spezifische JavaScripts einbauen, wie Sie es bei einer (mobilen) Webseite auch machen. Das ist meist einfach, hat aber einige Nachteile. Vor allen Dingen sind solche Werbebanner nicht an die Gestaltung in Apps angepasst und werden daher nur sehr wenige Klicks produzieren. Aber auch die Anpassung der geschalteten Werbung an die Inhalte der App ist suboptimal, da die Algorithmen von Webbannern eben auf Webseiten ausgerichtet sind.
2. Bei einigen AdvertisingPartnern gibt es spezielle Lösungen für PhoneGapApps, die den Anzeigebereich der App aufteilen. Der Datei index.html wird dabei ein gewisser Bereich „geklaut“ – meist im Fußbereich – und dort wird dann nativ Werbung angezeigt. Die Anzahl der Anbieter dieses Wegs sollte bald zunehmen.
Ein praktisches Beispiel für Advertising mit AdMobDen zweiten Weg wollen wir anhand von Googles AdMob und Android mit der EclipseIDE einmal durchspielen, denn hier ist das Feature schon vorhanden.Angenommen, wir haben eine PhoneGapApp, über die ein Anwender KFZKennzeichnen nachschlagen kann. Ein Anwender gibt in einem Eingabefeld die ersten Zeichen des KFZKennzeichens ein (maximal drei Zeichen sind notwendig). Mit jedem Zeichen wird die Auswahl genauer und die Trefferliste wird unterhalb des Eingabefelds angezeigt (siehe Bild 12.5).Nun bietet sich der Kopf oder Fußbereich der App an, dass wir hier Werbung schalten. Und das machen wir jetzt mit AdMob. Die Monetarisierung erfolgt grundsätzlich für alle PhoneGapApps unter Android gleich: � Einloggen in Ihren AdMobAccount � Eine Seite für eine AndroidApp erstellen � Eine spezifische Publisher ID erhalten
Zuerst benötigen Sie also einen AdMobAccount, um eine Publisher ID zu bekommen (https://de.admob.com/). Dabei können Sie sich auch mit einem normalen GoogleKonto anmelden. Sie kommen dann in den Administrationsbereich von AdMob (siehe Bild 12.6).
12.3 Mit einer App Geld verdienen 305
BIlD 12.5 Eine App ohne Werbung
BIlD 12.6 Der Administrationsbereich von AdMob
12.3 Mit einer App Geld verdienen 307
BIlD 12.8 Die .jar-Datei des AdMob-SDK muss in ein PhoneGap-Projekt integriert werden.
BIlD 12.9 Order and Export
308 12 Anhang
BIlD 12.10 Die Zielplattform des Projekts
12.3 Mit einer App Geld verdienen 311
Wenn Sie die Angabe bestätigen, kommt derzeit eine seltsame Fehlermeldung, dass Sie das AdMob Android SDK laden sollen. Das ist Unsinn, der ignoriert werden kann und irgendwann beseitigt sein sollte1. Das können Sie ignorieren. Gehen Sie nun zu der Liste Ihrer Apps, wenn sie nicht sowieso schon angezeigt wird. In den Einstellungen zu Ihrer App sehen Sie dann die Publisher ID im oberen Bereich der Webseite. Es sollt ein alphanumerischer Code aus 15 Zeichen sein. Geben Sie den noch im JavaCode ein und testen Sie die App im Emulator. Das sollte bereits Werbung anzeigen (siehe Bild 12.12). Sie können nun Ihre App wie üblich in Google Play veröffentlichen und der Anwender sollte in Zukunft angepasste Werbung sehen. Klickt er darauf, verdienen Sie Geld.
BIlD 12.12 Unten sehen Sie nun Werbung in der App.
1 Die oben angedeuteten Probleme sind wohl Kinderkrankheiten im mobilen Advertising-Markt, die verschwinden werden.
314 Stichwortverzeichnis
CAPTURE_INVALID_ARGUMENT 216CAPTURE_NO_MEDIA_FILES 216CAPTURE_NOT_SUPPORTED 216capture.supportedAudioModes 215capture.supportedImageModes 215capture.supportedVideoModes 215captureVideo() 214CaptureVideoOptions 212Casting 292categories 235changeVersion() 271chunkedMode 268cleanup() 205clear() 283clearRect() 118clearWatch() 99, 121, 129ClickThroughRate siehe CTRclone() 243Cloud 139CoarseLocation 98codecs 217compass 121ConfigurationData 212config.xml 132, 143, 145confirm() 158Connection 153Connection.CELL_2G 153Connection.CELL_3G 153Connection.CELL_4G 153Connection.ETHERNET 153Connection.NONE 153Connection.UNKNOWN 153Connection.WIFI 153Contact 235Contacts 233ContactAddress 237ContactError 243, 244ContactField 236ContactFindOptions 246ContactName 237ContactOrganization 237contacts.find() 245Content Distribution Network 169controlgroup 186cookieEnabled 90Cookies 282coords 101copyTo() 254cordova 151Cordova 5Cordova.plist 71, 72CordovaSourceDictionary.xml 87correctOrientation 207
CostPerClick 302country 237CPM 302CPR 302create 258create() 235Create a new Xcode project 49createReader() 254createWriter() 254, 262css() 172CTR 302
Ddatainline 186datarel 184datarole 181, 185, 186, 187
– jQuery 181datatheme 192Date 106Dateiattribute 251Dateisystem 249, 251Dateisystemoperationen 250Datenbank 269Datenbanktransaktion 271Datenbindung 174Datenfelder 293Datenströme 250Datentypen 292Datepicker 202Datumsobjekt 106DELETE 281department 237destinationType 207Device 151deviceready 85, 92DHTMLX Touch 165Dialogbox 158DirectoryEntry 254DirectoryReader 254, 258displayName 235Document Object Model 81DOM 81, 297DONE 256DotNotation 293download() 267draggable() 201DROP 281droppable() 201duration 215, 217
Eeach() 173Eclipse 11
Stichwortverzeichnis 315
ECMA 290ECMAScript 290emails 235EMPTY 256enableHighAccuracy 109encodingType 207Engine siehe SchachEngineerror 256, 257EthernetID 96Eventhandler 294Event Helper 174exclusive 258executeSql() 271, 274eXtensible Markup Language 59Extension Points 30
FFallstudien 149, 288familyName 237FFI 5fieldcontain 187file() 254, 262File 253FileError 259fileKey 268fileName 257, 268FilePath 87FileReader 256, 262filesystem 253FileSystem 258FileTransfer 267FileTransferError 269FileUploadOptions 267, 268FileUploadResult 268FileWriter 254fillRect() 118fillStyle 118fillText() 118filter 246find() 245Flags 254, 258font 118Foreign Function Interface 5Formularelemente 185frequency 116, 122fullPath 216, 253, 263function 294Funktionen 293
– anonyme 101, 295Funktionsreferenz 294Funktionsreferenzen 295Funktionsunterschrift 294Funkzellen 95
GGeld verdienen 299Geodating 95Geolocation API Specification 94GeoLocation Services 96Geolocation, Tracking 263Geolokalisierung 94, 95Geschwindigkeit 95, 115get() 173, 184getContext() 117getCurrentAcceleration() 129getCurrentHeading() 121getCurrentPosition() 99, 103, 226getDirectory() 254, 258getDuration() 226getElementById() 298getElementsByName() 298getElementsByTagName() 298getFile() 254, 258, 261, 263getFormatData() 216getItem() 283getMetadata() 255, 259getParent() 255getPicture() 205Git 139GitHub 139givenName 237Global Positioning System siehe GPSGMap2 111Google Earth, KML 264Google Gears 96Google Maps 110
– KML 264google.maps.Map 111google.maps.Marker 113GPS 95Grafikkontext 117Greenwich 101
Hheaders 268headingAccuracy 123height 217Himmelsrichtung 121honorificPrefix 237honorificSuffix 237html() 173HTML5 117
Iid 235IDE 9ims 236
316 Stichwortverzeichnis
Info.plist 71innerHTML 173, 299INSERT 281insertId 274Instanzelemente 296Interpretation 29iOSSimulators 13iPhoneDevCamp 4IPNummer 96isDirectory 253isFile 253, 263item() 274iWebkit 5
Jjar 57jarsigner 45Java 2, 9Java Archive 57Java Build Path 306Java Development Kit siehe JDKJava Native Interface siehe JNIJavaScript
– Kurzeinführung 289 – Namensraum 291
JavaWrapper 9JDK 10JNI 149jQTouch 5, 164jQuery 167jQuery() 170jQuery Mobile 5, 178jQuery UI 201JRE 29JSON 293JVM 29
Kkey() 283Keyhole Markup Language siehe KMLKeystore 45Klassenelemente 296KML 263Kommandozeilentools 149Kompass 121Kompilierung 29Konstruktor 296Kopieren 254
Llandscape 148, 200Landscape 131language 90
lastModifiedDate 216, 253latitude 101Launcher Icon 37length 257limit 215Literale 292LLVM Compiler 13LOADING 256loadUrl() 59Local Data Storage 282LocalFileSystem 258LocalFileSystem.PERSISTENT 258, 261LocalFileSystem.TEMPORARY 258locality 237localStorage 282longitude 101Löschen 255
MMACAdresse 96madvertise 300magneticHeading 123Marker, Google Maps 113Marketplace, Microsoft 17Marktplatz, Google 15Math.floor() 116maximumAge 109MediaAccessControl 96MediaError 225MediaError.MEDIA_ERR_ABORTED 225MediaError.MEDIA_ERR_DECODE 225MediaError.MEDIA_ERR_NETWORK 225MediaError.MEDIA_ERR_NONE_SUPPORTED
225MediaFile 212, 216MediaFileData 212, 216Media.MEDIA_NONE 225Media.MEDIA_PAUSED 225Media.MEDIA_RUNNING 225Media.MEDIA_STARTING 225Media.MEDIA_STOPPED 225mediaType 207Mehrsprachigkeit 276MemoApp 276Metadata 259Metadaten 251, 255Methoden 293Metro 27Microsoft, Registrieren 17middleName 237Midlets 27MIDlets XIIMIMETypen 212
Stichwortverzeichnis 317
mode 215modificationTime 259Monetarisieren 302moveTo() 255multiple 246Multipurpose Internet Mail Extensions 212MySQL 15
Nname 216, 236Namensraum, JavaScript 291Navbars 185navigator 94navigator.camera 205navigator.compass 121navigator.contacts.find() 245navigator.geolocation 94Netscape 290network 153Netzwerkstatus 153Netzwerkverbindung 151new 296Newsletter 149, 288nickname 236Nitobi 4note 236notification 156NotizApp 276null 292Nullmeridian 101Number 292
OObject 292Objective C 2Objektnotation 293onabort 256, 257onerror 256, 257onload 85, 256onloadend 256, 262onloadstart 256onprogress 256, 257onwrite 257onwriteend 257, 262onwritestart 257openDatabase() 271organizations 236orientationchange 200Orientierung 200Overlays, Google Maps 113
PPackage 37
pagebeforecreate 200pagebeforehide 200pagebeforeshow 200pagecreate 200pagehide 200pageshow 200params 268pause() 226PhoneGap.plist 71PhoneGapWrapper 5phoneNumbers 236photos 236Physikalische Adresse.Lokalisierung via MAC
Adresse 96ping 98Placement, KML 264platform 90, 151Plattformen 6play() 226Plugin Development Guide 149PluginEntwicklung 149Plugins, Eclipse 30Point, KML 264portrait 148, 200position 257Position 95postalCode 237preference 147Prinzip der Fehlertoleranz 79Projekteinstellungen 150, 287ProjektTemplates, Windows Phone 65Punktnotation 293
Qquality 208Quellangaben 287Quellcodes 3
RRadian 126readAsDataURL() 256readAsText() 256, 262readEntries() 258readyState 256, 257Refactoring 176Referenzsysteme 2region 237Rekursion 295release() 226remove() 243, 255removeClass() 281removeItem() 283removeRecursively() 255
318 Stichwortverzeichnis
requestFileSystem() 258, 261, 263resizable() 201resolveLocalFileSystemURI() 258response 268responseCode 268result 256return 294RFID 97RIA 26Rollensystem, jQuery 181root 258Root 16rooten 16
– Android 15rotate() 125rows 274rowsAffected 274Rückgabewert, Funktion 294Rückmeldung 151, 156Runden, floor() 116
Ssave() 242, 243saveToPhotoAlbum 208Schaltflächen 185Schieberegler 188, 189Schlüsselspeicher 45screen 112scrollstart 200scrollstop 200seek() 258seekTo() 226Selbstaufrufe 295SELECT 281selectable() 201SelfServicePlattform 303SellAring Mobile Ad Network 300Sencha Touch 5, 164Session Data Storage 282sessionStorage 282setItem() 283setMetadata() 255size 216, 253Skyhook 96Slider 188sortable() 201sourceType 208Spracheingabe 276SQLError 271SQLite 15, 269SQLResultSet 274SQLResultSetRowList 274SQLTransaction 271
startRecord() 226Steuerelemente, Google Maps 113stop() 226stopRecord() 226streetAddress 237StreetView 97String 292Suchen 245super.loadUrl() 59Superuser 16Support 149, 288supportedAudioModes 212, 215supportedImageModes 212, 215supportedVideoModes 212, 215swipe 200swipeleft 200swiperight 200
TTachometerApp 115tap 200taphold 200targetdevice 148targetHeight 208targetWidth 208Textknoten 173ThemenFramework 192ThemeRoller 203timeout 109timestamp 123TimeStamp, KML 264TKP 302Toolbars 185toURL() 255traceroute 98Trackingsystem, Geolocation 263transaction() 271translate() 125trueHeading 123truncate() 258Typ 292type 216, 253Typisierung, lose 292
Uuidisabled 281undefined 292Universally Unique Identifier 151UpdateManager, Eclipse 31Upgrade 150, 287upload() 267urls 236userAgent 90
Stichwortverzeichnis 319
usespermission 61, 73uuid 151UUID 151
Vval() 173var 295Variablen 292
– lokale 295Vermarktung 139, 287
– AndroidApps 15 – Apple 22 – Windows Phone 17
Veröffentlichung, AndroidApps 15Verschieben 255vibrate() 161Visual Studio Express 12Vollbildmodus 148Vollkreis 101
WwatchAcceleration() 129watchHeading() 121watchPosition() 99Web 2.0 Touch 165Webkit 2WebView 2Werbung 299Whitelist, iOS 71
Widgets 168width 217WiFi Access Point Database 96WiFiAdresse 96Wiki 149, 289window.requestFileSystem() 261Windows Phone 8 65Windows Phone Dev Center 17Windows Phone Developer Registration 18Windows Phone Developer Tools 12Windows PhoneGerät freischalten 17WLANRouter 96WMAppManifest.xml 74write() 258, 262Wurzelverzeichnis 258
XXAMPP 15Xcode Developer Tools 13XML 59XUI 165
ZZeitstempel 105Zepto 164Zertifikat 45Zielgerät 148Zielplattformen 6