Make keytools available to the Android SDK on OS X

If you want to create an App for Android, and if you work on OS X / Macbook, and if you want to create a key for the first time, and if you wonder how to add the keytool path to your PATH environement, then this posting might be interesting for you. It’s about the basic configuration on OS X / Macbook for signing your Andoid Apps. It’s refers to  Google’s document “Signing your applications“. The samples, paths etc. are taken from my macbook.

Google says:

“Before you begin, you should make sure that Keytool is available to the SDK build tools. In most cases, you can tell the SDK build tools how to find Keytool by setting your JAVA_HOME environment variable to references a suitable JDK. Alternatively, you can add the JDK version of Keytool to your PATH variable.”

So what if you don’t know how to set your JAVA_HOME variable or how to add something to the PATH variable? Here are some (hopefully) helpful hints around this topic. The following happens in a termin window.

Not needed, but sometimes useful: Find out which Java-Version is installed:

java -version

Something like this should be the result:

java version "1.6.0_22"
Java(TM) SE Runtime Environment
 (build 1.6.0_22-b04-307-10M3261)
Java HotSpot(TM) 64-Bit Server VM
(build 17.1-b03-307, mixed mode)

Where on the harddisk is Java installed? It might be here:

System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/

This path points to a symbolic link ’1.6.0′. And this link refers to

System/Library/Java/JavaVirtualMachines/1.6.0.jdk

Where lives keytool?

/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/
Contents/Home/bin/keytool

Show the content of your PATH variable:

echo $PATH

Add keytool to the PATH variable. There are a couple of ways to do it. I did it this way:

  • Open the file .profile, which lives in /Users/your_account_name with a text editor
  • You’ll find something like
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin…
  • Add the keytool path to this line:
    :/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/keytool
  • Save the file
  • Open a new terminal window
  • echo $PATH should now contain the path to keytool
  • Enter ‘keytool’ in the terminal window
  • You should get a description of the keytool syntax as a result

Happy coding,
Rolf Dohrmann
Mobile Web Developer

 

Posted in Android, OS X | Leave a comment

Android-Apps signieren

Dies ist eine stark gekürzte Zusammenfassung der englischsprachigen Anleitung zum Signieren von Apps: http://developer.android.com/guide/publishing/app-signing.html.

Teile des Postings beziehen sich speziell auf die Entwicklung mit Eclipse und auf OS X.

Überblick

Alle Apps, die auf einem Android-Gerät installiert werden sollen, müssen signiert sein. Dazu wird ein Zertifikat mit einem privaten Schlüssel (private key) benötigt. Dieses Zertifikat kann mit den Standard-Tools Keytool und Jarsigner selbst erstellt werden. Es dient dazu, den Urheber der App identifizieren zu können. Keytool und Jarsigner sind im JDK (Java Development Kit) enthalten.

Es gibt zwei Arten der Signierung: debug mode und release mode.

Während man die App entwickelt, kann man im debug mode kompilieren. Keytool sorgt dafür, dass die App bei jedem Kompilieren mit dem debug key signiert wird.

Wenn die App fertig ist und veröffentlicht werden soll, muss man im release mode kompilieren und einen private key zum signieren benutzen.

Wenn man mit Eclipse entwickelt und und das ADT (Android Development Tools) Plugin für Eclipse benutzt, kann man mit dem ADT Export Wizard in einem einzigen Schritt die App kompilieren, einen private key generieren und die App damit signieren.

Strategien zum Signieren

Google empfiehlt, für alle Apps dasselbe Zertifikat zu benutzen. Dabei spielt es keine Rolle, ob es sich um gänzlich unterschiedliche Apps oder um Updates bereits existierender Apps handelt. Die Gründe:

  • Updates
    Bei der Installation eines Updates einer App werden die Zertifikate verglichen. Wenn die Zertifikate übereinstmmen, erlaubt das System die Installation. Wenn die Zertifikate nicht übereinstimmen, muss man das Update mit einem neuen package name versehen. Damit handelt es sich für Android um ein anderes Programm und wird entsprechend nicht als Update installiert. Ich gehe davon aus, dass dies dazu führt, dass eventuell gespeicherten Userdaten der ‘alten’ App unter der ‘neuen’ App nicht mehr zur Verfügung stehen.
  • Modularität / Code and data sharing
    Nähere Infos siehe Original-Anleitung.

Bei der Erstellung eines Zertifikats wird die Gültigkeitsdauer definiert. Es ist darauf zu achten, dass diese groß genug gewählt wird, denn nach Ablauf der Gültigkeitsdauer wird ein Update der App nicht mehr ohne weiters möglich sein. Die Empfehlung liegt bei 25 Jahren.

Wenn die App im Android Market veröffentlicht werden soll, darf die Gültigkeitsdauer nicht vor dem 22. Oktober 2033 enden.

Basis-Setup

Die SDK build tools greifen beim Signieren der App auf keytools und jarsigner zu. Es ist dafür zu sorgen, dass das SDK die Pfade zu den Tools kennt. Darum sollten die Pfade entweder in JAVA_HOME oder die Pfadvariable PATH eingetragen werden.

Signieren im Debug Mode

Um den Entwickelung-Prozess und das Debuggen von Android Apps zu vereinfachen, gibt es den debug mode. Wenn man im debug mode arbeitet, signieren die SDK build tools die App bei jeder Kompilierung automatisch mit einem debug keystore und debug key.

Wenn man mit Eclipse entwickelt und die ADT Plugin benutzt, ist das Signieren im debug mode per Voreinstellung aktiviert. Alles läuft automatisch.

Das Debug-Zertifikat hat eine Gültigkeit von 365 Tagen.

Signieren im Release Mode

Das Signieren im release mode erfordert 4 Schritte:

  • Bereitstellen eines passenden private keys
  • Die App im realease mode kompilieren
  • Signieren der App mit dem private key

 Bereitstellen eines passenden private keys

Entweder man hat bereits einen private key oder man erzeugt ihn mit keytools. Hier ist ein Beispiel, wie man mit keytool einen private key erstellt:

keytool -genkey -v -keystore my-release-key.keystore
-alias alias_name -keyalg RSA -keysize 2048 -validity 10000

Die einzelnen Parameter:

  • -genkey
    Erzeugt einen key.
  • -v
    Umfangreichere Rückmeldungen von keytool aktivieren.
  • -keystore
    Der Name des keytores, der den private key beinhaltet.
  • -alias
    Ein Alias für den key. Nur die ersten 8 Zeichen werden berücksichtigt.
  • -keyalg
    Der Verschlüsselungsalgorithmus, der beim Erstellen des keys benutzt werden soll.
  • -keysize
    2048 bits oder mehr werden empfohlen.
  • -validity
    Die Gültigkeitsdauer des keys in Tagen. 10000 oder mehr werden empfohlen.

Über diesen Link findet man eine ausfühliche Beschreibung von keytools: http://download.oracle.com/javase/1.5.0/docs/tooldocs/#security

Nach Eingabe des o.g. Kommandos werden die folgenden Informationen abgefragt:

  • Keystore-Password, min. 6 Zeichen
  • Wiederholung des Keystore-Passwords
  • Vor- und Nachname
  • Name der organisatorischen Einheit
  • Name der Organisation
  • Name der Stadt der Gemeinde
  • Name des Bundeslandes oder der Provinz
  • Landescode

Wenn man das alles eingegeben hat, bekommt man die eingegeben Daten angezeigt und wird gefragt, ob alles richtig ist. Achtung, wer die Abfragen und Meldungen von keystore in Deutsch bekommt, wird bei der Abfrage

Ist CN=Rolf Dohrmann, OU=Rolf Dohrmann, O=Rolf Dohrmann,
L=Ottersberg, ST=Niedersachsen, C=DE richtig?
 [Nein]:  ja

Keytools speichert den keystore in dem Verzeichnis, in dem man sich aktuell befindet.

Um die Sache abzukürzen – es folgen noch einige Aktionen mit jarsigner, die bewirken, dass die App mit dem Zertifikat signiert wird. Eine genaue Beschreibung befindet sich im Originaldokument. Ich persönlich arbeite mit Eclipse, und da kann man sich das Leben etwas einfacher machen.

App kompilieren und signieren mit Eclipse und dem ADT Plugin

Die gute Nachricht: Wenn man mit Eclipse arbeitet und das ADT-Plugin installiert hat, kann man den Export Wizard benutzen. Dieser übernimmt alle Aktionen, die sonst manuell mit keytools und jarsigner durchgeführt werden müssten. Was ist zu tun?

  • Das Projekt im Project Exporer auswählen.
  • Rechte Maustaste -> Export.
  • Android / Export Android Application auswählen. Next.
  • Project auswählen, falls es noch nicht im Eingabefeld steht. Next.
  • Den keystore zuordnen. Angenommen, man hat bereits einen keystore mit keytools erstellt: Bei ‘Location’ den Pfad angeben und bei ‘Password’ das vorher festgelegte Passwort für den keystore eingeben. Next.
  • Der Alias sollte schon eingetragen sein. Das Passwort für den key eingeben. Next.
  • Angeben, wo die fertige APK gespeichert werden soll. Finish.

Auf diese Weise hat man sich die vielen Kommandos im Terminalfenster gespart. Besten Dank an die Entwicker des ADT Plugins!

Happy Coding,
Rolf Dohrmann

 

 

 

 

 

 

 

 

 

 

 

Posted in Android | Tagged | Leave a comment

Phonegap & jQuery Mobile – deviceready & $(document).ready

Ein paar Bemerkungen zu Phonegap’s  ‘deviceready’-Event, $(document).ready und anderen jQuery Mobile Event-Handlern.

Situation: Ich habe eine App mit Phonegap und jQuery Mobile erstellt. Die App sollte Cookies setzen und damit unter Umständen ein automatisiertes Login ermöglichen. Ich fand heraus, dass die Cookies zwar gesetzt wurden, aber dennoch nach einem Neustart der App nicht mehr zur Verfügung standen.

Obwohl kein unmittelbarer Zusammenhang erkennbar war, wollte ich ausschließen können, dass die Ursache des Fehlers darin lag, dass entweder Phonegap oder das DOM noch nicht vollständig geladen waren. Und so habe ich mich etwas intensiver damit beschäftigt.

Phonegap meldet sich, wenn es komplett geladen ist, über das Event ‘deviceready’. Also kann man sich über einen Event-Listener informieren lassen, wann’s denn soweit ist:

// event listener
function init() {
 document.addEventListener("deviceready", deviceInfo, true);  
}

Die Funktion ‘init’ wird in meinem Beispiel vom body-Tag der HTML-Seite aufgerufen:

<body onload="init();">

Nach Abfeuern der deviceready-Events wird die Callback-Funktion ‘deviceInfo’ aufgerufen. In ihr habe ich über ‘alert’ die Meldung ausgegeben, dass Phonegap nun zur Verfügung steht:

var deviceInfo = function() {
  alert('phonegap ready');
}

Desweiteren habe ich die folgende Funktion getestet:

$(document).ready(function() {    
  alert('dom ready');
});

Sie teilt mit, wann das DOM komplett geladen wurde.

Und als Letztes habe ich noch einen jQuery Mobile Event benutzt: ‘pagebeforeshow’. Dieser Event wird, wie der Name schon sagt, abgefeuert, bevor eine Seite in JQM angezeigt wird. Im folgenden Beispiel wird eine Funktion aufgerufen, bevor die JQM-Seite ‘#login’ angezeigt wird.

$('#login').live("pagebeforeshow", function() {
  alert ('pagebeforeshow');
});

Die Events wurden in der folgenden Reihenfolge angezeigt:

  1. pagebeforeshow
  2. dom ready
  3. phonegap ready

Ich kann nicht sagen, ob diese Reihenfolge in jedem Fall so auftritt. Tatsache ist, dass es bei meiner App so war. Und daraus ergibt sich z.B. folgendes:

Annahme 1: Ich habe über Phonegap eine Datenbank angelegt und darin meine Login-Daten gespeichert. Annahme 2: Ich möchte, wenn die Login-Seite geladen wird, diese Datenbak abfragen und ein automatisiertes Login durchführen, falls Login-Daten darin enthalten sind.

Wenn ich nun in der der Funktion, die beim Laden der Seite aufgerufen wird, den Zugriff auf die DB ausführen will, wird das scheitern,  da Phonegap noch nicht vollständig geladen ist und die Datenbank-Funktionen somit noch nicht zur Verfügung stehen. Dumm gelaufen.

Was kann man da tun? Sicherlich gibt es auch hier wieder mehrere Lösungsansätze. Ein Ansatz wäre, eine zeitgesteuerte Schleife einzubauen, die dann aktiv wird, wenn Phonegap noch nicht geladen ist, und die dann abbricht, wenn Phonegap geladen ist. Also so etwas in der Art:

if (!checkReady()) {
  // not loaded. create time loop that checks again
  var timeloop = window.setInterval(
    function() {
      if (checkReady()) {
        // cancel time loop
        window.clearInterval(timeloop);
        // do something with DB
      }
    }
    ,1000
  );
} else {
  // do something with DB
}

Wobei ‘checkready()’ eine Funktion wäre, die überprüft, ob Phonegap und DOM geladen sind.

Happy Coding,
Rolf Dohrmann

Posted in jQuery Mobile, PhoneGap, Uncategorized | Leave a comment

jQuery Mobile: Event feuert zweimal

Ich arbeite nun seit längerem mit jQuery Mobile und seit einigen Wochen beschäftige ich mich intensiv mit Phonegap. Die beiden scheinen sich ganz gut zu vertragen. In den letzten 24 Stunden habe ich mich allerdings schwarz geärgert. Anstatt meine Applikation zu entwickeln, musste ich mich ständig mit Problemen herumschagen, die (vermutlich) durch jQuery Mobile verursacht wurden und die mir bislang in dieser Form noch nicht untergekommen waren.

Auf eines der Probleme möchte ich hier eingehen. Es handelt sich um die Tatsache, dass jQuery Mobile unter bestimmten Umständen mehrfach mit dem Abfeuern eines Events reagiert. Das Maximum lag bislang immer bei 2 Events pro Aktion. Es war mir lange nicht klar, woher das seltsame Verhalten der App kam und es hat Stunden gedauert, bis ich den Fehler eingekreist hatte. Danach ging es darum, einen Workaround zu bauen, um das unerwünschte Verhalten abzustellen.

Konkret ging es um Folgendes:

Meine App beinhaltet eine Seite, die aus einer Reihe von DIV-Blöcken besteht, die durch eine Datenbankabfrage erzeugt werden. Die DIV-Blöcke beinhalten die Daten und sollen durch ein ‘tap’ angewählt werden können. Dazu habe ich die DIVs über die jQuery-Funktion ‘live()’ mit einem Event-Handler verbunden:

$('#pg-showRecs .oneRecShown').live('tap',function(event) {
}

Wie bereits oben erwähnt, stellte sich heraus, dass durch ein tap auf das DIV manchmal mehre tap-Events erzeugt wurden. Das führte dazu, dass ganz seltsame Phänomene auftraten. Die Zielseite wurde gelegentlich mit falschen Daten gefüllt (weil keine oder eine falsche ID übermittelt wurde) und manchmal wurde auch eine gänzlich andere Seite angezeigt. Wie ich inzwischen weiß, scheint das Phänomen bekannt zu sein und ist möglicherweise auch nicht nur auf jQuery Mobile beschränkt. Allerdings taucht es wohl im Zusammenhang mit der aktuellen Beta 1 verstärkt auf. Und diese Version benutze ich gerade. Infos in diesem Zusammenhang:

http://code.google.com/intl/en/mobile/articles/fast_buttons.html
http://forum.jquery.it/topic/events-firing-twice-new-to-beta-1

Was tun?

Ich fand im jQuery Mobile Forum einen Denkanstoß. Sicherlich kann man das Problem auch auf andere Art lösen, aber für mich hat es folgendermaßen funktioniert:

Der entscheidende Hinweis war, dass der zweite Event die gleichen Koordinaten haben würde wie der erste. Da es (zumindest in meinem Kontext) extrem unwahrscheinlich ist, dass der User zweimal hintereinander genau dieselben Koordinaten erwischt, konnte ich durch eine Abfrage der Koordinaten und Zwischenspeichern der jeweils letzten Koordinaten doppelte Events weitgehend abfangen. ‘Weitgehend’ deshalb, weil sich herausstellte, dass der zweite Event mitnichten immer genau dieselben Koordinaten enthält wie der erste. Nachdem ich auch das herausgefunden hatte, bestand die Lösung darin, abzufragen, ob sich die Werte der Koordinaten des ersten und des zweiten Events innerhalb eines bestimmten Bereichs befanden. Mit dieser Methode klappt nun alles erst einmal sehr gut.

Die Koordinaten des Events können folgendermaßen abgefragt werden:

$('#pg-showRecs .oneRecShown').live('tap',function(event)
    var x = event.clientX;
    var x = event.clientX;}

Happy Coding,
Rolf

Posted in jQuery Mobile, PhoneGap, smartphone, Webapp | Leave a comment

jQuery Mobile Projekt: Bereitstellung von Funktionalitäten der Software ‘Obserwando’ für die Nutzung auf Smartphones und Tablets

Einleitung

Die Firma Rösler Software-Technik GmbH bietet ihren Kunden eine Dienstleistung namens ‘Obserwando’ an. Dabei handelt es sich um eine Kombination aus Hardware und Software, die u.a. in den folgenden Bereichen eingesetzt werden kann:

  • Sicherung gegen Diebstahl und unbefugte Benutzung
  • Jederzeitige Standortbestimmung
  • Erfassung von Betriebszeiten
  • Nutzungskontrolle per elektronischem Schlüssel

von Baumaschinen und Fahrzeugen.

Ausführlichere Informationen über den Funktionsumfang von Obserwando finden sich auf der Firmen-Website.

Im engeren Sinne bezeichnet ‘Obserando’ eine webbasierte Software / Web-Applikation, mit deren Hilfe die genannten Dienstleistungen realisiert werden.

Funktionsweise Obserwando

Projektziele und Umsetzung

Das Ziel des Projektes war die Bereitstellung einer Teilmenge der Obserwando-Funktionalitäten zur Nutzung auf Smartphones und Tablets.

App vs. WebApp

Zunächst war die Frage zu klären, ob der Zugriff der mobilen Endgeräte auf die Daten des

Obserwando Login Screen

Obserwando Login Screen

Obserwando-Servers über eine App oder eine WebApp erfolgen sollte. Die Entscheidung fiel aus den folgenden Gründen zugunsten einer WebApp auf der Basis des  jQuery Mobile -Frameworks aus:

Die Entwicklung von Apps ist grundsätzliche zeit- und damit auch kostenintensiver als die Entwicklung von WebApps. Dies liegt u.a. daran, dass eine App nur auf dem Betriebssystem einsetzbar ist, für das sie entwickelt wurde, also z.B. iOS oder Android. Möchte man seinen Kunden möglichst freie Hand bei der Auswahl seines Smartphones/Tablets lassen (und damit des eingesetzten Betriebssystems), ist man gezwungen, für jedes in Frage kommende Betriebssysteme eine eigene App zur Verfügung zu stellen.

Eine WebApp kann hingegen prinzipiell auf allen Endgeräten genutzt werden, die einen halbwegs modernen Browser mitbringen. Leider verarbeiten die verschiedenen Browser HTML, CSS und Javascript nicht identisch, was zu Fehlern in der Darstellung oder der

Standortanzeige auf Google Map

Standortanzeige auf Google Map

Funktionalität der WebApp führen kann. Insofern wäre also auch bei einer WebApp eine Anpassung an unterschiedliche Browser/Betriebssysteme erforderlich. Diese Mehrarbeit kann durch den Einsatz der jQuery Mobile Bibliothek vermieden werden werden.

Ein weiterer großer Vorteil bei der Verwendung von WebApps ist, dass die User/Kunden neue Versionen nicht manuell updaten müssen, da die WebApp nicht auf den Endgeräten installiert ist.

jQuery Mobile

jQuery Mobile ist ein Framework, das die Entwicklung von WebApps für Smartphones und Tablets mit Touchscreen unterstützt. jQuery Mobile bietet Hilfe in vielen unterschiedlichen Bereichen der Entwicklung. Erwähnt werden soll die sehr breite Unterstützung unterschiedlichster Smartphone-Platformen, die in dieser Form derzeit von keiner anderen vergleichbaren Software geboten wird. Eine detaillierte Liste der unterstützten Browser/Betriebssysteme findet sich hier.

Technische Umsetzung

Die WebApp ist eine Client-Anwendung. Sie bezieht ihre Daten vom Obserwando-Server.

Auswahl der Maschinen

Auswahl der Maschinen

Es wurde auf eine strikte Trennung von Server und Client geachtet. Es wäre durchaus denkbar gewesen, die Seiten der WebApp zumindest auch teilweise auf dem Server zu generieren. Davon wurde Abstand genommen, um möglichst beide Systeme/Anwendungen unabhängig voneinander betreiben und pflegen zu können.

Die WebApp basiert auf HTML, CSS, Javascript. Darauf aufbauend kommen jQuery und jQuery Mobile zum Einsatz. Weitere Programmiersprachen wie PHP, Perl, etc. werden wurden nicht benötigt.

Die Datenkommunikation mit dem Server erfolgt über eine JSON-Schnittstelle.

Features

Eintrag in der Maschinenakte

Eintrag in der Maschinenakte

Die WebApp bietet die folgenden Features:

  • Login
  • Mehrsprachigkeit (derz. Deutsch und Englisch)
  • Dynamisch erzeugte Seiteninhalte
  • Anzeige von Geo-Daten in einer eingebundenen Google Map.
  • Anzeige von Realtime-Daten der verwalteten Maschinen.

Die WebApp kann unter folgender Adresse aufgerufen werden und sollte mit allen Webkit-Browsern und auch Firefox bedienbar sein:

https://m.obserwando.de/

Für das Login können folgenden Daten verwendet werden:

  • Deutsch: gast/gast
  • Englisch: guest/guest

Eine Kurzbeschreibung / Handbuch findet sich hier:

Obserwando auf dem Smartphone

Posted in Projekt / Project, smartphone, Web App, Webapp | Leave a comment

Der Back-Button ist weg / jQuery Mobile

Die Macher von jQuery Mobile haben die Version Beta 1 (jquery.mobile-1.0b1) veröffentlicht. Es gibt wieder eine ganze Reihe von Änderungen. Eine der Änderung betrifft den Back-Button.

back-button jquery mobile beta 1

Bislang war es so, dass man sich nicht um das Einfügen des Back-Buttons kümmern musste. Wenn man auf eine Seite verlinkte, wurde der Back-Button von jQuery mobile automatisch in den Header eingefügt. Das ist seit der Beta 1 nicht mehr so. Eine ausführliche Begründung, warum dieses Feature ausgeschaltet wurde, findet sich im Blog des jQuery mobile teams.

Wer den Back-Button tatsächlich braucht, kann ihn mit Hilfe des data-Attributs sehr einfach für jede einzelne Seite wieder einfügen:

<div data-role="page" id="page2" data-add-back-btn="true">

Soll der Back-Button auf allen Seiten (außer der ersten) erscheinen, empfiehlt es sich, die Konfiguration von jQuery mobile zu ändern:

<script>
 $(document).bind("mobileinit", function() {
 $.mobile.page.prototype.options.addBackBtn = true;
 });
 </script>

Der obige Code muss in die HTML-Seite eingebunden werden, bevor die jQuery-mobile-Bibliothek geladen wird, also oberhalb der Zeile

<script src="pfad/jquery-mobile-version.js"></script>


Rolf Dohrmann
Developement / Entwicklung von WebApps, Apps, Maps

Posted in jQuery Mobile, Web App, Webapp | Tagged , , , | Leave a comment

#05 – Tutorial – Web Apps mit jQuery mobile – einfache Liste

von Rolf Dohrmann / Web-App Entwickler

Ziel dieses Tutorials:

Erstellen einer Seite mit einer einfachen Liste. Die Listenelemente sind anklickbar und laden externe Seiten in die Web-App.

Dieses Tutorial baut auf den vorherigen Turorials auf.

Listen sind übliche Elemente einer Web-App (in Titanium heißen sie übrigens “tableview”). jQuery mobile (JQM) bietet viele Möglichkeiten Listen zu formatieren und dem eigenen Bedarf anzupassen. Schauen wir uns zunächst den Aufbau einer Liste in ihrer einfachsten Form an.

Eine Liste in JQM basiert auf dem HTML-Listen-Tag “ul”. Damit jQuery mobile die Liste nicht als einfache HTML-Liste darstellt, sondern sie bezüglich Design und Funktion in der auf Smartphones üblichen Weise aufbaut, muss man die data-role angeben, in diesem Fall:

data-role="listview"

ganz verschiedene

Wie erstellt man eine Liste, und wie wird die Liste aussehen?

Innerhalb des Content-Bereichs der Seite, in der die Liste erscheinen soll, muss folgender oder ähnlicher Code eingefügt werden:

<ul data-role="listview">
 <li><a href="gelb.html">gelb</a></li>
 <li><a href="gruen.html">grün</a></li>
 <li><a href="blau.html">blau</a> </li>
</ul>

Das Beispiel geht davon aus, dass es drei externe Seiten (gelb.html, gruen.html und blau.html) gibt, die bei Klick/Tab auf einen Listeneintrag angezeigt werden sollen.

Weil es gerade so gut passt, möchte ich auf den Zeichencode hinweisen. Ohne Angabe eines Zeichencodes wird der obige Quelltext das folgende oder ein ähnlich unschönes Resultat bringen:

Umlaut

Der Grund dafür ist, dass bei den bisherigen Tutorials darauf verzichtet wurde, einen Zeichencode im Header zu definieren. Daraus resultieren Schwierigkeiten in der Darstellung von Umlauten etc. Da ich meine Dateien in UTF-8 speichere, füge ich dem Header folgende Zeichencodedeklaration hinzu:

<meta charset="utf-8">

Damit ist das Problem behoben, die Beschriftung der Liste wird korrekt dargestellt. Auf dem folgenden Screenshot ist das “ü” ein “ü” und desweiteren sieht man, dass jQuery mobile die Listeneinträge nicht nur formatiert hat, sondern auch einen kleinen Pfeil am rechten Rand eines jeden Eintrages eingefügt hat.

Liste korrekt

Hier kommt der Quelltext:

<!DOCTYPE html>
<html>
 <head>
 <title>Tutorial #5</title>
 <meta charset="utf-8">
 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css" />
 <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
 <script src="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js"></script>
</head>
<body>

<div data-role="page" id="home">

 <div data-role="header">
 <h1>Basic List</h1>
 </div><!-- /header -->

 <div data-role="content">
 <ul data-role="listview">
 <li><a href="gelb.html">gelb</a></li>
 <li><a href="gruen.html">grün</a></li>
 <li><a href="blau.html">blau</a> </li>
 </ul>
 </div><!-- /content -->

 <div data-role="footer">
 <h4>Footer</h4>
 </div><!-- /footer -->
</div><!-- /page -->

</body>
</html>

Happy Coding,

Rolf Dohrmann


Posted in Allgemein, jQuery Mobile, smartphone, Tutorial, Web App, Webapp | Leave a comment

#04 – Tutorial – Web Apps mit jQuery mobile – externe Seiten

von Rolf Dohrmann / Web-App Entwickler

Im letzten Tutorial ging es um die Verlinkung interner Seiten. Von internen Seiten spricht man in diesem Zusammenhang, wenn sich mehrere Seiten innerhalb eines HTML-Dokuments befinden. Diesmal geht es um die Anzeige von externen Seiten, so wie man es von “normalen” Websites her kennt.

Von Handling her ist es denkbar einfach, eine externe Seite zu verlinken. Man muss gar nichts Besonderes beachten, der Link sieht aus wie immer:

<a href="ziel.html">Dies ist ein Link</a>

Aber was passiert, wenn man auf den Link klickt? Jedenfalls nicht das, was man von “normalen” Webseiten her kennt. Denn dann würde die Seite, auf der sich der Link befindet, verschwinden und die neue erscheinen. Was wäre mit dem Header und dem Footer? Die müssten in jede Seite eingebunden werden. Der User hätte ein Flackern, wenn die alte Seite verschwindet und die die neue noch nicht da ist.

Wie dem auch sei, bei jQuery mobile (JQM) läuft das ein wenig anders: JQM fängt den Klick auf den Link ab, lädt die anzuzeigende Seite via AJAX und integriert den Teil der Seite, der die verwertbaren Elemente enthält. Was sind die verwertbaren Elemente?  Etwa so etwas:

<div data-role="page" id="seite03">

  <div data-role="header">
    <h1>Seite 03</h1>
  </div><!-- /header -->

  <div data-role="content">
    <h1>Seite 03 - extern</h1>
  </div><!-- /content -->

  <div data-role="footer">
   <h4>Footer</h4>
  </div><!-- /footer -->

</div><!-- /page -->

Diese Struktur kennen wir ja bereits aus den vorherigen Tutorials. Sie definiert für JQM eine Seite. Alles, was außerhalb dieser Struktur steht, ist für jQuery mobile uninteressant.

Nachdem JQM die externe Seite via AJAX eingelesen hat, werden die relevanten Teile (siehe oben) in die Struktur der aufrufenden Seite eingebaut, so, als würde es sich um eine interne Seite handeln. Sie wird in das DOM (Document Object Model) integriert.

Einer der Vorteile dieses Vorgehens ist, dass die ins DOM integrierte Seite ab sofort bei jedem erneuten Aufruf immer direkt zur Verfügung steht. Sie wird also ohne Verzögerung angezeigt, muss nicht immer wieder aus dem Internet geladen werden. Und darum geht es ja u.a., dass der User den Eindruck einer in sich kompletten App erhält, die schnell reagiert und somit unnötige Wartezeiten vermeidet.

Hier ist der Quelltext der aufrufenden = Hauptseite:

<!DOCTYPE html>
<html>
 <head>
 <title>Tutorial #4</title>
 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css" />
 <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
 <script src="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js"></script>
</head>
<body>

<div data-role="page" id="seite01">

 <div data-role="header">
 <h1>Seite 01</h1>
 </div><!-- /header -->

 <div data-role="content">    
 <h1>Seite 01</h1>
 <p><a href="#seite02">Hier geht's zur Seite 02 - intern</a></p>
 <p><a href="seite-03.html">Hier geht's zur Seite 03 - extern</a></p>
 <p><a href="seite-gibts-nicht.html">Hier kommt eine Fehlermeldung</a></p>

 </div><!-- /content -->

 <div data-role="footer">
 <h4>Footer</h4>
 </div><!-- /footer -->
</div><!-- /page -->

<div data-role="page" id="seite02">

 <div data-role="header">
 <h1>Seite 02</h1>
 </div><!-- /header -->

 <div data-role="content">    
 <h1>Seite 02</h1>    
 </div><!-- /content -->

 <div data-role="footer">
 <h4>Footer</h4>
 </div><!-- /footer -->
</div><!-- /page -->

</body>
</html>

Und hier kommt der Quelltext der aufzurufenden, externen Seite (übrigens muss sie nicht die Links auf die jQuery mobile Dateien im Head beinhalten):

<!DOCTYPE html>
<html>
 <head>
 <title>Tutorial #4</title>
</head>
<body>

<div data-role="page" id="seite03">

 <div data-role="header">
 <h1>Seite 03</h1>
 </div><!-- /header -->

 <div data-role="content">    
 <h1>Seite 03 - extern</h1>        
 </div><!-- /content -->

 <div data-role="footer">
 <h4>Footer</h4>
 </div><!-- /footer -->
</div><!-- /page -->

</body>
</html>

Und so sollte das dann aussehen (Firefox auf Mac):

Hauptseite:

Seite 01

Externe Seite 03:

Seite 03

Übrigens managed jQuery mobile auch Fehlermeldungen automatisch. In obigem Beispiel befindet sich ein Link auf eine nicht existierende Datei. Anstatt sich aufzuhängen oder eine weiße Seite mit Fehlermeldung anzuzeigen, bleibt JQM in Kontext der aufrufenden Seite und zeigt eine nette, kurz erscheindene Fehlermeldung in einem Fenster an, dass nach ein paar Sekunden wieder verschwindet. Und weil es so schnell wieder weg ist, kriege ich auch keinen Screenshot hin, auf dem dieses Fenster zu sehen wäre…
Happy Coding!
Rolf Dohrmann
Web & App & Map Entwickler
Web & App & Map Developer
Posted in Allgemein, Entwicklung, jQuery Mobile, smartphone, Tutorial, Web App, Webapp | Leave a comment

#03 – Tutorial – Web-Apps mit jQuery mobile – interne Seiten

von Rolf Dohrmann / Web-App Entwickler

Im letzten Tutorial haben wir uns das Basisgerüst einer jQuery mobile (JQM) Webapp zu Gemüte geführt. Dabei ging es nur um die Darstellung einer einzelnen Seite. Eine Webapp mit einer Seite macht nicht viel Sinn, und darum schauen wir uns jetzt an, auf welche Weise man mehr als eine Seite in der Webapp unterbringen und verlinken kann.

Es gibt grundsätzlich zwei Möglichkeiten der Einbindung weiterer Seiten: intern und extern. In diesem Tutorial geht es um die Einbindung interner Seiten.

Vorab sei noch bemerkt, dass ab jetzt die Vorzüge des JQM-Frameworks deutlich werden. In diesem Zusammenhang denke ich z.B. an die Titelleiste, in der standardmäßig der Name der angezeigten Seite angezeigt wird und in der ein Back-Button erscheint, sobald man eine zweite Seite aufgerufen hat. Dies sei nur mal so am Rande erwähnt. Es gibt noch viel mehr, was JQM im Hintergrund für uns erledigt, aber auch dazu schreibe ich bei Gelegenheit an anderer Stelle mehr.

Nun aber los.

Sobald eine Webapp (oder auch eine Website) aus mehr als einer Seite besteht, wird eine Navigation benötigt, um zu der oder den anderen Seiten zu gelangen. Wir machen das erst einmal sehr rudimentär und einfach: wir setzen einen Link in den Contentbereich der ersten Seite. Über diesen Link kommt man zur zweiten Seite. Von der zweiten Seite kommt man über den oben erwähnten Back-Button zurück auf die erste Seite.

Damit man verlinken kann, benötigt jede Seite, also die page, eine eigene ID. Vielleicht ein kleiner Hinweis am Rande (obwohl es ziemlich offensichtlich ist): Die Funktion, die ein bestimmter DIV-Block in der Gesamtseite hat, wird über das Attribut “data-role” definiert. So ist der DIV-Container mit data-role=”page” der Container für die anzuzeigende Seite. Der Container mit der data-role=”header” definiert die Titelzeile, usw.

Der Quellcode für die erste Seite könnte also folgermaßen aussehen:

<div data-role="page" id="seite01">
   <div data-role="header">
     <h1>Seite 01</h1>
   </div><!-- /header -->
   <div data-role="content">
     <h1>Seite 01</h1>
     <p><a href="#seite02">Hier geht's zur Seite 02</a></p>
   </div><!-- /content -->
   <div data-role="footer">
     <h4>Footer Page 1</h4>
   </div><!-- /footer -->
</div><!-- /page -->

Und die zweite Seite so:

<div data-role="page" id="seite02">
  <div data-role="header">
    <h1>Seite 02</h1>
  </div><!-- /header -->
  <div data-role="content">
    <h1>Seite 02</h1>
  </div><!-- /content -->
  <div data-role="footer">
    <h4>Footer</h4>
  </div><!-- /footer -->
</div><!-- /page -->

Der Link von Seite 01 auf Seite 02 hat als Zieladresse

href="#seite02"

Wenn man mit internen Verlinkungen arbeitet, benutzt man das Nummernzeichen und die ID der anzuzeigenden Seite. Das war’s. Wenn alles klappt, sollte das Ergebnis so aussehen (in Safari auf Mac):

Seite 01

Seite 02

Hier nochmal der komplette Quelltext:
<!DOCTYPE html>
<html>
 <head>
 <title>Tutorial #3</title>
 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css" />
 <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
 <script src="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js"></script>
</head>
<body>

<div data-role="page" id="seite01">

 <div data-role="header">
 <h1>Seite 01</h1>
 </div><!-- /header -->

 <div data-role="content">    
 <h1>Seite 01</h1>
 <p><a href="#seite02">Hier geht's zur Seite 02</a></p>        
 </div><!-- /content -->

 <div data-role="footer">
 <h4>Footer</h4>
 </div><!-- /footer -->
</div><!-- /page -->

<div data-role="page" id="seite02">

 <div data-role="header">
 <h1>Seite 02</h1>
 </div><!-- /header -->

 <div data-role="content">    
 <h1>Seite 02</h1>    
 </div><!-- /content -->

 <div data-role="footer">
 <h4>Footer</h4>
 </div><!-- /footer -->
</div><!-- /page -->

</body>
</html>
Happy Coding,
Rolf Dohrmann
Web, App und Map-Entwickler
Web, App and Map Developer
Posted in jQuery Mobile, smartphone, Tutorial, Webapp | Leave a comment

#02 – Tutorial – Web-Apps mit jQuery mobile – die erste Seite

von Rolf Dohrmann / Web-App Entwickler

Die erste Seite mit jQuery mobile. Sozusagen ein Kinderspiel. Auf der jQuery Mobile (JQM) Website ist beschrieben, wie’s geht. Insofern ist dieses Tutorial fast überflüssig. Dort steht ja schon alles… Aber eben doch nicht alles. Ansonsten hätte ich nicht inzwischen Stunden damit zugebracht heraus zu finden, wie dieses und jenes funktioniert bzw. warum es eben nicht funktioniert. Vielleicht kann ich ja doch noch ein paar hilfreiche Infos einfließen lassen. Außerdem ist ja nicht jede/r des Englischen mächtig. Und erschwerend kommt hinzu, dass ich mir nicht alles merken kann und darum mit Sicherheit bei Bedarf auch selbst in mein eigenes Tutorial schauen werde. Insofern ist dies hier auch mein eigenes Nachschlagewerk. Soviel zur “Rechtfertigung” ;-)

Hier sind die Original-”Docs” zur aktuellen Version 1.0a2:

http://jquerymobile.com/demos/1.0a2/

Als kleine Einleitung sei bemerkt, dass JQM standardmäßig alle anzuzeigenden Seiten, also die Seiten der Webapp, per AJAX in das DOM der Startseite einbaut. EDV-Kauderwelsch? Muss man das verstehen? Nein, nicht unbedingt und vor allem nicht jetzt. Ganz unwichtig ist es aber nicht, denn auf diesem Paradigma beruht das komplette JQM-Framework. Nehmen wir diese kleine Info als einen Hinweis für diejenigen, die bereits mit AJAX und dem DOM in Berührung gekommen sind. Alle anderen lassen sich nicht beeindrucken oder gar abschrecken!

Jetzt aber genug geschwafelt, hier kommt der Quelltext der ersten Seite:

<!DOCTYPE html>
<html>
<head>

 <title>Tutorial #2</title>
 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css" />
 <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
 <script src="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js"></script>

</head>
<body>

<div data-role="page">
   <div data-role="header">
     <h1>Header Page 1</h1>
   </div><!-- /header -->
   <div data-role="content">
     <p>Page content goes here.</p>
   </div><!-- /content -->
   <div data-role="footer">
     <h4>Footer Page 1</h4>
   </div><!-- /footer -->
</div><!-- /page -->

</body>
</html>

So sieht die Seite auf einem Mac im Safari-Browser aus:

JQM erste Seite

War doch gar nicht so schwierig :-)

Aber im Ernst, verglichen mit der Entwicklung einer nativen App hat man’s beim Schreiben von Webapps wirklich viel leichter. Kein Kompilieren, kein Anzeigen in einem Emulator (den man erst einmal downloaden, installieren, eventuell konfigurieren muss und der dann auf Anhieb vielleicht trotzdem nicht funktioniert…).

Safari, Chrome, Firefox sind auf jedenfall gut zum Testen. Irgendwann sollte man sich das Werk dann auch auf einem Smartphone ansehen, aber das hat erst einmal noch Zeit.

So, was gibt’s denn nun in der Webapp zu sehen?

Da wäre zum einen ein Titel in der Browser-Kopfzeile und auf dem Reiter/Tab (Tutorial #2). Im Anzeigefenster (Viewport) des Browsers erscheint die Webapp mit einer eigenen Titelleiste (Header Page 1), einem Contentbereich (Page content goes here) und einer Fußzeile (Footer Page 1). Wie haben wir das gemacht? Schauen wir in den Quellcode.

JQM basiert auf HTML-Dokumenten, die in HTML5 geschrieben sind. Damit der Browser weiß, dass er ein HTML5-Dokument darstellen soll, muss man ihm das durch den Doctype mitteilen. Und der ist bei HTML5 erfreulich kurz und einfach:

<!DOCTYPE html>

Die folgenden drei Zeilen

<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css" />
<script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js"></script>

binden die JQM-Sytlesheet-Datei, das jQuery- und das jQuery mobile-Framework ein. Im obigen Beispiel werden die Dateien aus dem Internet geladen. Man kann sie sich aber auch downloaden und dann die downgeloadeten Dateien in das Projekt einbinden. Vorteil: man ist dann nicht davon abhängig, dass der jquery.com-Server funktioniert.

Der folgende Block definiert in JQM eine Seite. Man könnte auch mehrere Seiten in einer HTML-Datei definieren, doch dazu später.

<div data-role="page">
</div><!-- /page -->

Eine Seite kann wiederum in verschiedene Bereiche unterteilt werden: Header, Content und Footer:

   <div data-role="header">
   </div><!-- /header -->
   <div data-role="content">
   </div><!-- /content -->
   <div data-role="footer">
   </div><!-- /footer -->

Diese Bereiche können mit den üblichen HTML-Mitteln gestaltet werden, z.B:

   <div data-role="content">
     <p>Page content goes here.</p>
   </div><!-- /content -->

Die Kommentare (z.B. <!– /content –>) sind nicht zwingend erforderlich. Sie sollen nur die Lesbarkeit des Quelltextes verbessern.

HPY CDNG!

Rolf Dohrmann


Web-App Entwickler
Web App Developer

Posted in Allgemein, jQuery Mobile, smartphone, Tutorial, Web App, Webapp | Leave a comment