Cordova / PhoneGap - Audio Player Tutorial Android

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Cordova / PhoneGap - Audio Player Tutorial Android

      Hallo liebe [lexicon]Cordova[/lexicon] / [lexicon]PhoneGap[/lexicon] – Entwickler,

      ich möchte euch hier einen Workshop anbieten, der einige wichtige Bestandteile im Umgang mit der [lexicon]Cordova[/lexicon] / [lexicon]PhoneGap[/lexicon] File-API, Media-API abdeckt.
      Wir werden gemeinsam Schritt für Schritt einen „intelligenten“ Audio-Player in [lexicon]Javascript[/lexicon] programmieren und diesen auf eure Endgeräte voll lauffähig machen.
      Die avisierte Zielplattform wird Android sein. Der hier vorgestellte Quellcode ist aber leicht an andere Plattformen, wie IOS, anpassbar!

      Und noch eins: Ich lege hier größten Wert auf die deutsche Sprache und werde von daher jedes englische Detail genauestens erklären. Wenn's recht ist :)

      Zum Projekt:

      Audio Player a-la Samsung

      Features:
      • Zugriff auf alle auf dem Gerät gespeicherten Audio-Dateien
      • Zugriff auf alle auf einer eventuell verfügbaren Speicherkarte gespeicherten Audio-Dateien
      • Persistente Speicherung im Local Storage
      • Persistente Speicherung in einer SQLite-Datenbank
      • Permanente Wiedergabe aller gefundenen Audio’s
      • Alle Player-Typischen Funktionen wie Vor und Zurück, Pause, Stopp, Loop, scrollbare Fortschrittsanzeige
      • Speicherung der "letzten Wiedergabe" (max. die letzten 50 Titel)
      • Favoriten-Liste
      • Neusynchronisierung aller Audio-Dateien
      • Design in JQuery Mobile

      Die Oberfläche des Home könnte wie folgt aussehen:

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Ich werde als erstes mit der [lexicon]HTML[/lexicon]-Struktur beginnen und mache hier erst einmal Schluß, um in Erfahrung zu bringen, ob überhaupt ein Interesse an diesen Workshop besteht. Sollte dies der Fall sein, antwortet einfach auf diesen Thread!

      Bis dann, Mario (vtaker)


      Okay Freunde. Los geht's!



      Fangen wir also an.

      Schritt 1a: Einrichten eines [lexicon]Cordova[/lexicon]-Projekts / (Schritt 1b: Erstellen eines [lexicon]PhoneGap[/lexicon]-Projektes)


      Eigentlich sollte man voraussetzten, wie ein solches Projekt angelegt wird. Es gibt hier auch ein sehr schönes Tutorial, was umfassend beschreibt, wie ein solches Projekt angelegt wird.

      Wie erstelle ich meine erste Android App unter Windows

      Von daher werde ich nur das Nötigste anreißen. Auch wird vorausgesetzt, dass alle Software-Pakete einschließlich Android [lexicon]SDK[/lexicon] und das ADT-[lexicon]Plugin[/lexicon] für Eclipse vorhanden ist und alle Pfade korrekt angepasst sind. Ich werde das Projektverzeichnis auf dem Desktop platzieren. Dies soll aber nicht heißen, dass ihr jetzt ein solches Verzeichnis auf euren Desktop platziert. Das erledigt für uns das Kommandozeilentool [lexicon]CMD[/lexicon].

      Drücke die Windows Taste (Zwischen STRG & ALT) und gleichzeitig R. In dem sich öffnenden Fenster trägst Du „[lexicon]CMD[/lexicon]“ ein und drückst "Enter". Um nun auf Deinem Desktop zu wechseln, gebe den guten alten DOS Befehl „cd“ gefolgt von einem Leerzeichen und danach „Desktop“ ein. Das Ganze mit Enter bestätigen. Nun erstellen wir unser [lexicon]Cordova[/lexicon] Projekt mittels dem Befehl:

      Quellcode

      1. cordova create AudioPlayer com.example.audioplayer AudioPlayer


      Nun, nachdem unser Projekt erfolgreich erstellt wurde, wechseln wir mit

      Quellcode

      1. cd AudioPlayer


      in unser Projekt-verzeichnis. Als nächstes müssen wir unserem [lexicon]Cordova[/lexicon] Projekt mitteilen, auf welchen Plattformen es später laufen soll. Da wir uns für Android entschieden haben, gibt ihr als nächsten Befehl

      Quellcode

      1. cordova platform add android


      in die [lexicon]CMD[/lexicon] ein. Nachdem wir nun unsere Zielplattforrm hinzugefügt haben, müssen wir zum Schluß das ganze Projekt kompilieren (erzeugen). Dies geschieht mit dem Befehl

      Quellcode

      1. cordova build


      Diesen Kompiler-Befehl solltet ihr euch, wenn ihr [lexicon]Cordova[/lexicon] arbeitet, hinter die Ohren schreiben, da dieser bei jeder Änderung am Quellcode ausgeführt werden muß, bevor das Projekt getestet werden kann. Dies geht mir gelinde gesagt, gehörig auf dem Sa… Sorry! J Anderenfalls werden Änderungen nicht mit übersetzt!!! Weswegen ich auch viel lieber mit [lexicon]PhoneGap[/lexicon] arbeite. Aber das ist Geschmackssache.

      Jetzt wird es Zeit, unser Projekt in Eclipse zu importieren. Schließt die [lexicon]CMD[/lexicon], falls nicht schon geschehen und startet Eclipse (als Administrator ausführen). Nach Festlegen des Workspace,- kann man auf dem Standard belassen und für alle Projekte übernehmen, man möge mich Erschlagen, wenn ich jetzt etwas falsches behauptet habe, wird Eclipse vollständig geladen, [lexicon]SDK[/lexicon]’s initialisiert und nötigenfalls aktualisiert, sowie der Arbeitsbereich eingerichtet. Dies kann etwas Zeit in Anspruch nehmen. Kann man in Eclipse im rechten Statusbereich beobachten.

      Zunächst klicken wir oben auf File -> New -> Project. In dem sich öffnenden Fenster klicken wir auf "Android" und anschließend auf "Android Project from existing Code". Im nächsten Schritt klicken wir oben auf "Browse" wählen den "AudioPlayer" Ordner auf dem Desktop aus und gehen ins das Verzeichnis "AudioPlayer" -> "platforms" -> "android". Diesen Ordner klicken wir an und klicken auf "Ok". Nun noch auf "Finish" und unser AudioPlayer-Projekt wird importiert.

      Ihr findet nun im linken Bereich, den Package-Explorer, unser Projekt wieder. Dies ist hierarchisch aufgebaut, ähnlich wie beim Windows-Explorer. Klickt nun auf das Wurzelverzeichnis unseres Projektes (AudioPlayer) und anschließend (obere Menüleiste) auf "Project" -> "Properties". In dem neuen Fenster auf "Resource" -> "Resource Filters" und dann löschen wir die beiden enthaltenen Filter..."Apply" und "Ok".

      Damit ist euer Projekt vollständig in Eclipse eingerichtet.


      Schritt 1b: Erstellen eines [lexicon]PhoneGap[/lexicon]-Projektes

      Ein [lexicon]PhoneGap[/lexicon]-Projekt zu erstellen, ist wesentlich unspektakulärer und doch gibt es auch hier einiges zu beachten.

      Zunächst benötigen wir ein [lexicon]PhoneGap[/lexicon] Release, was ihr auf der Seite

      PhoneGap Project

      finden könnt. Diese Seite empfiehlt sich in übrigen als Favorit abgespeichert zu werden. Sie liefert uns ein ausführliches Kompendium rund um alle API’s in [lexicon]PhoneGap[/lexicon]. Dort angekommen, klickt ihr auf die Schaltfläche „Install [lexicon]PhoneGap[/lexicon]“. Man kann [lexicon]PhoneGap[/lexicon] ebenfalls überdie [lexicon]CMD[/lexicon] installieren, wir gehen aber diesmal einen anderen Weg. Im unterem Abschnitt der sich geöffneten Seite findet ihr ein Release-Archiv. Klickt nun auf das Archiv „[lexicon]PhoneGap[/lexicon] 2.9.0“ vom 26. Juni 2013. Für unsere Zwecke ist dieses Archiv sehr stabil und fast überdimensioniert. Ladet euch das Zip-Archiv in einen beliebigen Ordner,- dieser sollte natürlich vorhanden und aussagekräftig sein. Das erspart viel Sucherei. Zu guter Letzt, das ganze Teil noch austüten und fertig!

      Startet nun Eclipse (als Administrator ausführen). Eclipse sollte immer als Admin gestartet werden! Dies könnt ihr dauerhaft festlegen, indem ihr auf euren Desktop das Eclipse-Icon mit der rechten Maustaste anklickt und im Kontextmenü „Eigenschaften“ aufruft. Klickt nun auf den Reiter „Kompatibilität“ und hakt nun unter „Berechtigungsstufe“ „Programm als Administrator ausführen“ an. Anschließend auf „Übernehmen“ und „OK“. Fertig ist der Lack.

      Nach Festlegen des Workspace,- kann man auf dem Standard belassen und für alle Projekte übernehmen, man möge mich Erschlagen, wenn ich jetzt etwas falsches behauptet habe, wird Eclipse vollständig geladen, [lexicon]SDK[/lexicon]’s initialisiert und nötigenfalls aktualisiert, sowie der Arbeitsbereich eingerichtet. Dies kann etwas Zeit in Anspruch nehmen. Kann man in Eclipse im rechten Statusbereich beobachten. Sollten in Eclipse noch irgendwelche Projekte geöffnet sein, schließt diese mit einem Klick auf „File -> Close All“.

      Nun ist es an der Zeit unser [lexicon]PhoneGap[/lexicon]-Projekt zu erstellen. Klickt hierfür auf „File -> New -> Projekt“.In dem sich nun öffnenden Dialog wählt ihr „Android Application Project“ und klickt danach auf „Next“.

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Im nächsten Fenster geben wir unserem Kind einen Namen. In der Spalte „Application Name“ geben wir nun „Audio Player“ ein. Lasst zwischen Audio und Player ruhig ein Leerzeichen. Das ist der Name, der auf unseren Handy später unter dem Icon erscheint. In der Regel sollten alle restlichen Textfelder automatisch befüllt werden und auch nicht geändert werden. Übernehmt die Einstellungen wie auf dem nachfolgendem Bild.

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Ein weiterer Klick auf „Next“, bringt uns zum nächsten Dialog. Wer hätte das gedacht. Auch diese Einstellungen übernehmt ihr, wie auf dem folgendem Screen.

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Wieder ein Klick auf „Next“. Jetzt haben wir die Möglichkeit ein Bild das uns als Icon dienen soll, festzulegen. Es wird automatisch für alle Auflösungen skaliert. Das Resultat bekommt man in Echtzeit recht präsentiert. Ein Klick auf „Browse“, Bilddatei auswählen, „Trim Surrounding Blank Space“ aktivieren, gegebenfalls einen Hinergrund durch Klick auf „Square“ für einen rechteckigen Hintergrund, oder „Circle“ für einen runden Hintergrund festlegen. Eine Hinergrundfarbe über „Background Color“ definieren. Oder man lässt den Hintergrund mit einem Klick auf „None“ weg.

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Und wieder auf „Next“ klicken. Im nächsten und letztem Dialog stellt bitte sicher, dass die Option „Create Activity“ aktiviert und „Blank Activity“ angewählt ist.

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Noch einmal auf „Next“ und belasst alles so, wie es ist.

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Jetzt nur noch auf „Finish“ klicken und unser Projekt wird erzeugt. Dies kann etwas Zeit in Anspruch nehmen. Den Fortschritt kann man in der Statusbar unten rechts verfolgen.

      Ist unser Projekt fertig gestellt, wird unser Projekt im Package-Explorer,- dass ist der linke Bereich von Eclipse, hinzugefügt und freundlicher Weise auch gleich der dazugehörige Baum geöffnet. Das mittlere Fenster (Main Window) repräsentiert unseren Code-Explorer und dort wurde zugleich die „activity_main.xml“ in der visuellen Ansicht (Graphical Layout) geladen. Ein Klick auf den Dateinamen neben „Graphical Layout“ unterhalb des Code-Explorers, würde uns die Code-Ansicht bringen.

      Da wir an dieser Datei keinerlei Änderungen vornehmen werden, kann diese durch einen Klick auf das Kreuz der aktiven Datei (oberhalb des Code-Explorers) geschlossen werden.

      Desweiteren wurde die Datei „MainActivity.java“ geöffnet. Obwohl Java nicht unsere Baustelle ist, muss an dieser Datei einmalig kleine Anpassungen vorgenommen werden.

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Schauen wir uns zunächst einmal unser Projekt im Package-Explorer mal etwas genauer an.

      Im Ordner „src“ befinden sich unsere Java-Klassen, die uns beim entwickeln unserer App zur Verfügung stehen. Hier haben wir eigentlich nichts verloren. Erst recht haben wir nichts im Ordner „gen“ verloren. Dort befindet sich unsere fertig kompilierten (übersetzten) Dateien, die zur Laufzeit auf unserem Handy ausgeführt werden. Es folgen die Android-Bibliotheken. Der Ordner „assets“ hingegen wird unsere Spielwiese. Dort werden wir uns die meiste Zeit kräftig austoben. Dazu gleich mehr. Desweiteren ist für uns der Ordner „libs“ kurzzeitig interessant. Hierin befinden sich Jar-Dateien, oder halt nur eine Jar-Datei. Noch. Im Ordner „res“ befinden sich die Ressourcen unseres Projekts. Unter anderem auch unser Icon für unsere App in sämtliche Zoomstufen.

      Fazit: Uns interessiert eigentlich nur der Ordner „assets“!!!

      Okay, nun machen wir unser Projekt mit [lexicon]PhoneGap[/lexicon] bekannt. Und organisieren die Hochzeit.

      Ihr habt zu Beginn ein [lexicon]PhoneGap[/lexicon] Release 2.9.0 herunter geladen und entpackt. Öffnet nun euren Windows-Explorer und öffnet den entpackten [lexicon]PhoneGap[/lexicon] Ordner. Dort findet ihr 2 Verzeichnisse. „doc“ für Dokumentationen und den Ordner „lib“. Öffnet nun den Ordner „lib“ und ihr findet für alle möglichen Plattformen ein Unterverzeichnis. Uns interessiert das Android-Verzeichnis. Öffnet dieses. Hier finden wir eine,- Achtung jetzt wird’s bunt!, eine Jar-Datei mit den Namen „[lexicon]cordova[/lexicon]-2.9.0.jar“. Wir sind nach wie vor bei [lexicon]PhoneGap[/lexicon]! Die Namensgebung rührt daher:

      Quelle Wikipedia:

      [lexicon]PhoneGap[/lexicon] baut auf Apache [lexicon]Cordova[/lexicon] auf welches von Adobe/Nitobi der Apache Software Foundation gespendet wurde. Apache [lexicon]Cordova[/lexicon] hieß ursprünglich ebenfalls [lexicon]PhoneGap[/lexicon], musste aber aus rechtlichen Gründen umbenannt werden, da für Apache Projekte aus markenrechtlichen Gründen keine bereits belegten Namen verwendet werden dürfen. Es wurde zunächst Apache Callback genannt und später in Apache [lexicon]Cordova[/lexicon] umbenannt. Bei Adobe Systems taucht es auch als Adobe [lexicon]PhoneGap[/lexicon] und Adobe [lexicon]PhoneGap[/lexicon] Build auf.

      Jar-Dateien sind eigentlich nur Container für Java-Klassen. Sollte uns nicht weiter interessieren.

      Diese „[lexicon]cordova[/lexicon]-2.9.0.jar“ kopiert ihr aus dem Windows-Explorer in Eclipse in den Package-Explorer und dort in das Verzeichnis „libs“ unseres Projektes. (in Eclipse rechte Maustaste auf „libs“ und auf „Paste“ klicken. Nun befindet sich unsere Jar-Datei, was unsere Brücke zwischen [lexicon]Javascript[/lexicon] und Java bildet,- unsere Funced-Bridge“, im Ordner „libs“. Unser Projekt kennt [lexicon]PhoneGap[/lexicon] allerdings immer noch nicht. Weiter geht’s.

      Zurück zum Windows-Explorer. Im Ordner woher wir auch unsere Jar-Datei herhaben befindet sich auch eine [lexicon]Javascript[/lexicon]-Datei: „[lexicon]cordova[/lexicon].[lexicon]js[/lexicon]“. Diese Datei kopiert ihr in unsere Spielwiese „assets“.

      Aber wir müssen zuvor noch mehrere Ordner erstellen!!!!!

      Hierfür klickt ihr mit der rechten Maustaste in Eclipse in unserem Package-Explorer auf das „assets“-Verzeichnis unseres Projektes, wählt „New -> Folder“. Im Textfeld „Folder name:“ gibt ihr „www“ ein und bestätigt es mit „Finish“. Im Package-Explorer wurde nun der Ordner „www“ in unserem „assets“-Ordner angelegt.

      Jetzt wiederholen wir den ganzen Kladderradatsch. Klickt nun mit der rechten Maustaste auf den eben erzeugten Ordner „www“ und über „New -> Folder“ legen wir noch die Verzeichnisse „lib/[lexicon]js[/lexicon]“ an. „lib“ bitte ohne s. Der „lib“-Ordner wird unsere Sammelstelle für unsere Ressourcen. „[lexicon]js[/lexicon]“ dürfte eigentlich klar sein. Hierin gehören unsere [lexicon]Javascript[/lexicon]-Dateien und die vorher kopierte „[lexicon]cordova[/lexicon].[lexicon]js[/lexicon]“. Fügt diese nun via „Paste“ in das „[lexicon]js[/lexicon]“-Verzeichnis ein. In „lib“ erstellen wir noch einen Ordner „[lexicon]css[/lexicon]“. Hier kommen unsere Stylesheet-Dateien rein und einen Ordner „img“ für unsere Bilddateien wie Backgrounds.

      Weiter geht's mit einer neuen Antwort, da die maximale Bildanzahl erreicht wurde.

      Dieser Beitrag wurde bereits 22 mal editiert, zuletzt von vtaker ()

    • Und weiter geht's:

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Der nächste Schritt liegt darin, unserem Projekt den Pfad von „[lexicon]cordova[/lexicon]-2.9.0.jar“ bekannt zu geben. Hierzu klickt ihr mit der rechten Maustaste auf „libs“ („nicht „lib“) und wählt dort „Build Path -> Configure Build Path“. In dem sich nun öffnenden Fenster wählt ihr auf der linken Seite „Java Build Path“ aus. Rechts oben auf dem Reiter „Libraries“ klicken. Da es sich bei unserer Jar-Bibliothek um eine externe handelt, klickt ihr rechts auf die Schaltfläche „Add External JARs…“. Hangelt euch nun zu eurem Projektverzeichnis (Workspace -> Anwendungsname). Bei mir wäre es C:\Benutzer\Mario(so, nun wisst ihr auch wie ich heiße)\workspace\AudioPlayer\libs. Dort finden wir unsere „[lexicon]cordova[/lexicon]-2.9.0.jar“, anklicken, auf öffnen klicken und zum Schluss auf „OK“ klicken.

      Jetzt klickt ihr mit der rechten Maustaste unser Wurzelverzeichnis (AudioPlayer) an und klickt auf „Refresh“. Damit aktualisieren wir unser Projekt und es ist nun mit [lexicon]PhoneGap[/lexicon] verheiratet.

      Das alleine reicht aber immer noch nicht. Die Ringe müssen noch an den Griffel genietet werden. Das macht die Sache um einiges glaubhafter! :) Jetzt müssen wir die bereits geöffnete „MainActivity.java“ ein wenig modifizieren.

      Im Code-Explorer finden wir als erstes den Package-Name

      Quellcode

      1. package com.example.audioplayer;


      Direkt darunter findet ihr eine Import-Anweisung und davor ein Pluszeichen. Klickt einmal drauf, so das das Plus zu Minus wird. Nun seht ihr alle Import-Anweisungen.

      Quellcode

      1. import android.support.v7.app.ActionBarActivity;
      2. import android.os.Bundle;
      3. import android.view.Menu;
      4. import android.view.MenuItem;


      Setzt nun euren Cursor direkt rechts neben der letzten Import-Anweisung (hinter das Semikolon), drückt die Enter-Taste, so das die Zeile umgebrochen wird. Dort fügt ihr folgende Anweisung hinzu:

      Quellcode

      1. import org.apache.cordova.*;


      Unterhalb der Imports befindet sich folgende Code-Zeile:

      Quellcode

      1. public class MainActivity extends ActionBarActivity {


      Ersetzt nun “ActionBarActivity” mit “DroidGap”.

      Quellcode

      1. public class MainActivity extends DroidGap {


      Darunter befinden sich folgende Code-Zeilen:

      Quellcode

      1. @Override
      2. protected void onCreate(Bundle savedInstanceState) {
      3. super.onCreate(savedInstanceState);
      4. setContentView(R.layout.activity_main); }


      Die Zeile „setContentView(R.layout.activity_main);“ überschreiben wir mit folgender Zeile:

      Quellcode

      1. super.loadUrl("file:///android_asset/www/index.html");


      So sollte es jetzt ausehen:

      Quellcode

      1. @Override
      2. protected void onCreate(Bundle savedInstanceState)
      3. {
      4. super.onCreate(savedInstanceState);
      5. super.loadUrl("file:///android_asset/www/index.html");
      6. }


      Als letzter Schritt muss das „protected“ in „public“ geändert werden.

      Speichert nun diese Datei über „File -> Save“ und refresht wie vorhin euer Projekt.

      Als vorletzten Schritt müssen wir noch die Berechtigungen für unsere App sowie die Orientierung, also auf das drehen unseres Handys, reagiert bzw. hinzugefügt werden. Dies geschieht in unserer „AndroidManifest.xml“-Datei.

      Ein Blick in unserem Package-Explorer verrät uns, das sich diese Datei im Ordner „res“ unseres Projektes befindet. Doppelt draufklicken und diese wird im Code-Explorer geöffnet.

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Diese Ansicht ist für uns wenig hilfreich. Also klicken wir unterhalb des Code-Explorers auf dem Reiter „AndroidManifest.xml“. Jetzt wird der pure XML-Code angezeigt.

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Setzt euren Cursor nun an das Ende des „<uses-sdk“-Block („/>“). Also vor dem „application“-Block.

      2 mal Enter drücken, um den Code schön übersichtlich zu gestalten. Fügt nun an dieser Stelle die Berechtigungen ein:

      Quellcode

      1. <supports-screens
      2. android:largeScreens="true"
      3. android:normalScreens="true"
      4. android:smallScreens="true"
      5. android:resizeable="true"
      6. android:anyDensity="true" />
      7. <uses-permission android:name="android.permission.VIBRATE" />
      8. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
      9. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      10. <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
      11. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
      12. <uses-permission android:name="android.permission.INTERNET" />
      13. <uses-permission android:name="android.permission.RECEIVE_SMS" />
      14. <uses-permission android:name="android.permission.RECORD_AUDIO" />
      15. <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
      16. <uses-permission android:name="android.permission.READ_CONTACTS" />
      17. <uses-permission android:name="android.permission.WRITE_CONTACTS" />
      18. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      19. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
      20. <uses-permission android:name="android.permission.GET_ACCOUNTS" />
      21. <uses-permission android:name="android.permission.BROADCAST_STICKY" />
      Alles anzeigen


      Wir haben hiermit unserer App erst einmal alle Rechte (Permissions) gegeben. Diese können wir zum Schluss des Workshops nach und nach entfernen, sofern diese Rechte nicht benötigt werden.

      Als nächstes fügen wir die Orientierung ein. Sucht euch im „application“-Block den „activity“-Block.

      Quellcode

      1. <activity
      2. android:name=".MainActivity"
      3. android:label="@string/app_name" >
      4. <intent-filter>


      Setzt euren Cursor direkt hinter das Ausrufezeichen von:

      Quellcode

      1. @string/app_name"


      Drückt die Enter-Taste und fügt folgenden Code hinzu:

      Quellcode

      1. android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"


      Eure Datei sollte nun wie folgt aussehen:

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Speichert nun diese Datei über „File -> Save“ und refresht euer Projekt.

      Ob ihr mir es glaubt oder nicht, das war es schon fast. Fast! Ein Blick in die Datei „MainActivity.java“ im Code-Explorer verrät uns, dass es nach einer „index.[lexicon]html[/lexicon]“ im „www“-Ordner schreit.

      Also erstellen wir diese kurzerhand. Beim Erstellen der „index.[lexicon]html[/lexicon]“, was unsere Homepage repräsentieren wird, sollte darauf geachtet werden, dass wir das HTML5 Format verwenden. Alle mobilen Browser-Engines kommen bestens mit dieses, noch sehr junges Format zurecht!!!!

      Ich benutze hierfür einen speziellen [lexicon]HTML[/lexicon]-Editor (Dreamweaver) wegen des hervorragenden Syntax Highlighting.

      Genauso gut können wir diese auch in Eclipse erstellen. Hierfür klickt ihr im Package-Explorer mit der rechten Maustaste auf dem Ordner „www“ und wählt „New -> File“. Gibt bei „File name:“ dort „index.[lexicon]html[/lexicon]“ ein und klickt auf „Finish“. Diese wird als Pfad im Code-Explorer dargestellt. Schließt diese Datei im Code-Explorer und klickt im „Package-Explorer“ mit der rechten Maustaste auf unsere „index.[lexicon]html[/lexicon]“. Sollte diese noch nicht erscheinen, einmal refreshen. Im Kontextmenü wählt ihr „Open With -> Text Editor“. Unsere noch leere „index.[lexicon]html[/lexicon]“ wird nun im Code-Explorer geöffnet und kann befüllt werden. Ich setzte mal voraus, dass ihr mit [lexicon]HTML[/lexicon] einigermaßen vertraut seit. Euer Grundgerüst sollte wie folgt aussehen:

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Im Header unterhalb des Titels fügen wir noch schnell folgende Code-Zeilen ein:

      Quellcode

      1. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      2. <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />


      Damit legen wir den Viewport fest. Jetzt müssen wir eine Referenz zu unserer [lexicon]Cordova[/lexicon]-[lexicon]Javascript[/lexicon]-Datei festlegen. Diese liegt in „lib/[lexicon]js[/lexicon]“.

      Quellcode

      1. <script type="text/javascript" charset="utf-8" src="lib/js/cordova.js"></script>


      Nun noch im Body Eine Überschrift der Größenordnung H1 mit einem äußerst sinnvollen Text:

      HTML-Quellcode

      1. <!doctype html>
      2. <html>
      3. <head>
      4. <meta charset="utf-8">
      5. <title>Unbenanntes Dokument</title>
      6. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      7. <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
      8. <script type="text/javascript" charset="utf-8" src="lib/js/cordova.js"></script>
      9. </head>
      10. <body>
      11. <h1>Hello World"</h1>
      12. </body>
      13. </html>
      Alles anzeigen


      Speichern, refreshen und fertig ist unser Projekt!

      So, meine lieben. Soviel für heute. Schritt 2, der erste Test und das hinzufügen von Plugins im [lexicon]Cordova[/lexicon]-Projekt präsentiere ich euch am Donnerstag Abend.


      Bis denne, Mario!

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von vtaker ()

    • Und weiter geht's:

      Hallo Freunde und Willkommen zurück zum 2. Teil unseres Workshops!


      Nachdem wir die Einrichtung unseres Projektes in [lexicon]Cordova[/lexicon] oder in [lexicon]PhoneGap[/lexicon] erfolgreich abgeschlossen haben, kommen wir zum ersten Test unseres Projekts.

      Ab hier stellt sich die Weiche wieder auf einem Gleis. Die Arbeitsweise, Syntax und Code ist bis auf geringe Abweichungen, auf die ich gesondert hinweisen werde, vollkommen identisch!

      Schritt 2: Das Kompilieren (Erzeugen) unseres Projekts


      Eines vorweg. Da wir auf die Media-Ressourcen des Endgerätes zugreifen und nicht auf einer Media-Ressource in unserem Projekt-Verzeichnis, testen wir unsere Anwendung von Anfang an direkt auf unserem Android-Handy. Dies würde in einem Emulator komplett scheitern!!!

      Verbindet hierfür via Datenkabel (Voraussetzung: alle Treiber für euer Gerät sind korrekt auf eurem Computer installiert) euer Handy mit euren Computer. Nachdem das Gerät erkannt wurde, aktiviert in eurem Gerät das USB-[lexicon]Debugging[/lexicon]!!! Diese Option findet ihr in der Regel unter Entwickler-Optionen. Schaut einfach in euer Handbuch, oder googelt entsprechend.

      Nachdem das Gerät erfolgreich erkannt wurde, ist es nun an der Zeit, unser Projekt zu testen.

      Jetzt trennen sich nochmals die Wege zwischen [lexicon]PhoneGap[/lexicon] und [lexicon]Cordova[/lexicon].

      Solltet ihr ein [lexicon]Cordova[/lexicon]-Projekt angelegt habt, öffnet ihr die [lexicon]CMD[/lexicon], wechselt mit dem Befehl „cd“ in euer Projektverzeichnis und kompiliert den ganzen Spaß erneut mit:

      [lexicon]cordova[/lexicon] build

      Das war auch schon der einzigste Unterschied zwischen [lexicon]Cordova[/lexicon] und [lexicon]PhoneGap[/lexicon]. Ab jetzt sind wieder alle Schritte identisch.

      Refresht nochmals euer Projekt. Und klickt nun mit der rechten Maustaste auf das Wurzelverzeichnis (AudioPlayer) und wählt „Run As -> Android Application“. Im sich nun öffnenden Fenster werden als erstes unser Handy angezeigt. Sollten Emulatoren eingerichtet worden sein, erscheinen diese deaktiviert darunter. Um die App auf unserem Gerät zu testen, sollte die Option „Choose a running Android Device“ aktiviert sein.

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Wie man oben unschwer erkennen kann, liegt bei meinem Gerät noch ein Problem vor. Das USB-[lexicon]Debugging[/lexicon] ist noch nicht aktiviert. Sollte es dennoch aktiviert sein, deaktiviert es kurz und schaltet es wieder zu. Alles zulassen, den Fingerprint akzeptieren und dann sollte es bei euch wie folgt aussehen:

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      Klickt nun auf eurem erkannten Endgerät und anschließend auf „OK“.

      Jetzt richten wir erwartungsvoll unsere Blicke auf euer Handy und nach wenigen Sekunden sollten wir den Beweis erbracht bekommen, dass unsere App tatsächlich funktioniert.

      In [lexicon]PhoneGap[/lexicon] erhalten wir folgenden Screen:

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      In [lexicon]Cordova[/lexicon] erhalten wir folgenden Screen:

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01


      OK. Staunen und sacken lassen bei einem Käffchen oder vielleicht auch ein Bier. Die Betonung liegt hierbei bei 1. Da wir noch nicht am Ziel unser Lektion sind, benötigen wir noch unsere geistigen Kräfte! :)

      Wenn ihr ein [lexicon]PhoneGap[/lexicon]-Projekt erzeugt hattet, könnt ihr euch für die nächsten 2 Schritte komplett zurücklehnen und überspringen, da diese nur ein [lexicon]Cordova[/lexicon]-Projekt betrifft.


      Schritt 3: Hinzufügen von Plugins ([lexicon]Cordova[/lexicon]-Projekt)


      Für unser Projekt benötigen wir natürlich auch Berechtigungen und dementsprechend auch einen Zugriff auf die dafür bereitgestellten API’s. Dies werden wir nun gemeinsam recht schnell abarbeiten.

      [lexicon]Cordova[/lexicon] hat gegenüber [lexicon]PhoneGap[/lexicon] den entscheidenden Vorteil, dass ein [lexicon]Cordova[/lexicon]-Projekt komplett „nackt“ erzeugt wird. Es basiert auf einem [lexicon]Plugin[/lexicon]-System. Dies spart Ressourcen am Endgerät. Man bindet also nur die API’s ein, die auch wirklich benötigt werden. Der Nachteil besteht darin, dass natürlich auch die entsprechenden Plugins vorhanden sein müssen, welche per [lexicon]Javascript[/lexicon]-Quellcode auch referenziert werden. Ein Zugriff auf das Dateisystem wird komplett fehlschlagen, wenn das [lexicon]Plugin[/lexicon] „FILESYSTEM“ fehlt.

      Auch die Projektseite von [lexicon]Cordova[/lexicon] ist hier zureichend dokumentiert und gehört als Favorit in unserem Browser als gespeichert.

      Cordova - Projekt

      Für unseren Audio Player benötigen wir den Zugriff auf das Dateisystem, sowie einen Zugriff auf das Mediasystem. Demzufolge benötigen wir das File-[lexicon]Plugin[/lexicon] und das Media-[lexicon]Plugin[/lexicon].

      Über den eben genannten Link gelangen wir nun zur Dokumentation des [lexicon]Cordova[/lexicon]-Projekts. Dort angekommen seht ihr auf der linken Seite einen Bereich Namens „API Reference“. Dort klickt ihr auf dem Unterbereich „[lexicon]Plugin[/lexicon] APIs“. Auf der rechten Seite findet ihr alle für [lexicon]Cordova[/lexicon] verfügbaren Plugins. Wir benötigen zum einem das FileSystem-[lexicon]Plugin[/lexicon] und zum anderm das Media-[lexicon]Plugin[/lexicon].

      Fangen wir mit dem File-[lexicon]Plugin[/lexicon] an.

      Sucht euch auf der rechten Seite in eurem Browser den Bereich „FileSystem“, klickt drauf und ihr landet direkt auf der entsprechenden [lexicon]Plugin[/lexicon]-Seite. Auf dieser Seite befindet sich ein Bereich „Install“. In der Regel ziemlich weit oben. Man muß schon etwas suchen. Einmal gefunden, wird man feststellen, dass dort nur eine einzige, nicht anklickbare Zeile, vorzufinden ist.

      [lexicon]cordova[/lexicon] [lexicon]plugin[/lexicon] add org.apache.[lexicon]cordova[/lexicon].file

      Dies allein genügt uns auch schon. Ein [lexicon]Cordova[/lexicon]-[lexicon]Plugin[/lexicon] binden wir in der Regel über die „[lexicon]CMD[/lexicon]“ ein.

      Kopiert euch also diese Zeile in die Zwischenablage und öffnet nun eure „[lexicon]CMD[/lexicon]“. Nochmals zur Erinnerung – Windows-Taste + R-Taste drücken und [lexicon]CMD[/lexicon] eingeben.

      Wechselt nun mit dem „cd“-Befehl in euer Projekt-Verzeichnis (AudioPlayer) und fügt dort den eben kopierten Befehl ein. Nur noch auf Enter drücken und unser [lexicon]Plugin[/lexicon] wird nun in unserem Projekt eingebunden.

      In Eclipse das Projekt erneut refreshen. Das war’s. Nun ist der Zugriff auf das Android-Datei-System gewährleistet. Analog macht ihr das selbe mit dem „Media-[lexicon]Plugin[/lexicon]“.

      In Eclipse alles refreshen.

      Möchtet ihr nun euer Projekt erneut testen, unbedingt darauf achten, das Projekt neu zu kompilieren (betrifft nur [lexicon]Cordova[/lexicon]-Projekte). Dies geschieht wie Eingangs schon beschrieben, über die „[lexicon]CMD[/lexicon]“. Das Projektverzeichnis aufrufen und „[lexicon]cordova[/lexicon] build“ aufrufen, das Projekt in Eclipse refreshen und über „Run As -> Android Application“ das Projekt erneut testen.

      Damit ist Schritt 3 komplett abgeschlossen. Ihr wisst nun, wie Plugins bereit gestellt werden.

      Unsere nächste Aufgabe, von den widerum [lexicon]PhoneGap[/lexicon]-Nutzer unbehelligt bleiben, ist das Erstellen eines „Blanko-Templates“.


      Zu Schritt 4 melde ich mich umgehend zurück. Sorry, aber solch ein umfassender Workshop benötigt Zeit.

      Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von vtaker ()

    • Hallo Freunde und Willkommen zurück zum 3. Teil unseres Workshops!

      Schritt 4: Erstellen eines Blanco-Templates (betrifft nur [lexicon]Cordova[/lexicon]-Projekt)

      Sicherlich ist einige Zeit vergangen, nur habe ich ebenfalls den alltäglichen Wahnsinn zu bewältigen. Wie auch immer, packen wir es an.

      Der 4. Schritt betrifft nur Leute, die ein [lexicon]Cordova[/lexicon]-Projekt wie oben beschrieben erzeugt hatten. Wir erstellen nun vielmehr ein „Blanko-Template“ (Schablone).

      Wie ihr nach dem kompilieren eures Projektes gesehen habt, bekommt ihr auf euer Handy nichts weiter zu sehen, als das animierte [lexicon]Cordova[/lexicon]-Logo. Das ist ja nicht das, was wir gebrauchen können. Also modifizieren wir jetzt unsere „Spielwiese“.

      Startet nun Eclipse und wartet bis alles geladen ist. Im Package-Explorer öffnet ihr jetzt euren Projektbaum, so das alle Dateien im Ordner „www“ zu sehen sind. Im „www“ Ordner befinden sich 3 Verzeichnisse: „[lexicon]css[/lexicon], img, [lexicon]js[/lexicon]“.

      Im [lexicon]CSS[/lexicon]-Verzeichnis befindet die sich von [lexicon]Cordova[/lexicon] erzeugte Standard-[lexicon]CSS[/lexicon]-Datei „index.[lexicon]css[/lexicon]“. Das „img“ Verzeichnis können wir völlig ignorieren, da wir das Logo ohnehin rausschmeißen. Im Ordner „[lexicon]js[/lexicon]“ befindet sich die [lexicon]Javascript[/lexicon]-Datei, die mit [lexicon]Cordova[/lexicon] automatisch angelegt wird.

      Wir werden die Datei „index.[lexicon]css[/lexicon]“, sowie „index.[lexicon]js[/lexicon]“ geringfügig modifizieren, so dass diese für unsere eigenen Zwecke verwendet werden können. Desweiterem modifizieren wir die „index.[lexicon]html[/lexicon]“, unsere Homepage, die als zentrale visuelle Schnittstelle dient. Wir finden diese direkt im „www“ Verzeichnis.


      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01

      Eines gleich vorweg. [lexicon]Cordova[/lexicon] erzeugt euch Crossplattform kompatible, völlig lauffähige Projekte. Von daher sollten Änderungen nur dort vorgenommen werden, wo diese auch wirklich notwendig sind.

      Hier gilt das Prinzip:

      Weniger ist mehr!!!!! Wir werden aber diesesmal radikale Änderungen vornehmen!!!

      Fangen wir mit der Index.[lexicon]HTML[/lexicon] an. Doppelt im Package-Explorer draufgeklickt und diese wird im Code-Explorer geöffnet.

      Stellt aber vorher sicher, dass diese als Textdatei geöffnet werden soll. Klickt hierfür mit der rechten Maustaste im Package-Explorer auf eure Index.[lexicon]html[/lexicon] und wählt unter „Open With -> Text Editor“ aus. Die Datei sollte jetzt geöffnet werden.

      Wie ihr am Doctype unschwer erkennen könnt, arbeiten wir im HTML5-Format. Es folgt eine Menge Kommentar. Dieser umfasst Lizenzbestimmungen.

      Es folgt der Header-Bereich. Hier wird unser Viewport festgelegt und die von [lexicon]Cordova[/lexicon] erzeugte [lexicon]CSS[/lexicon]-Datei eingebunden. Danach folgt, wie in jeder [lexicon]HTML[/lexicon]-Datei üblich der sichtbare Body-Bereich.

      [lexicon]Cordova[/lexicon] arbeitet analog wie Microsoft. Und zwar mit der Holzhammer-Methode. Wie ihr unschwer erkennen könnt, werden erst zum Schluss des Bodys die Referenzen zu unseren [lexicon]Javascript[/lexicon]-Bibliothen gesetzt. Man möchte mit dieser Methode sicherstellen, dass der gesamte DOM-Baum unserer Website komplett geladen ist. Ein Widerspruch, wie wir später sehen werden.

      Es gibt nämlich ein Handle Namens „onLoad und ondeviceready“ die das bestens sicherstellen können. Trotz alle dem, ist es kein Fehler, diese Scriptaufrufe am Ende des Bodys zu notieren.

      Hier die von [lexicon]Cordova[/lexicon] erzeugte index.[lexicon]html[/lexicon]:

      HTML-Quellcode

      1. <!DOCTYPE html>
      2. <!--
      3. Licensed to the Apache Software Foundation (ASF) under one
      4. or more contributor license agreements. See the NOTICE file
      5. distributed with this work for additional information
      6. regarding copyright ownership. The ASF licenses this file
      7. to you under the Apache License, Version 2.0 (the
      8. "License"); you may not use this file except in compliance
      9. with the License. You may obtain a copy of the License at
      10. http://www.apache.org/licenses/LICENSE-2.0
      11. Unless required by applicable law or agreed to in writing,
      12. software distributed under the License is distributed on an
      13. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      14. KIND, either express or implied. See the License for the
      15. specific language governing permissions and limitations
      16. under the License.
      17. -->
      18. <html>
      19. <head>
      20. <meta charset="utf-8" />
      21. <meta name="format-detection" content="telephone=no" />
      22. <meta name="msapplication-tap-highlight" content="no" />
      23. <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
      24. <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
      25. <link rel="stylesheet" type="text/css" href="css/index.css" />
      26. <title>Hello World</title>
      27. </head>
      28. <body>
      29. <div class="app">
      30. <h1>Apache Cordova</h1>
      31. <div id="deviceready" class="blink">
      32. <p class="event listening">Connecting to Device</p>
      33. <p class="event received">Device is Ready</p>
      34. </div>
      35. </div>
      36. <script type="text/javascript" src="cordova.js"></script>
      37. <script type="text/javascript" src="js/index.js"></script>
      38. </body>
      39. </html>
      Alles anzeigen


      Wir werden jetzt den body-Abschnitt radikal abändern. Siehe nachfolgenden Quelltext.

      HTML-Quellcode

      1. <!DOCTYPE html>
      2. <!--
      3. Licensed to the Apache Software Foundation (ASF) under one
      4. or more contributor license agreements. See the NOTICE file
      5. distributed with this work for additional information
      6. regarding copyright ownership. The ASF licenses this file
      7. to you under the Apache License, Version 2.0 (the
      8. "License"); you may not use this file except in compliance
      9. with the License. You may obtain a copy of the License at
      10. http://www.apache.org/licenses/LICENSE-2.0
      11. Unless required by applicable law or agreed to in writing,
      12. software distributed under the License is distributed on an
      13. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      14. KIND, either express or implied. See the License for the
      15. specific language governing permissions and limitations
      16. under the License.
      17. -->
      18. <html>
      19. <head>
      20. <meta charset="utf-8" />
      21. <meta name="format-detection" content="telephone=no" />
      22. <meta name="msapplication-tap-highlight" content="no" />
      23. <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
      24. <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
      25. <link rel="stylesheet" type="text/css" href="css/index.css" />
      26. <title>Hello World</title>
      27. </head>
      28. <body onLoad="load">
      29. Test
      30. <!--Euer Code-->
      31. <script type="text/javascript" src="cordova.js"></script>
      32. <script type="text/javascript" src="js/index.js"></script>
      33. </body>
      34. </html>
      Alles anzeigen


      Wie ihr erkennen önnt, ist vom Body nicht allzu viel übrig geblieben. Wir haben dem body-Tag ein „onLoad“-Ereignis hinzugefügt. Dieses soll sicherstellen, dass der gesamte DOM dieser Seite komplett geladen ist, sowie euer Gerät vollständig initialisiert wurde.

      Der Rest, wie Div’s und Absätze sind komplett rausgepflogen. Wir haben noch ein völlig sinnfreies Wort (Test) in den Body geschrieben, um gleich den [lexicon]CSS[/lexicon]-Reset zu überprüfen.

      Das war’s auch schon mit der index.[lexicon]html[/lexicon].

      Kommen wir nun zur index.[lexicon]css[/lexicon] Datei. Öffnet diese genauso wie die [lexicon]html[/lexicon]-Datei.

      Hier die index.[lexicon]css[/lexicon] wie sie von [lexicon]Cordova[/lexicon] erzeugt wurde:


      Quellcode

      1. /*
      2. * Licensed to the Apache Software Foundation (ASF) under one
      3. * or more contributor license agreements. See the NOTICE file
      4. * distributed with this work for additional information
      5. * regarding copyright ownership. The ASF licenses this file
      6. * to you under the Apache License, Version 2.0 (the
      7. * "License"); you may not use this file except in compliance
      8. * with the License. You may obtain a copy of the License at
      9. *
      10. * http://www.apache.org/licenses/LICENSE-2.0
      11. *
      12. * Unless required by applicable law or agreed to in writing,
      13. * software distributed under the License is distributed on an
      14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      15. * KIND, either express or implied. See the License for the
      16. * specific language governing permissions and limitations
      17. * under the License.
      18. */
      19. * {
      20. -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
      21. }
      22. body {
      23. -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
      24. -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
      25. -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
      26. background-color:#E4E4E4;
      27. background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
      28. background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
      29. background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
      30. background-image:-webkit-gradient(
      31. linear,
      32. left top,
      33. left bottom,
      34. color-stop(0, #A7A7A7),
      35. color-stop(0.51, #E4E4E4)
      36. );
      37. background-attachment:fixed;
      38. font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
      39. font-size:12px;
      40. height:100%;
      41. margin:0px;
      42. padding:0px;
      43. text-transform:uppercase;
      44. width:100%;
      45. }
      46. /* Portrait layout (default) */
      47. .app {
      48. background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
      49. position:absolute; /* position in the center of the screen */
      50. left:50%;
      51. top:50%;
      52. height:50px; /* text area height */
      53. width:225px; /* text area width */
      54. text-align:center;
      55. padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
      56. margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
      57. /* offset horizontal: half of text area width */
      58. }
      59. /* Landscape layout (with min-width) */
      60. @media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
      61. .app {
      62. background-position:left center;
      63. padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
      64. margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
      65. /* offset horizontal: half of image width and text area width */
      66. }
      67. }
      68. h1 {
      69. font-size:24px;
      70. font-weight:normal;
      71. margin:0px;
      72. overflow:visible;
      73. padding:0px;
      74. text-align:center;
      75. }
      76. .event {
      77. border-radius:4px;
      78. -webkit-border-radius:4px;
      79. color:#FFFFFF;
      80. font-size:12px;
      81. margin:0px 30px;
      82. padding:2px 0px;
      83. }
      84. .event.listening {
      85. background-color:#333333;
      86. display:block;
      87. }
      88. .event.received {
      89. background-color:#4B946A;
      90. display:none;
      91. }
      92. @keyframes fade {
      93. from { opacity: 1.0; }
      94. 50% { opacity: 0.4; }
      95. to { opacity: 1.0; }
      96. }
      97. @-webkit-keyframes fade {
      98. from { opacity: 1.0; }
      99. 50% { opacity: 0.4; }
      100. to { opacity: 1.0; }
      101. }
      102. .blink {
      103. animation:fade 3000ms infinite;
      104. -webkit-animation:fade 3000ms infinite;
      105. }
      Alles anzeigen


      Wir werden nun fast alles aus der [lexicon]CSS[/lexicon]-Datei schmeißen.

      Hier das was übrig bleibt:

      Brainfuck-Quellcode

      1. /*
      2. * Licensed to the Apache Software Foundation (ASF) under one
      3. * or more contributor license agreements. See the NOTICE file
      4. * distributed with this work for additional information
      5. * regarding copyright ownership. The ASF licenses this file
      6. * to you under the Apache License, Version 2.0 (the
      7. * "License"); you may not use this file except in compliance
      8. * with the License. You may obtain a copy of the License at
      9. *
      10. * http://www.apache.org/licenses/LICENSE-2.0
      11. *
      12. * Unless required by applicable law or agreed to in writing,
      13. * software distributed under the License is distributed on an
      14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      15. * KIND, either express or implied. See the License for the
      16. * specific language governing permissions and limitations
      17. * under the License.
      18. */
      19. /*----------------CSS Reset-----------------------------------------
      20. --------------------------------------------------------------------*/
      21. * {
      22. margin:0px;
      23. padding:0px;
      24. }
      25. /*-------------------------------------------------------------------
      26. --------------------------------------------------------------------*/
      Alles anzeigen


      Wahnsinn, nicht war… Das reicht uns für das erste aber schon.


      Als letztes öffnet ihr die index.[lexicon]js[/lexicon].

      Hier die von [lexicon]Cordova[/lexicon] erzeugte index.[lexicon]js[/lexicon]:

      Quellcode

      1. /*
      2. * Licensed to the Apache Software Foundation (ASF) under one
      3. * or more contributor license agreements. See the NOTICE file
      4. * distributed with this work for additional information
      5. * regarding copyright ownership. The ASF licenses this file
      6. * to you under the Apache License, Version 2.0 (the
      7. * "License"); you may not use this file except in compliance
      8. * with the License. You may obtain a copy of the License at
      9. *
      10. * http://www.apache.org/licenses/LICENSE-2.0
      11. *
      12. * Unless required by applicable law or agreed to in writing,
      13. * software distributed under the License is distributed on an
      14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      15. * KIND, either express or implied. See the License for the
      16. * specific language governing permissions and limitations
      17. * under the License.
      18. */
      19. var app = {
      20. // Application Constructor
      21. initialize: function() {
      22. this.bindEvents();
      23. },
      24. // Bind Event Listeners
      25. //
      26. // Bind any events that are required on startup. Common events are:
      27. // 'load', 'deviceready', 'offline', and 'online'.
      28. bindEvents: function() {
      29. document.addEventListener('deviceready', this.onDeviceReady, false);
      30. },
      31. // deviceready Event Handler
      32. //
      33. // The scope of 'this' is the event. In order to call the 'receivedEvent'
      34. // function, we must explicitly call 'app.receivedEvent(...);'
      35. onDeviceReady: function() {
      36. app.receivedEvent('deviceready');
      37. },
      38. // Update DOM on a Received Event
      39. receivedEvent: function(id) {
      40. var parentElement = document.getElementById(id);
      41. var listeningElement = parentElement.querySelector('.listening');
      42. var receivedElement = parentElement.querySelector('.received');
      43. listeningElement.setAttribute('style', 'display:none;');
      44. receivedElement.setAttribute('style', 'display:block;');
      45. console.log('Received Event: ' + id);
      46. }
      47. };
      48. app.initialize();
      Alles anzeigen


      Und hier unsere Modifikation:

      Quellcode

      1. /*
      2. * Licensed to the Apache Software Foundation (ASF) under one
      3. * or more contributor license agreements. See the NOTICE file
      4. * distributed with this work for additional information
      5. * regarding copyright ownership. The ASF licenses this file
      6. * to you under the Apache License, Version 2.0 (the
      7. * "License"); you may not use this file except in compliance
      8. * with the License. You may obtain a copy of the License at
      9. *
      10. * http://www.apache.org/licenses/LICENSE-2.0
      11. *
      12. * Unless required by applicable law or agreed to in writing,
      13. * software distributed under the License is distributed on an
      14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      15. * KIND, either express or implied. See the License for the
      16. * specific language governing permissions and limitations
      17. * under the License.
      18. */
      19. window.addEventListener('load', function () {
      20. document.addEventListener('deviceready', onDeviceReady, false);
      21. }, false);
      22. function onDeviceReady(){
      23. //Your Code
      24. };
      Alles anzeigen


      Durch die [lexicon]Script[/lexicon]-Aufrufe am Ende des Bodys stellen wir sicher, dass der DOM komplett geladen wurden. Das Event „load“ im Body-Tag stellt sicher, dass euer Gerät vollständig initialisiert wurde und steht euch innerhalb des Callbacks „onDeviceReady“ für den ersten Scriptaufruf ab sofort zu eurer Verfügung.

      Refresht nun in Eclipse euer Projekt. Kompiliert wie in den vorhergehenden [lexicon]Cordova[/lexicon]-Abschnitten bereits beschrieben über die [lexicon]CMD[/lexicon] erneut, schließt euer Handy an und startet euer Projekt.

      So sollte es auf eurem Handy jetzt aussehen:

      cordova-forum.de/index.php?att…ab8b0d7b16bb845634afddd01

      Ab dem nächsten Schritt gibt es für [lexicon]Cordova[/lexicon]-Projekte und [lexicon]PhoneGap[/lexicon]-Projekte keinen Unterschied mehr!!!!!

      Bis in Kürze!!!!

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von vtaker ()

    • Und weiter geht's:

      Hallo Freunde und Willkommen zurück zum 4. Teil unseres Workshops!

      Nachdem wir für unser [lexicon]Cordova[/lexicon]-Projekt ein Blanco-Template erstellt hatten, ist es nun an der Zeit, unsere externen Ressourcen einzubinden.

      Solltet ihr ein [lexicon]PhoneGap[/lexicon]-Projekt erzeugt haben, müsst ihr allerdings erst mal mit dem [lexicon]Cordova[/lexicon]-Projekt gleichziehen. Dies ist eigentlich schnell erledigt.

      Schritt 4.1: Erstellen der index.[lexicon]js[/lexicon], index.[lexicon]css[/lexicon] (betrifft nur [lexicon]PhoneGap[/lexicon]-Projekt)

      Startet euer Eclipse und öffnet unser Audio Player Projekt im Package-Explorer. Öffnet den Ordner „assets/www/lib“. Klickt nun mit der rechten Maustaste auf dem Ordner „[lexicon]js[/lexicon]“ und wählt „New -> File“. Tragt unter „File name“ index.[lexicon]js[/lexicon] ein und klickt auf Finish. Wir haben nun im Ordner [lexicon]js[/lexicon] zur [lexicon]cordova[/lexicon].[lexicon]js[/lexicon], die Datei index.[lexicon]js[/lexicon] erstellt. Wiederholt diesen Vorgang nun für die index.[lexicon]css[/lexicon]. Diese gehört in das [lexicon]css[/lexicon]-Verzeichnis.

      Nachdem beide Dateien erstellt worden sind, klickt ihr mit der rechten Maustaste als erstes auf die index.[lexicon]js[/lexicon]. Aus dem Kontextmenü wählt ihr „Open With -> Text Editor“. Diese Datei wird ab sofort als bearbeitbare Textdatei geöffnet. Beim nächstem mal, reicht ein Doppelklick auf diese Datei.

      Fügen wir nun schnell unsere erste Anweisung ein:

      Quellcode

      1. window.addEventListener('load', function () {
      2. document.addEventListener('deviceready', onDeviceReady, false);
      3. }, false);
      4. function onDeviceReady(){
      5. //Euer Code
      6. };


      Jetzt öffnen wir nach dem selben Prinzip unsere index.[lexicon]css[/lexicon] und fügen unseren Reset ein:

      Brainfuck-Quellcode

      1. @charset "utf-8";
      2. /* CSS Document */
      3. /*----------------CSS Reset-----------------------------------------
      4. --------------------------------------------------------------------*/
      5. * {
      6. padding: 0;
      7. margin: 0;
      8. }


      Alles speichern und das Projekt resetten.

      Jetzt öffnet ihr eure index.[lexicon]html[/lexicon] aus dem www-Verzeichnis.

      Bindet nun eure [lexicon]css[/lexicon] Datei im Header ein und fügt dem Body-Tag noch ein onLoad Ereignis zu. Anschließend bindet ihr eure [lexicon]Javascript[/lexicon] Datei am ende des Bodys ein:

      HTML-Quellcode

      1. <!doctype html>
      2. <html>
      3. <head>
      4. <meta charset="utf-8">
      5. <title>Unbenanntes Dokument</title>
      6. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      7. <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
      8. <link rel="stylesheet" href="lib/css/index.css" />
      9. <script type="text/javascript" charset="utf-8" src="lib/js/cordova.js"></script>
      10. </head>
      11. <body onLoad="load();">
      12. <h1>Hello World</h1>
      13. <script type="text/javascript" src="lib/js/index.js"></script>
      14. </body>
      15. </html>
      Alles anzeigen


      Alles speichern, refreshen, euer Handy anschließen und das Projekt starten.

      Somit ist unser [lexicon]PhoneGap[/lexicon]-Projekt mit dem [lexicon]Cordova[/lexicon]-Projekt gleichgezogen.

      Ab jetzt ist für [lexicon]Cordova[/lexicon] und [lexicon]PhoneGap[/lexicon] alles gleich!!!

      Schritt 5: Externe Ressourcen einbinden

      Bis jetzt sieht unser Projekt im Handy noch sehr traurig aus. Es reagiert zwar auf das kippen, mehr aber nicht. Es wird also Zeit, unserem Projekt etwas Design und Struktur zu verleihen.

      Was bietet sich da also an? Richtig, JQuery und JQuery Mobile. Diese Frameworks müssen wir uns erst einmal besorgen und in unserem Projekt einbinden.

      Das JQuery [lexicon]Framework[/lexicon] bekommt ihr hier.

      Dort angekommen ladet ihr euch, aber Achtung, mit der rechten Maustaste und Ziel speichern unter die Version 1.11.2 in der komprimierten Version herunter. (Download the compressed, production jQuery 1.11.2) Ladet euch auch, diese allerdings mit Linksklick, die dazugehörige Map-Datei. (Download the map file for jQuery 1.11.2)

      Kopiert nun beide Dateien in das [lexicon]js[/lexicon]-Verzeichnis eures Projektes. Öffnet nun eure index.[lexicon]html[/lexicon] und referenziert die jquery-1.11.2.min.[lexicon]js[/lexicon] genau unter der Referenz von [lexicon]cordova[/lexicon].[lexicon]js[/lexicon].

      Quellcode

      1. <script src="lib/js/jquery-1.11.2.min.js"></script>


      Projekt refreshen!!!

      Besorgen wir uns nun das JQuery Mobile [lexicon]Framework[/lexicon] und binden es an der richtigen Stelle ein.

      JQuery Mobile bekommt ihr hier.

      Auf der rechten Seite bekommt ihr ganz oben den Download angeboten. Ladet euch die Lasted Stable runter. Dies ist die Version 1.4.5. Entpackt das Paket nun. Wir müssen jetzt einiges in unser Projekt kopieren.

      Als erstes kopiert ihr die Dateien jquery.mobile-1.4.5.min.[lexicon]js[/lexicon] und jquery.mobile-1.4.5.min.map in euer [lexicon]js[/lexicon]-Verzeichnis. Im nächstem Schritt legen wir im Ordner [lexicon]css[/lexicon] ein neues Verzeichnis an. In Eclipse Rechtsklick auf [lexicon]css[/lexicon] und im Kontextmenü „New -> Folder“ auswählen. Unter „Folder name“ gibt ihr themes/default ein und bestätigt das Ganze mit Finish.

      Öffnet nun den [lexicon]css[/lexicon]-Baum weiter, bis auch default geöffnet ist. In den Ordner default kopiert ihr euch alle [lexicon]css[/lexicon]-Dateien von JQuery Mobile, die mit „.min.[lexicon]css[/lexicon]“ enden. Es sollten 7 Dateien sein. Wechselt nun wieder in das Verzeichnis wo ihr JQuery Mobile entpackt hattet. Dort kopiert ihr euch den Ordner images in das default-Verzeichnis, wo auch schon unsere [lexicon]css[/lexicon]-Dateien drin sind.

      Damit haben wir alle Ressourcen zusammen. Was nun folgt, ist das referenzieren unserer externen Ressourcen in unserer index.[lexicon]html[/lexicon].

      Wir haben im Header unserer index.[lexicon]html[/lexicon] bereits unsere index.[lexicon]css[/lexicon] referenziert. Unsere jquery.mobile-1.4.5.min.[lexicon]css[/lexicon], die ja im default-Ordner liegt, referenzieren wir genau darüber. Dies ist nicht willkürlich gewählt, sondern hat einen Grund! Das Stylsheet des Frameworks muß vor eigenen [lexicon]css[/lexicon] gestellt werden!

      Fügen wir diese also ein (achtet auf den Pfad zur Datei):

      Quellcode

      1. <link rel="stylesheet" href="css/themes/default/jquery.mobile-1.4.5.min.css">


      Fügen wir noch zu guter letzt die jquery.mobile-1.4.5.min.[lexicon]js[/lexicon] in unserer index.[lexicon]html[/lexicon] ein. Diese referenzieren wir genau unter der jquery-1.11.2.min.[lexicon]js[/lexicon] ein. Erst muß JQuery geladen werden, erst danach JQuery Mobile. Und erst danach wird unsere index.[lexicon]js[/lexicon] referenziert.

      Quellcode

      1. <script src="js/jquery.mobile-1.4.5.min.js"></script>


      Alles speichern und nochmals refreshen. Unsere externen Dateien sind somit eingebunden.

      Jetzt kommt Struktur in unsere index.[lexicon]html[/lexicon].

      Bis jetzt sollte unsere index.[lexicon]html[/lexicon] wie folgt aussehen ([lexicon]PhoneGap[/lexicon] minimale Abweichungen):

      HTML-Quellcode

      1. <!DOCTYPE html>
      2. <html>
      3. <head>
      4. <meta charset="utf-8" />
      5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      6. <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
      7. <link rel="stylesheet" href="css/themes/default/jquery.mobile-1.4.5.min.css">
      8. <link rel="stylesheet" type="text/css" href="css/index.css" />
      9. <title>Audio Player</title>
      10. </head>
      11. <body onLoad="load">
      12. <p>Test</p>
      13. <script type="text/javascript" src="cordova.js"></script>
      14. <script src="js/jquery-1.11.2.min.js"></script>
      15. <script src="js/jquery.mobile-1.4.5.min.js"></script>
      16. <script type="text/javascript" src="js/index.js"></script>
      17. </body>
      18. </html>
      Alles anzeigen


      Besorgen wir uns noch schnell ein passenden Background (Hintergrundbild) für unsere index.[lexicon]html[/lexicon]. Diese jpg-Datei gehört in euer img-Verzeichnis.

      Da wir mit dem JQuery Mobile [lexicon]Framework[/lexicon] arbeiten, ist es uns möglich, mehrere Webseiten in einer einzigen Webseite, also unsere index.[lexicon]html[/lexicon], unterzubringen. Dies funktioniert über das Attribut „data-role“.

      Ich gehe mal davon aus, dass eure index.[lexicon]html[/lexicon] nach wie vor geöffnet ist. Okay. Im Body befindet sich noch das überflüssige Wort „Test“. In euer [lexicon]PhoneGap[/lexicon]-Projekt war es eine H1-Überschrift „Hello World“. Dies löscht ihr mal schleunigst aus eure Datei und fügt stattdessen einen Div-Container ein. Dieser erhält die ID „home“ und repräsentiert unsere Startseite. Nachdem ihr die ID vergeben habt, setzten wir das Attribut „data-role“ und vergeben als Wert „page“ (Seite). Danach legen wir ein Thema fest. Dies geschieht mit dem Attribut „data-theme“ und als Wert vergeben wir „b“. Das ist ein schickes Schwarz. Zum Schluß noch unseren Background festlegen.

      Das Ganze sollte dann so aussehen:

      HTML-Quellcode

      1. <!DOCTYPE html>
      2. <html>
      3. <head>
      4. <meta charset="utf-8" />
      5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      6. <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
      7. <link rel="stylesheet" href="css/themes/default/jquery.mobile-1.4.5.min.css">
      8. <link rel="stylesheet" type="text/css" href="css/index.css" />
      9. <title>Audio Player</title>
      10. </head>
      11. <body onLoad="load">
      12. <div id="home" data-role="page" data-theme="b" style="background:url(img/EVE_Online.jpg) no-repeat fixed;">
      13. </div>
      14. <script type="text/javascript" src="cordova.js"></script>
      15. <script src="js/jquery-1.11.2.min.js"></script>
      16. <script src="js/jquery.mobile-1.4.5.min.js"></script>
      17. <script type="text/javascript" src="js/index.js"></script>
      18. </body>
      19. </html>
      Alles anzeigen


      Schon haben wir unsere Startseite. Naja, noch nicht ganz. Es fehlt noch der Kopf, der Content und der Fußbereich.

      Nach dem selben Prinzip erstellen wir unsere Bibliothek-Seite. Vielleicht mit einem anderen Background.

      HTML-Quellcode

      1. <!DOCTYPE html>
      2. <html>
      3. <head>
      4. <meta charset="utf-8" />
      5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      6. <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
      7. <link rel="stylesheet" href="css/themes/default/jquery.mobile-1.4.5.min.css">
      8. <link rel="stylesheet" type="text/css" href="css/index.css" />
      9. <title>Audio Player</title>
      10. </head>
      11. <body onLoad="load">
      12. <!--------------Home - Seite---------------------->
      13. <div id="home" data-role="page" data-theme="b" style="background:url(img/EVE_Online.jpg) no-repeat fixed;">
      14. </div>
      15. <!--------------Bibliothek - Seite---------------------->
      16. <div id="bibliothek" data-role="page" data-theme="b" style="background:url(lib/img/Abstract-Wave-Color-Light-Background-Vector.jpg) no-repeat fixed;">
      17. </div>
      18. <script type="text/javascript" src="cordova.js"></script>
      19. <script src="js/jquery-1.11.2.min.js"></script>
      20. <script src="js/jquery.mobile-1.4.5.min.js"></script>
      21. <script type="text/javascript" src="js/index.js"></script>
      22. </body>
      23. </html>
      Alles anzeigen


      Für dem User ist es nachher so, als würde eine neue Seite geöffnet werden.

      Legen wir nun mal den Kopfbereich unserer Home-Seite an.

      Ich habe hier nur mal einen Ausschnitt unserer „Home-Seite“ bereitgestellt:

      Brainfuck-Quellcode

      1. <!--------------Home - Seite---------------------->
      2. <div id="home" data-role="page" data-theme="b" style="background:url(lib/img/EVE_Online.jpg) no-repeat fixed;">
      3. <header data-role="header" data-position="fixed">
      4. <div data-role="navbar">
      5. <ul>
      6. <li><a href="#" data-icon="home" data-iconpos="right">HOME</a></li>
      7. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      8. <li><a href="#" data-icon="power" data-iconpos="right">BEENDEN</a></li>
      9. </ul>
      10. </div>
      11. </header>
      12. </div>
      Alles anzeigen


      Wir haben hier einen Header-Bereich definiert und darin eine Navbar gelegt. Darin eine ungeordnete Liste. Das alles redert unser [lexicon]Framework[/lexicon] fein säuberlich in eine schicke Navbar. Und die Verlinkung zur Bibliothek-Seite funktioniert auch schon.

      Speichert jetzt alles, refresht euer Projekt nochmal. [lexicon]Cordova[/lexicon]-Projekte müssen jetzt nochmal über die [lexicon]CMD[/lexicon] mit dem Befehl [lexicon]cordova[/lexicon] build erneut kompiliert werden. Schließt euer Handy an, nochmals refreshen und das Projekt starten.

      Wir werden nun unsere erste Funktion schreiben. Diese soll sich um das Beenden unserer App kümmern. Wer unsere App bereits getestet hat, dem ist aufgefallen, dass wir im Kopfbereich eine Navbar mit 3 Schaltflächen eingefügt haben. Die rechte Schaltfläche trägt als Wert „Beenden“. Dieser werden wir ein onClick Ereignis hinzufügen.

      In eurer fügt ihr in dem Listenelement mit dem Wert Beenden ein onClick Ereignis zu:

      Brainfuck-Quellcode

      1. <!--------------Home - Seite---------------------->
      2. <div id="home" data-role="page" data-theme="b" style="background:url(img/EVE_Online.jpg) no-repeat fixed;">
      3. <header data-role="header" data-position="fixed">
      4. <div data-role="navbar">
      5. <ul>
      6. <li><a href="#" data-icon="home" data-iconpos="right">HOME</a></li>
      7. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      8. <li><a href="#" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      9. </ul>
      10. </div>
      11. </header>
      12. </div>
      Alles anzeigen


      Öffnet nun eure index.[lexicon]js[/lexicon]. Dies ist unser Ausgangspunkt für unsere Scripte. Im Callback onDeviceReady nehmen wir unseren ersten Funktionsaufruf vor. Da man allerdings davon ausgehen kann, das alles bereits initialisiert wurde, werden wir unsere Beenden-Funktion darunter schreiben.

      Quellcode

      1. // JavaScript Document
      2. window.addEventListener('load', function () {
      3. document.addEventListener('deviceready', onDeviceReady, false);
      4. }, false);
      5. function onDeviceReady(){
      6. //Euer Code
      7. };
      8. function beenden(){
      9. if(navigator.app)
      10. {
      11. navigator.app.exitApp();
      12. }
      13. else if(navigator.device)
      14. {
      15. navigator.device.exitApp();
      16. }
      17. }
      Alles anzeigen


      Speichert jetzt alles, refresht euer Projekt nochmal. [lexicon]Cordova[/lexicon]-Projekte müssen jetzt nochmal über die [lexicon]CMD[/lexicon] mit dem Befehl [lexicon]cordova[/lexicon] build erneut kompiliert werden. Schließt euer Handy an, nochmals refreshen und das Projekt starten.

      Ab sofort können wir unsere App über die entsprechende Schaltfläche beenden. Alle Ressourcen werden wieder freigegeben.

      So Leute. Ich schließe für heute dieses Tutorial und setzte diesen Schritt in Kürze fort.

      Bis später,

      Mario

      Dieser Beitrag wurde bereits 27 mal editiert, zuletzt von vtaker ()

    • Hallo Freunde und Willkommen zurück zum 4. Teil unseres Workshops!

      Schritt 5: Unsere index.[lexicon]html[/lexicon] (Fortsetzung)

      Nachdem wir 2 Seiten in unserer index.[lexicon]html[/lexicon] erstellt hatten und auch schon unsere erste Javascriptfunktion geschrieben hatten, wird es nun langsam Zeit, unsere index.[lexicon]html[/lexicon] zu vervollständigen.

      Öffnet in Eclipse eure index.[lexicon]html[/lexicon] und fügt in unserer „Home-Seite“ unterhalb des Header-Bereiches, den wir schon in der vorherigen Sitzung erstellt hatten, einen Div hinzu. Dies wird unser Content (der Hauptbereich). Hier bringen wir auch unseren Player unter, der aber vorerst versteckt, also via [lexicon]CSS[/lexicon] auf Hidden gesetzt wird.

      Da wir mit JQuery Mobile arbeiten, gibt es auch hier ein passendes „data-role“ Attribut. Nämlich „content“.

      Abbildung unserer Home-Seite:

      Brainfuck-Quellcode

      1. <!--------------Home - Seite---------------------->
      2. <div id="home" data-role="page" data-theme="b" style="background:url(lib/img/EVE_Online.jpg) no-repeat fixed;">
      3. <header data-role="header" data-position="fixed">
      4. <div data-role="navbar">
      5. <ul>
      6. <li><a href="#" data-icon="home" data-iconpos="right">HOME</a></li>
      7. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      8. <li><a href="#" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      9. </ul>
      10. </div>
      11. </header>
      12. <div data-role="content">
      13. </div>
      14. </div>
      Alles anzeigen


      Innerhalb dieses Content-Bereiches legt ihr einen weiteren Div an und vergibt diesem eine ID mit den Namen „home_inhalt“.

      Innerhalb dieses Div’s fügt ihr 2 versteckte Textfelder ein. Hierbei ist es wichtig, das diese auch später aus dem [lexicon]Script[/lexicon] angesprochen werden können. Also vergeben wir beide versteckte Textfelder einen Namen und eine ID. Den Sinn und Zweck des ganzen, erkläre ich euch später.

      Das erste Feld bekommt die ID und den Namen: „automatik_play“ und setzt den Anfangswert auf 0.

      Das zweite Feld bekommt die ID und den Namen: „player_status“ und setzt ebenfalls den Anfangswert auf 0.

      Anschließend fügen wir ein Paragraph (<p> Tag) für unsere Status-Ausgabe ein. Dieser bekommt die ID „home_meldung“. Setzt diesen auf zentriert (align=“center“). Als Starttext definieren wir: „Synchronisierung läuft.“. Es folgen zwei Zeilenumbrüche (<br /><br />) und geben in Folge „Bitte warten…“ ein. Jetzt schließen wir den Paragraphen.

      Stand der Dinge:

      Quellcode

      1. <div data-role="content">
      2. <div id="home_inhalt">
      3. <input name="automatik_play" type="hidden" id="automatik_play" value="0">
      4. <input name="player_status" type="hidden" id="player_status" value="0">
      5. <p id="home_meldung" align="center">Synchronisierung läuft.<br /><br />Bitte warten...</p>
      6. </div>
      7. </div>


      Gefolgt von einem Zeilenumbruch, Legt ihr wieder einen Paragraph an, vergibt diesem die ID „aktueller_titel“ und zentriert diesen. Hier wird kein Startwert festgelegt, da dieser noch unsichtbar sein soll. In diesem Paragraphen lassen wir uns den aktuell laufenden Titel anzeigen.

      Und wieder ein Zeilenumbruch.

      Jetzt kommen wir zum Player, also das visuelle Teil vom ganzem. Der soll Eingangs unsichtbar sein.

      Legt hierfür einen Div-Container an. Dieser soll auf die ID „aktueller_player“ lauschen, zentriert sein und legt eine Stylesheetanweisung Namens „display“ an, dessen Wert wir auf „none“ setzen. Damit stellen wir sicher, das unser Player Eingangs unsichtbar ist.

      In unserem Player soll folgendes vorhanden sein:
      • Eine Trackbar (zur Anzeige der aktuellen Position und zum reinspringen an einer bestimmten Stelle im Titel)
      • Die Zurück-Schaltfläche
      • Die Pause/Play-Schaltfläche
      • Die Stop-Schaltfläche
      • Die Next-Schaltfläche
      • Die Loop-Schaltfläche (für die Endloswiedergabe)
      • Die Favoriten-Schaltfläche (zum Hinzufügen zur Favoritenliste)
      • Anzeige der Gesamtlänge
      • Anzeige der aktuellen Position

      Fangen wir also an. Als erstes wird unser Slider eingebaut.

      Ein Range wurde erstmals mit [lexicon]HTML[/lexicon] 5 ausgeliefert und ermöglicht es, diverse Werte in Form eines Sliders anzupassen.

      Legt euch einen Div-Container mit der ID „slider“ an. Innerhalb dieses Containers fügen wir ein Range-Slider ein. Als Namen und ID vergibt ihr „time-slider“. Der aktuelle Wert beträgt numerisch 0. Der minimale Wert beträgt ebenfalls 0. Der maximale Wert beträgt 100. Anschließend setzen wir noch ein nettes Feature von JQuery Mobile ein: Das Attribut „data-highlight“ dessen Wert (boolscher Wert, – also wahr(true) oder unwahr(false)), wahr also „true“ sein soll. Da ein Range-Slider noch ein Eingabefeld besitzt, was wir in unserem Falle nicht benötigen, setzten wir noch eine JQuery Mobile Klasse: class="ui-hidden-accessible". Zum Schluß bekommt dieser Slider, damit dieser auch was zu tun hat, noch ein onChange Ereignis. Dieses nennen wir einfach „sprung“. Wir wollen ja über diesen Slider später im Titel hin und her springen können.

      Nach unserem Div-Container mit der ID „slider“ legen wir uns einen weiteren Div-Container an. Hier vergeben wir als „data-role“ das „controlgroup“ und setzten als „data-type“ den Wert „horizontal“.

      Wir haben hiermit eine Gruppe von Schaltflächen definiert, die sich in einer Gruppe befinden und horizontal angeordnet werden. Dies wird unsere Player-Navigation.

      Innerhalb dieses Div’s setzt ihr 6 Links.

      Nachdem Div folgt ein Zeilenumbruch.

      Jetzt noch 2 Paragraphen und noch ein Div was eine [lexicon]CSS[/lexicon]-Klasse erhält, die wir gleich definieren.

      Und da das jetzt einfach zuviel auf einen Haufen war, hier der gesamte Block:

      Quellcode

      1. <div data-role="content">
      2. <div id="home_inhalt">
      3. <input name="automatik_play" type="hidden" id="automatik_play" value="0">
      4. <input name="player_status" type="hidden" id="player_status" value="0">
      5. <p id="home_meldung" align="center">Synchronisierung läuft.<br /><br />Bitte warten...</p>
      6. <br />
      7. <p id="aktueller_titel" align="center"></p>
      8. <br />
      9. <div id="aktueller_player" align="center" style="display:none;">
      10. <div id="slider">
      11. <input type="range" name="time-slider" id="time-slider" value="0" min="0" max="100" data-highlight="true" class="ui-hidden-accessible" onChange="sprung();" />
      12. </div>
      13. <div data-role="controlgroup" data-type="horizontal">
      14. <a href="#" id="schalter_previous" data-role="button" onClick="previousAudio();">|<<</a>
      15. <a href="#" id="schalter_pause" data-role="button" onClick="pauseAudio();">||</a>
      16. <a href="#" id="schalter_stop" data-role="button" onClick="stopAudio();">X</a>
      17. <a href="#" id="schalter_next" data-role="button" onClick="nextAudio();">>>|</a>
      18. <a href="#" id="schalter_loop" data-role="button" data-icon="refresh" data-iconpos="notext" onClick="loopAudio();">&nbsp;</a>
      19. <a href="#" id="schalter_favorit" data-role="button" data-icon="star" data-iconpos="notext" onClick="favoritAudio();">&nbsp;</a>
      20. </div>
      21. <br>
      22. <p id="gesamt_laenge"></p>
      23. <p id="aktuelle_position"></p>
      24. <div class="clearfloat"></div>
      25. </div>
      26. </div>
      27. </div>
      Alles anzeigen


      Zum Schluß unserer Homeseite, definieren wir noch schnell einen Footer. Den werde ich nun nicht mehr weiter dokumentieren.

      Hier nun unsere gesamte Home-Seite:


      Brainfuck-Quellcode

      1. <!--------------Home - Seite---------------------->
      2. <div id="home" data-role="page" data-theme="b" style="background:url(img/EVE_Online.jpg) no-repeat fixed;">
      3. <header data-role="header" data-position="fixed">
      4. <div data-role="navbar">
      5. <ul>
      6. <li><a href="#" data-icon="home" data-iconpos="right">HOME</a></li>
      7. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      8. <li><a href="#" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      9. </ul>
      10. </div>
      11. </header>
      12. <div data-role="content">
      13. <div id="home_inhalt">
      14. <input name="automatik_play" type="hidden" id="automatik_play" value="0">
      15. <input name="player_status" type="hidden" id="player_status" value="0">
      16. <p id="home_meldung" align="center">Synchronisierung läuft.<br /><br />Bitte warten...</p>
      17. <br />
      18. <p id="aktueller_titel" align="center"></p>
      19. <br />
      20. <div id="aktueller_player" align="center" style="display:none;">
      21. <div id="slider">
      22. <input type="range" name="time-slider" id="time-slider" value="0" min="0" max="100" data-highlight="true" class="ui-hidden-accessible" onChange="sprung();" />
      23. </div>
      24. <div data-role="controlgroup" data-type="horizontal">
      25. <a href="#" id="schalter_previous" data-role="button" onClick="previousAudio();">|<<</a>
      26. <a href="#" id="schalter_pause" data-role="button" onClick="pauseAudio();">||</a>
      27. <a href="#" id="schalter_stop" data-role="button" onClick="stopAudio();">X</a>
      28. <a href="#" id="schalter_next" data-role="button" onClick="nextAudio();">>>|</a>
      29. <a href="#" id="schalter_loop" data-role="button" data-icon="refresh" data-iconpos="notext" onClick="loopAudio();"> </a>
      30. <a href="#" id="schalter_favorit" data-role="button" data-icon="star" data-iconpos="notext" onClick="favoritAudio();"> </a>
      31. </div>
      32. <br>
      33. <p id="gesamt_laenge"></p>
      34. <p id="aktuelle_position"></p>
      35. <div class="clearfloat"></div>
      36. </div>
      37. </div>
      38. </div>
      39. <div id="footer" data-role="footer" data-position="fixed" align="center">
      40. <a href="#" data-role="button" data-transition="flip" data-icon="info" data-iconpos="right" data-iconshadow="true">Info</a>
      41. </div>
      42. </div>
      Alles anzeigen


      Speichert jetzt alles, refresht euer Projekt nochmal. [lexicon]Cordova[/lexicon]-Projekte müssen jetzt nochmal über die [lexicon]CMD[/lexicon] mit dem Befehl [lexicon]cordova[/lexicon] build erneut kompiliert werden. Schließt euer Handy an, nochmals refreshen und das Projekt starten.

      Nachdem ihr in etwa wisst, wie ihr mit HTML5 und JQuery Mobile mehrere Seiten in einer schreibt, kommentiere ich die Bibliothek_seite nicht weiter. Es ist auch für mich sehr aufwendig alles einzeln zu dokumentieren.

      Solltet ihr nicht weiterkommen, postet einfach. Ich helfe dann gern.

      Hier unsere gesamte Bibliothek-Seite innerhalb unserer index.[lexicon]html[/lexicon] (übernehmt diese 1:1):

      Brainfuck-Quellcode

      1. <!--------------Bibliothek - Seite---------------------->
      2. <div id="bibliothek" data-role="page" data-theme="b" style="background:url(lib/img/Abstract-Wave-Color-Light-Background-Vector.jpg) no-repeat fixed;">
      3. <header data-role="header" data-position="fixed">
      4. <div data-role="navbar">
      5. <ul>
      6. <li><a href="#home" data-transition="flip" data-icon="home" data-iconpos="right">HOME</a></li>
      7. <li><a href="#" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      8. <li><a href="#" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      9. </ul>
      10. </div>
      11. </header>
      12. <div data-role="content">
      13. <div id="bibliothek_inhalt">
      14. <a href="#alledateien" data-role="button" data-transition="flip" onClick="alleDateienlisten();">Alle Audio-Dateien</a>
      15. <a href="#letztewiedergabe" data-role="button" data-transition="flip" onClick="letzeWiedergabeListeAuflisten();">Zuletzt wiedergegeben</a>
      16. <a href="#favoriten" data-role="button" data-transition="flip" onClick="FavoritenListeAuflisten();">Meine Favoriten</a>
      17. <a href="#" data-role="button" data-transition="flip" onClick="reset_sync2();">Erneut synchronisieren</a>
      18. <a href="#" data-role="button" data-transition="flip" onClick="table_delete();">Zuletzt wiedergegeben leeren</a>
      19. </div>
      20. </div>
      21. <div id="footer" data-role="footer" data-position="fixed" align="center">
      22. <a href="#" data-role="button" data-transition="flip" data-icon="info" data-iconpos="right" data-iconshadow="true">Info</a>
      23. </div>
      24. </div>
      Alles anzeigen


      Wie ihr auf der Bibliothek-Seite unschwer erkennen könnt, gibt es hier Links zu weiteren Seiten. Die werden wir, ihr, jetzt schnell erstellen. Auch wird euch aufgefallen sein, das ich schon sehr viel Funktionsaufrufe eingebaut habe. Diese werden wir in den nächsten Schritten vornehmen.

      Der erste Link auf der Bibliotheks-Seite führt uns auf die Seite, wo uns alle Audio-Dateien aufgelistet werden sollen. Übernehmt diese wieder 1:1.

      Hier unsere Seite für alle Dateien:

      Brainfuck-Quellcode

      1. <!--------------alle Dateien - Seite---------------------->
      2. <div id="alledateien" data-role="page" data-theme="b">
      3. <header data-role="header" data-position="fixed">
      4. <div data-role="navbar">
      5. <ul>
      6. <li><a href="#home" data-transition="flip" data-icon="home" data-iconpos="right">HOME</a></li>
      7. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      8. <li><a href="" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      9. </ul>
      10. </div>
      11. </header>
      12. <div data-role="content">
      13. <h3 id="anzahl_titels" align="center"></h3>
      14. <div id="alleDateien_inhalt">
      15. <ul id="file-listings"></ul>
      16. </div>
      17. </div>
      18. <div id="footer" data-role="footer" data-position="fixed" align="center">
      19. <a href="#" data-role="button" data-transition="flip" data-icon="info" data-iconpos="right" data-iconshadow="true">Info</a>
      20. </div>
      21. </div>
      Alles anzeigen


      Auch haben wir eine Seite für die zuletzt wiedergegebenen Titel festgelegt.

      Hier unsere Seite für die zuletzt wiedergegebenen Titel:

      Brainfuck-Quellcode

      1. <!--------------letzte Wiedergabe - Seite---------------------->
      2. <div id="letztewiedergabe" data-role="page" data-theme="b">
      3. <header data-role="header" data-position="fixed">
      4. <div data-role="navbar">
      5. <ul>
      6. <li><a href="#home" data-transition="flip" data-icon="home" data-iconpos="right">HOME</a></li>
      7. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      8. <li><a href="" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      9. </ul>
      10. </div>
      11. </header>
      12. <div data-role="content">
      13. <h3 id="anzahl_titel_letzte_wiedergabe" align="center"></h3>
      14. <div id="letzte_wiedergaben_inhalt">
      15. <ul id="file-listing-letzte-wiedergabe"></ul>
      16. </div>
      17. </div>
      18. <div id="footer" data-role="footer" data-position="fixed" align="center">
      19. <a href="#" data-role="button" data-transition="flip" data-icon="info" data-iconpos="right" data-iconshadow="true">Info</a>
      20. </div>
      21. </div>
      Alles anzeigen


      Und schlussendlich haben wir noch eine Seite für unsere Favoriten-Liste.

      Hier unsere Seite für unsere Favoriten-Liste:

      Brainfuck-Quellcode

      1. <!--------------meine Favoriten - Seite---------------------->
      2. <div id="favoriten" data-role="page" data-theme="b">
      3. <header data-role="header" data-position="fixed">
      4. <div data-role="navbar">
      5. <ul>
      6. <li><a href="#home" data-transition="flip" data-icon="home" data-iconpos="right">HOME</a></li>
      7. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      8. <li><a href="" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      9. </ul>
      10. </div>
      11. </header>
      12. <div data-role="content">
      13. <h3 id="anzahl_titel_favoriten" align="center"></h3>
      14. <div id="favoriten_inhalt">
      15. <ul id="file-listing-favoriten"></ul>
      16. </div>
      17. </div>
      18. <div id="footer" data-role="footer" data-position="fixed" align="center">
      19. <a href="#" data-role="button" data-transition="flip" data-icon="info" data-iconpos="right" data-iconshadow="true">Info</a>
      20. </div>
      21. </div>
      Alles anzeigen


      Die beiden anderen Schaltflächen lösen ebenfalls Ereignisse aus, linken aber wieder via [lexicon]Script[/lexicon] auf die Home-Seite.

      Somit ist unsere index.[lexicon]html[/lexicon] fertig. Fast!!!!

      Was jetzt noch fehlt, sind 4 versteckte Textfelder, die uns später als Schalter (Switcher) dienen. Diese verfrachten wir vor unserer Home-Seite und unterhalb des Body-Tags.

      Quellcode

      1. <input name="erster_start" id="erster_start" type="hidden" value="0">
      2. <input name="song_id" type="hidden" id="song_id" value="0">
      3. <input name="datenbank_modus" type="hidden" id="datenbank_modus" value="0">
      4. <input name="wiederholen" type="hidden" id="wiederholen" value="0">



      Und zu guter letzt. Hier unsere komplette index.[lexicon]html[/lexicon]:

      in der nächsten Antwort:

      Dieser Beitrag wurde bereits 20 mal editiert, zuletzt von vtaker ()

    • Hier unsere komplette index.[lexicon]html[/lexicon]:

      HTML-Quellcode

      1. <!DOCTYPE html>
      2. <html>
      3. <head>
      4. <meta charset="utf-8" />
      5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      6. <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
      7. <link rel="stylesheet" href="css/themes/default/jquery.mobile-1.4.5.min.css">
      8. <link rel="stylesheet" type="text/css" href="css/index.css" />
      9. <title>Audio Player</title>
      10. </head>
      11. <body onLoad="load">
      12. <input name="erster_start" id="erster_start" type="hidden" value="0">
      13. <input name="song_id" type="hidden" id="song_id" value="0">
      14. <input name="datenbank_modus" type="hidden" id="datenbank_modus" value="0">
      15. <input name="wiederholen" type="hidden" id="wiederholen" value="0">
      16. <!--------------Home - Seite---------------------->
      17. <div id="home" data-role="page" data-theme="b" style="background:url(img/EVE_Online.jpg) no-repeat fixed;">
      18. <header data-role="header" data-position="fixed">
      19. <div data-role="navbar">
      20. <ul>
      21. <li><a href="#" data-icon="home" data-iconpos="right">HOME</a></li>
      22. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      23. <li><a href="#" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      24. </ul>
      25. </div>
      26. </header>
      27. <div data-role="content">
      28. <div id="home_inhalt">
      29. <input name="automatik_play" type="hidden" id="automatik_play" value="0">
      30. <input name="player_status" type="hidden" id="player_status" value="0">
      31. <p id="home_meldung" align="center">Synchronisierung läuft.<br /><br />Bitte warten...</p>
      32. <br />
      33. <p id="aktueller_titel" align="center"></p>
      34. <br />
      35. <div id="aktueller_player" align="center" style="display:none;">
      36. <div id="slider">
      37. <input type="range" name="time-slider" id="time-slider" value="0" min="0" max="100" data-highlight="true" class="ui-hidden-accessible" onChange="sprung();" />
      38. </div>
      39. <div data-role="controlgroup" data-type="horizontal">
      40. <a href="#" id="schalter_previous" data-role="button" onClick="previousAudio();">|<<</a>
      41. <a href="#" id="schalter_pause" data-role="button" onClick="pauseAudio();">||</a>
      42. <a href="#" id="schalter_stop" data-role="button" onClick="stopAudio();">X</a>
      43. <a href="#" id="schalter_next" data-role="button" onClick="nextAudio();">>>|</a>
      44. <a href="#" id="schalter_loop" data-role="button" data-icon="refresh" data-iconpos="notext" onClick="loopAudio();">&nbsp;</a>
      45. <a href="#" id="schalter_favorit" data-role="button" data-icon="star" data-iconpos="notext" onClick="favoritAudio();">&nbsp;</a>
      46. </div>
      47. <br>
      48. <p id="gesamt_laenge"></p>
      49. <p id="aktuelle_position"></p>
      50. <div class="clearfloat"></div>
      51. </div>
      52. </div>
      53. </div>
      54. <div id="footer" data-role="footer" data-position="fixed" align="center">
      55. <a href="#" data-role="button" data-transition="flip" data-icon="info" data-iconpos="right" data-iconshadow="true">Info</a>
      56. </div>
      57. </div>
      58. <!--------------Bibliothek - Seite---------------------->
      59. <div id="bibliothek" data-role="page" data-theme="b" style="background:url(img/Abstract-Wave-Color-Light-Background-Vector.jpg) no-repeat fixed;">
      60. <header data-role="header" data-position="fixed">
      61. <div data-role="navbar">
      62. <ul>
      63. <li><a href="#home" data-transition="flip" data-icon="home" data-iconpos="right">HOME</a></li>
      64. <li><a href="#" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      65. <li><a href="#" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      66. </ul>
      67. </div>
      68. </header>
      69. <div data-role="content">
      70. <div id="bibliothek_inhalt">
      71. <a href="#alledateien" data-role="button" data-transition="flip" onClick="alleDateienlisten();">Alle Audio-Dateien</a>
      72. <a href="#letztewiedergabe" data-role="button" data-transition="flip" onClick="letzeWiedergabeListeAuflisten();">Zuletzt wiedergegeben</a>
      73. <a href="#favoriten" data-role="button" data-transition="flip" onClick="FavoritenListeAuflisten();">Meine Favoriten</a>
      74. <a href="#" data-role="button" data-transition="flip" onClick="reset_sync2();">Erneut synchronisieren</a>
      75. <a href="#" data-role="button" data-transition="flip" onClick="table_delete();">Zuletzt wiedergegeben leeren</a>
      76. </div>
      77. </div>
      78. <div id="footer" data-role="footer" data-position="fixed" align="center">
      79. <a href="#" data-role="button" data-transition="flip" data-icon="info" data-iconpos="right" data-iconshadow="true">Info</a>
      80. </div>
      81. </div>
      82. <!--------------alle Dateien - Seite---------------------->
      83. <div id="alledateien" data-role="page" data-theme="b">
      84. <header data-role="header" data-position="fixed">
      85. <div data-role="navbar">
      86. <ul>
      87. <li><a href="#home" data-transition="flip" data-icon="home" data-iconpos="right">HOME</a></li>
      88. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      89. <li><a href="" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      90. </ul>
      91. </div>
      92. </header>
      93. <div data-role="content">
      94. <h3 id="anzahl_titels" align="center"></h3>
      95. <div id="alleDateien_inhalt">
      96. <ul id="file-listings"></ul>
      97. </div>
      98. </div>
      99. <div id="footer" data-role="footer" data-position="fixed" align="center">
      100. <a href="#" data-role="button" data-transition="flip" data-icon="info" data-iconpos="right" data-iconshadow="true">Info</a>
      101. </div>
      102. </div>
      103. <!--------------letzte Wiedergabe - Seite---------------------->
      104. <div id="letztewiedergabe" data-role="page" data-theme="b">
      105. <header data-role="header" data-position="fixed">
      106. <div data-role="navbar">
      107. <ul>
      108. <li><a href="#home" data-transition="flip" data-icon="home" data-iconpos="right">HOME</a></li>
      109. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      110. <li><a href="" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      111. </ul>
      112. </div>
      113. </header>
      114. <div data-role="content">
      115. <h3 id="anzahl_titel_letzte_wiedergabe" align="center"></h3>
      116. <div id="letzte_wiedergaben_inhalt">
      117. <ul id="file-listing-letzte-wiedergabe"></ul>
      118. </div>
      119. </div>
      120. <div id="footer" data-role="footer" data-position="fixed" align="center">
      121. <a href="#" data-role="button" data-transition="flip" data-icon="info" data-iconpos="right" data-iconshadow="true">Info</a>
      122. </div>
      123. </div>
      124. <!--------------meine Favoriten - Seite---------------------->
      125. <div id="favoriten" data-role="page" data-theme="b">
      126. <header data-role="header" data-position="fixed">
      127. <div data-role="navbar">
      128. <ul>
      129. <li><a href="#home" data-transition="flip" data-icon="home" data-iconpos="right">HOME</a></li>
      130. <li><a href="#bibliothek" data-transition="flip" data-icon="star" data-iconpos="right">BIBLIOTHEK</a></li>
      131. <li><a href="" data-icon="power" data-iconpos="right" onClick="beenden();">BEENDEN</a></li>
      132. </ul>
      133. </div>
      134. </header>
      135. <div data-role="content">
      136. <h3 id="anzahl_titel_favoriten" align="center"></h3>
      137. <div id="favoriten_inhalt">
      138. <ul id="file-listing-favoriten"></ul>
      139. </div>
      140. </div>
      141. <div id="footer" data-role="footer" data-position="fixed" align="center">
      142. <a href="#" data-role="button" data-transition="flip" data-icon="info" data-iconpos="right" data-iconshadow="true">Info</a>
      143. </div>
      144. </div>
      145. <script type="text/javascript" src="cordova.js"></script>
      146. <script src="js/jquery-1.11.2.min.js"></script>
      147. <script src="js/jquery.mobile-1.4.5.min.js"></script>
      148. <script type="text/javascript" src="js/index.js"></script>
      149. </body>
      150. </html>
      Alles anzeigen


      So, nun geben wir alles ein wenig Ordnung ([lexicon]Style[/lexicon]). Öffnet eure index.[lexicon]css[/lexicon] und übernehmt einfach den gesamten Inhalt 1:1. Dieses Stylesheet könnt ihr später nach euren Belieben ändern.

      Hier unsere index.[lexicon]css[/lexicon]:

      Brainfuck-Quellcode

      1. @charset "utf-8";
      2. /* CSS Document */
      3. /*----------------CSS Reset-----------------------------------------
      4. --------------------------------------------------------------------*/
      5. * {
      6. padding: 0;
      7. margin: 0;
      8. }
      9. #anzahl_titels,
      10. #anzahl_titel_letzte_wiedergabe,
      11. #anzahl_titel_favoriten {
      12. margin-top:8px;
      13. margin-bottom:8px;
      14. color:#C4E9FF;
      15. }
      16. #file-listings li,
      17. #file-listing-letzte-wiedergabe li,
      18. #file-listing-favoriten li {
      19. border:#333 solid 1px;
      20. background:#000;
      21. font-size:1.1em;
      22. word-wrap:break-word;
      23. margin:6px 0 6px 0;
      24. padding:8px;
      25. list-style:none;
      26. }
      27. #file-listings li a,
      28. #file-listing-letzte-wiedergabe li a,
      29. #file-listing-favoriten li a {
      30. color:#FFF;
      31. background:#000;
      32. margin:6px 0 6px 0;
      33. }
      34. #file-listings li a:hover,
      35. #file-listing-letzte-wiedergabe li a:hover,
      36. #file-listing-favoriten li a:hover {
      37. color:#666;
      38. background:#000;
      39. margin:6px 0 6px 0;
      40. }
      41. #gesamt_laenge {
      42. float:left;
      43. }
      44. #aktuelle_position {
      45. float:right;
      46. }
      47. .clearfloat {
      48. clear:both;
      49. }
      50. #slider {
      51. margin:5px 0 12px 0;
      52. width:85%;
      53. }
      54. div.ui-slider-track
      55. {
      56. margin: 0;
      57. width: 100%;
      58. }
      Alles anzeigen


      Speichert jetzt alles, refresht euer Projekt nochmal. [lexicon]Cordova[/lexicon]-Projekte müssen jetzt nochmal über die [lexicon]CMD[/lexicon] mit dem Befehl [lexicon]cordova[/lexicon] build erneut kompiliert werden. Schließt euer Handy an, nochmals refreshen und das Projekt starten.

      Alle Links funktionieren. Die Info-Seite behandeln wir ganz am Schluss dieses Workshops. Dort werde ich euch einen Code zum Versenden von SMS mit an die Hand geben. Auch wird eine Schnittstelle zu Facebook implementiert sein.

      Jetzt kommen wir, auf das ihr wirklich brennt. Die Programmierung unseres Players.

      Ich verabschiede mich für heute und sage Tschüß, bis zum nächstem Teil in Kürze.

      Schritt 6: Der Dateizugriff und das Local Storage unter Android

      Mario

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von vtaker ()

    • Hallo Freunde und Willkommen zurück zum 5. Teil unseres Workshops!

      Schritt 6: Der Dateizugriff und das Local Storage unter Android

      Nachdem wir nun alle Grundlagen geschaffen haben, unsere index.[lexicon]html[/lexicon], index.[lexicon]css[/lexicon], sowie unsere index.[lexicon]js[/lexicon] erstellt haben, ist es nun endlich an der Zeit, unserem Player Leben einzuhauchen.

      Was soll in groben Zügen enthalten sein:
      • Beim Erststart soll der gesamte Gerätespeicher und eventuell vorhandene SD-Card nach vordefinierten Audiodateien durchsucht werden
      • Permanente Speicherung aller gefundenen Daten im Local Storage
      • Auflistung aller gefundenen Dateien
      • Erneutes synchronisieren
      • Speichern der letzten Wiedergabe in SQLite
      • Auflisten der letzten Wiedergabe
      • Speichern von Titeln in den Favoriten in einer SQLite Datenbank
      • Auflisten der Favoriten
      • Übergreifende Wiedergabe aller Titel aus allen Speicherressoucen
      • Playerstatus-Überwachung
      • Titelsprung
      • Endloswiedergabe
      • Fortlaufende Wiedergabe

      Um dies alles realisieren zu können, bedarf es einer genauen Planung des gesamten Ablaufes unserer App.

      Eines vorweg: In der Vergabe von Variablennamen bin ich nicht sehr kreativ!!! Bitte seht mir dieses nicht nach!!!!

      Okay, dann wollen wir mal!

      Öffnet eure index.[lexicon]js[/lexicon]. Dort steht bis jetzt noch nicht allzu viel drin. Wir haben eine Funktion, die sich um das Beenden unserer App kümmert. Desweiterem, was jetzt viel wichtiger ist. Wir überprüfen beim Appstart ob unser Gerät komplett initialisiert wurde. Ist dies der Fall, wird die Funktion „onDeviceReady“ aufgerufen. Das heißt, innerhalb dieser Funktion steht unser Gerät vollständig zur Verfügung und können dort unseren ersten Funktionsaufruf vornehmen.

      Genau das werden wir jetzt auch machen alle weiteren Anweisung ab unserer ersten Funktion befinden sich innerhalb von „onDeviceReady“, egal ob wir jetzt ausserhalb der Funktion „onDeviceReady“ weiter arbeiten, oder ganz und gar in eine neue Datei schreiben. Unser Gerät ist initialisiert!!!

      Legen wir los:

      Unser erster Funktionsaufruf lautet „datenbankzugriff();“.

      Quellcode

      1. window.addEventListener('load', function () {
      2. document.addEventListener('deviceready', onDeviceReady, false);
      3. }, false);
      4. function onDeviceReady(){
      5. datenbankzugriff();
      6. };
      7. function beenden(){
      8. if(navigator.app)
      9. {
      10. navigator.app.exitApp();
      11. }
      12. else if(navigator.device)
      13. {
      14. navigator.device.exitApp();
      15. }
      16. }
      Alles anzeigen


      Das solls für unsere index.[lexicon]js[/lexicon] gewesen sein. Legen wir nun eine leere Javascriptdatei an und nennen diese main.[lexicon]js[/lexicon].

      Hier werden wir unseren Dateizugriff und das Speichern vornehmen. Solbald diese Datei angelegt wurde, öffnet diese, damit wir Code in dieser schreiben können.

      Referenziert diese Datei natürlich auch in eurer index.[lexicon]html[/lexicon] unterhalb der Referenz zu eurer index.[lexicon]js[/lexicon].

      Quellcode

      1. <script type="text/javascript" src="js/main.js"></script>


      Als erstes müssen wir „Global“ die Extensionen, also Dateitypen bekannt geben, nach denen durchsucht werden soll. Es handelt sich hierbei um ein superglobales Array, also ein Variable die mehrere Werte annehmen kann. Wir könnten hier alle möglichen Audiodateiformate festlegen, die auch ein mobiles Endgerät unterstützt. Man könnte aber auch Videoformate mit aufnehmen. Wobei unser Player bei solchen Dateien nur den Ton abgreifen würde.

      Wir belassen es erst einmal auf „mp3“. Das dürfte für die meisten zutreffend sein.

      Fügt also folgendes in eurer main.[lexicon]js[/lexicon] ein:

      Quellcode

      1. EXTENSION = ['.mp3'];


      Jetzt bauen wir noch 2 Hilfsfunktionen ein, die es verhindern sollen, dass während der Synchronisierung Links angeklickt werden können. Die erste zum Deaktivieren und die zweite zum Aktivieren.

      Quellcode

      1. var DisabledLinkHref = 'javascript:void(0)';
      2. var DisabledLinkTarget = '';
      3. var LinkArray = new Array();
      4. var TargetArray = new Array();
      5. function DisableLinks()
      6. {
      7. $.mobile.loading("show");
      8. for(i=0;i<document.links.length;i++)
      9. {
      10. a = document.links[i].href;
      11. b = document.links[i].target;
      12. LinkArray[i] = a;
      13. TargetArray[i] = b;
      14. document.links[i].href = DisabledLinkHref;
      15. document.links[i].target = DisabledLinkTarget;
      16. }
      17. erststartcheck();
      18. }
      19. function EnableLinks()
      20. {
      21. for(i=0;i<LinkArray.length;i++)
      22. {
      23. document.links[i].href = LinkArray[i];
      24. document.links[i].target = TargetArray[i];
      25. }
      26. }
      Alles anzeigen


      Diese Hilfsfunktionen sollen im Quelltext ganz unten stehen, also setzt euren Cursor wieder nach unseren Extensionen und macht wegen der besseren Lesbarkeit 2 Zeilenumbrüche. Hier schreiben wir fleißig weiter.

      Kümmern wir uns jetzt um unsere Einstiegsfunktion „datenbankzugriff();“. Dort werden wir gleich ins kalte Wasser geschmissen und mit SQLite konfrontiert.

      Die Funktion „datenbankzugriff();“ hat die Aufgabe zu überprüfen, ob eine Datenbank Namens „Audio Spieler“ vorhanden ist. Ist dies der Fall, bleibt diese bestehen. Ist dies nicht der Fall, wird diese automatisch angelegt. Dies erwartet auch einige Parameter, die wir gleich übergeben werden. Als Rückgabe erhalten wir sogenannte Callbacks (Rückmeldungen). Ein Callback ist dafür zuständig, was ausgeführt werden soll, der 2. Callback liefert uns das Ergebnis ob es geklappt hat und der 3. Callback liefert uns im Falle das es schief gegangen ist, einen Fehler-Callback.

      Wir werden ohnehin sehr viel mit diesen Callbacks arbeiten.

      Probieren wir es mal und schreibt folgendes in eure main.[lexicon]js[/lexicon]:

      Quellcode

      1. function datenbankzugriff(){
      2. var db = window.openDatabase("AudioSpielerDB", "1.0", "Audio Spieler DB", 20000);
      3. db.transaction(populateDB, errorDB, successDB);
      4. }


      Man kann also unsere Funktion „datenbankzugriff();“ als Bedingung sehen.

      Wir legen nun die 3 Callbackfunktionen an:

      Quellcode

      1. function populateDB(tx){
      2. }
      3. function errorDB(error){
      4. }
      5. function successDB(){
      6. }
      Alles anzeigen


      Kümmern wir uns um den ersten Callback. Ist die „Bedingung“ erfüllt, führe bitte unsere Funktion „populateDB(tx);“ aus. Diese soll Tabellen in unserer Datenbank anlegen, insofern diese noch nicht vorhanden sind.

      Gibt es ein Fehler, springe in den error-Callback und gib uns eine entsprechende Fehlermeldung aus.

      Hat alles geklappt, führe unsere nächste Funktion aus.

      Nach diesem Schema stricken wir unsere App zum fertigen Pullover.

      Also befüllt nun eure 3 Funktionen wie folgt:

      Quellcode

      1. function populateDB(tx){
      2. tx.executeSql("CREATE TABLE IF NOT EXISTS letzte (lfd INTEGER, titelid INTEGER)");
      3. tx.executeSql("CREATE TABLE IF NOT EXISTS favorit (lfd INTEGER, titelid INTEGER)");
      4. }
      5. function errorDB(error){
      6. navigator.notification.alert(error, null, "Fehler beim Erzeugen oder Öffnen der Datenbank", "OK");
      7. }
      8. function successDB(){
      9. datenbankzugriff2();
      10. }
      Alles anzeigen


      Wir haben also 2 Tabellen angelegt. Eine für die zuletzt wieder gegebenen Titel und eine für unsere Favoriten. Hat alles geklappt, wird nun die Funktion „datenbankzugriff2();“ aufgerufen. Diese wird nun alle Links deaktivieren.

      Quellcode

      1. function datenbankzugriff2(){
      2. DisableLinks();
      3. }


      Schaut man sich die Funktion „DisableLinks();“, die wir an dem Schluss unserer Datei geschrieben hatten, etwas genauer an, wird euch auffallen, das ich nach dem Deaktivieren einen weiteren Funktionsaufruf gesetzt habe. Nämlich „erststartcheck();“.

      In dieser Funktion wird endlich überprüft, ob die App schon einmal gestartet wurde, oder ob eine Erstsynchronisierung stattfinden muss. Damit kommt zum erstem mal, dass Local Storage (Local = lokal in der App, Storage = Speichern) ins Spiel.

      Exkurs:

      Das Local Storage ist vergleichbar mit einer Datenbank, mit dem Unterschied, dass diese sehr leicht zu handlen (handhaben) ist. Sie besteht aus einem Schlüssel – Wertepaar. Es gibt einen eindeutigen Schlüssel und diesem wird ein Wert übergeben. Über die Performance lässt sich kein eindeutiges Ergebnis herleiten. Alle über diese App gespeicherten Werte, bleiben persistent, also dauerhaft (auch nach Beendigung der App) erhalten, und stehen beim erneuten Start der App zur Verfügung. Deinstalliert man hingegen die App, werden auch alle über die App gespeicherten Werte dauerhaft gelöscht.

      Der beste Weg für unsere App ist es zu checken, ob unser Local Storage Werte enthält. Dies ermitteln wir einfach über die Anzahl der Einträge. Sind keine vorhanden, weiß unser [lexicon]Script[/lexicon], das wir zum erstem mal diese App gestartet haben, und die Synchronisierung wird angestoßen.

      Die Syntax hierfür ist denkbar einfach:

      localStorage.length

      Es wird also die Länge abgefragt. Ist diese gleich (numerisch) 0, also ein Integer, dann sind wir zum ersten mal hier.

      Schreibt jetzt einfach mal unter der Funktion „datenbankzugriff2();“ folgende Funktion „erststartcheck();“.

      Quellcode

      1. function erststartcheck(){
      2. len = window.localStorage.length;
      3. if ( len < 1 )
      4. {
      5. document.getElementById("home_meldung").innerHTML = '';
      6. document.getElementById("home_meldung").align="center";
      7. document.getElementById("home_meldung").innerHTML = 'Synchronisierung läuft.<br /><br />Bitte warten...';
      8. window.localStorage.clear();
      9. interval = setInterval(erststartvergleich,1000);
      10. erstinitialisierung();
      11. }
      12. else
      13. {
      14. document.getElementById("home_meldung").innerHTML = '';
      15. document.getElementById("home_meldung").align="center";
      16. document.getElementById("home_meldung").innerHTML = 'Audio Player ist bereit';
      17. EnableLinks();
      18. $.mobile.loading("hide");
      19. document.getElementById("erster_start").value="1";
      20. }
      21. }
      Alles anzeigen


      Wir fragen also ab, ob die Variable len < 1 ist. Ist dies der Fall, stoßen wir die Synchronisierung an. Wir löschen das Local Storage vorsorglich und setzten ein Intervall von 1 Sekunde, was überprüfen soll, ob unser verstecktes Feld "erster_start" in unserer index.[lexicon]html[/lexicon] den Wert 1 übernommen hat. Dies ist für unsere App das Signal, dass die Synchronisierung abgeschlossen ist. Unabhängig davon rufen wir die Funktion „erstinitialisierung();“ auf.

      Sind im Gegensatz schon Werte im Local Storage, werden alle Links wieder aktiviert und unser verstecktes Feld in der index.[lexicon]html[/lexicon] erhält den Wert 1.

      Da wir ein Intervall (Timer) gesetzt haben, müssen wir auch auf diesen reagieren.

      Setzt euch vor die eben geschriebene Funktion und fügt folgene Funktion ein:

      Quellcode

      1. function erststartvergleich(){
      2. if ( document.getElementById("erster_start").value=="1" )
      3. {
      4. clearInterval(interval);
      5. alleDateienlisten();
      6. }
      7. }


      Kümmern wir uns jetzt um die Funktion „erstinitialisierung();“. Jetzt greifen wir auf das Android-Dateisystem zu.


      So Leute. Ich habe bereits rechteckige Augen.

      Ich setzte das Tutorial morgen fort.

      Bis denne,

      Mario

      Dieser Beitrag wurde bereits 29 mal editiert, zuletzt von vtaker ()

    • Au ja, habe schon rechteckige Augen. Ja Großer, ich biete die fertige App zum Download an. Auch wird es ZUM SCHLUSS den gesamten Quelltext aller Dateien geben.

      Ich plädiere allerdings dazu, alle User erst einmal zum Mitmachen und lernen anzuregen, bevor ich für "Faulies" die Katze aus dem Sack lasse!!! Dies ist meine Intension.

      Bin mal eben Kippen kaufen. :)

      Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von vtaker ()

    • Hallo Freunde und Willkommen zurück zum 5. Teil unseres Workshops!

      Schritt 6: Fortsetzung (Der Dateizugriff und das Local Storage unter Android)


      Zunächst einen kleinen Exkurs.

      Exkurs:

      Es gibt 2 Arten auf das Android Dateisystem zuzugreifen.

      Die erste Möglichkeit besteht darin, auf das ROOT-Verzeichnis zuzugreifen.

      requestFileSystem

      Die zweite Möglichkeit werden wir uns zu nutzen machen. Man greift als Startpunkt auf eine absolute URL, die unter Android von Hause aus vorhanden ist.

      resolveLocalFileSystemURI

      Wir werden uns in der obersten Ebene, also in diesen Bereich einklinken, wo wir auch die Möglichkeit haben, auf alle vorhandenen Speichermedien zugreifen zu können.

      In unserem Fall file:///storage. Dies ist unter Android der Hauptknoten, und bietet uns sogar Zugriff auf den „Super-Root-Bereich“, auf den wir noch nicht einmal mit unserem mobilen Endgerät zugreifen können. Jedenfalls nicht ohne spezielle Tastenkombinationen.



      Öffnet eure main.[lexicon]js[/lexicon] und setzt euren Cursor unterhalb unserer zuletzt geschriebenen Funktion („erststartcheck();“). Wir haben als letzte angesprochene Funktion „erstinitialisierung();“ ins Auge gefasst. Dort werden wir nun Kontakt mit dem Dateisystem unter Android aufnehmen.

      Legt euch also nun die Funktion an. Innerhalb dieser lassen wir uns den Ajaxloader anzeigen und verwenden die eben genannte Methode, um uns ins Dateisystem einzuklinken.

      Als Erfolgscallback soll die Funktion „getDirSuccess();“ aufgerufen werden. Diese wird uns einen Verzeichnisreader zur Verfügung stellen. Die Erstellung eines solchen Readers ist denkbar einfach.

      Aber jetzt schön der Reihe nach. Zuerst klinken wir uns ein:

      Quellcode

      1. function erstinitialisierung(){
      2. $.mobile.loading("show");
      3. window.resolveLocalFileSystemURI("file:///storage", getDirSuccess);
      4. }


      Unser Zugriff wurde nun angestoßen. Legen wir als nächstes unsere Funktion „getDirSuccess();“ an. Diese Funktion erwartet einen Übergabeparameter in Richtung „DirectoryEntry“. Wir nennen diesen einfach „dirEntry“. Innerhalb dieser Funktion legen wir kurzerhand einen Verzeichnis-Reader an und übergeben diesen die Methode „readEntries“. Gefolgt von einem Callback, geht es auch schon ans auslesen unseres ersten Verzeichnisses. Dies ist zugegebener Maßen äußerst trickreich, aber tröstet euch, [lexicon]native[/lexicon] Applikationen in Java sind um ein weiteres komplexer!

      Aber wie immer, hübsch der Reihe nach:

      Quellcode

      1. function getDirSuccess(dirEntry) {
      2. var directoryReader = dirEntry.createReader();
      3. directoryReader.readEntries(readerSuccess);
      4. }


      Fügen wir als nächstes unsere Funktion „readerSuccess();“ ein. Auch diese benötigt einen Parameter. Nennen wir diesen einfach „entries“.

      Als erstes legen wir innerhalb dieser Funktion eine leere Variable Namens „extension“ an. Diese soll die Dateiendung der gerade durchsuchten Datei im gerade durlaufendem Verzeichnis aufnehmen und mit dem superglobalen Array, dass wir ganz am Anfang dieser Datei definiert hatten abgleichen.

      Trifft dies mit unseren festgelegten Dateitypen zu, im unserem Fall „mp3“, wird diese im Local Storage gespeichert.

      Nach dem Anlegen unserer leeren Variable durchlaufen wir für unser aktuelles Verzeichnis eine „For-Schleife“, überprüfen ob es sich bei dem aktuellem Element um eine Datei handelt, checken die Extension. Passt alles, rein in dem Local Storage. Handelt es sich um ein Verzeichnis, verlassen wir diese Funktion und stoßen mit Übergabe des Elements eine weitere Funktion an, was eine Ebene tiefer geht. Und immer so weiter…

      So bekommen wir wirklich alle „MP3’s“ in unserem Local Sorage. Gespeichert wird ein eundeutiger Schlüssel. In unserem Falle inkrementieren wir einfach das Hinzuschreiben, also eine laufende Nummer. Als Wert soll der Dateiname gefolgt von 7, ja wie nennt man jetzt dieses Zeichen, Striche, dürfte in keinem Titel vorhanden sein, sowie der absolute Dateipfad.

      Ist alles durchlaufen, geben wir alle Links (Buttons) unserer App wieder frei, schalten den Ajaxloader auf unsichtbar, lassen unser Meldungsfeld in der index.[lexicon]html[/lexicon] „Audio Player ist bereit“ ausgeben, und setzten den Value unseres versteckten Feldes „erster_start“ in unserer index.htm auf 1. Damit wird unser zuvor gesetzter Intervall gecancelt und unsere Synchronisierung ist abgeschlossen.

      Das war auch schon das große Geheimnis in Sachen Dateizugriff.

      Zu guter Letzt wie immer der entsprechende Quelltext:

      Quellcode

      1. function readerSuccess(entries) {
      2. var extension;
      3. for (i=0; i<entries.length; i++) {
      4. var entry = entries[i];
      5. if(entries[i].isFile){
      6. extension = entries[i].name.substr(entry.name.lastIndexOf('.'));
      7. if ( $.inArray(extension, EXTENSION) >= 0 )
      8. {
      9. var t = window.localStorage.length + 1;
      10. window.localStorage.setItem(t,entries[i].name + '|||||||' + entries[i].fullPath);
      11. }
      12. }
      13. if (entries[i].isDirectory){
      14. directoryPath = entries[i].fullPath;
      15. gotPath(directoryPath);
      16. }
      17. }
      18. EnableLinks();
      19. $.mobile.loading("hide");
      20. document.getElementById("home_meldung").innerHTML = '';
      21. document.getElementById("home_meldung").align="center";
      22. $("#home_meldung").css("font-size","1.2em");
      23. document.getElementById("home_meldung").innerHTML = 'Audio Player ist bereit';
      24. document.getElementById("erster_start").value="1";
      25. }
      Alles anzeigen


      Damit auch der Durchlauf aller Verzeichnisse funktioniert, müssen wir über die Funktion „getDirSuccess();“ eine weitere Funktion Namens „gotPath();“ anlegen. Diese ließt das nächste Verzeichnis aus. Und so weiter...

      Quellcode

      1. function gotPath(directoryPath) {
      2. window.resolveLocalFileSystemURI(directoryPath, getDirSuccess);
      3. }


      Jetzt möchten wir natürlich unsere gespeicherten Daten in unserer „Seite“ „alledateien“ ausgeben. Machen wir das. Wir legen uns nun eine neue leere Javascriptdatei an und nennen die „player.[lexicon]js[/lexicon]“. Referenziert diese Datei in eurer index.[lexicon]html[/lexicon] unterhalb eurer main.[lexicon]js[/lexicon].

      Quellcode

      1. <script type="text/javascript" src="js/player.js"></script>


      Als erstes werden eine Reihe von globale Variablen fällig. Diese legen wir nun an.

      Quellcode

      1. var mediaDat = null;
      2. var mediaTimer = null;
      3. var counter = 0;
      4. var titel;
      5. var naechster_titel;
      6. var vorheriger_titel;
      7. var aktueller_song_id;
      8. var letzte_wiedergabe_local;
      9. var favoriten_wiedergabe_local;
      10. var anzahl_wiedergabe_liste_letzte;
      11. var anzahl_wiedergabe_favoriten;
      12. var aktueller_song_id2;
      13. var aktueller_song_id3;
      14. zeiletitelidArr = new Array();
      15. zeiletitelidFavoritenArr = new Array();
      Alles anzeigen


      Ein Blick in unserer index.[lexicon]html[/lexicon] verrät uns, das der Link (Button) „alle Audio-Dateien“ eine Funktion Namens „alleDateienlisten();“ referenziert. Diese legen wir nun in unserer player.[lexicon]js[/lexicon] an.

      Was innerhalb dieser Funktion passiert, ist schnell erklärt. Als erstes setzten wir alle visuellen Anzeigeelemente auf 0. Also einen Leerstring.

      Danach setzen wir, dadurch das wir „alle Dateien auflisten“ angeklickt haben, unser verstecktes Feld „datenbank_modus“ auf 0. Wir rufen nun die Länge des Local Storage auf und speichern diese in einer Variable und geben die Anzahl visuell aus. Jetzt packen wir unsere ungeordnete Liste (<ul id=“ file-listings“>) in eine Variable. Mit einer „For-Schleife“ durchlaufen wir das gesamte Local Storage, fügen für jedes Element ein Listenelement „<li>“, sowie einen Link im Listenelement ein.

      Der Link selbst, bekommt jetzt ein onClick-Ereignis mit Übergabe der laufenden Nummer aus dem Local Storage übergebügelt. Jetzt wird der Titelname wieder aus dem Local Storage selektiert und die inneren [lexicon]HTML[/lexicon]-Elemente der ungeordneten Liste werden hinzugefügt.

      Quellcode

      1. function alleDateienlisten(){
      2. $("#file-listings").html("");
      3. $("#anzahl_titels").html("");
      4. document.getElementById("datenbank_modus").value="0";
      5. var datenbank_len2 = window.localStorage.length;
      6. $("#anzahl_titels").html(datenbank_len2 + " Audio's synchronisiert");
      7. var ul = document.getElementById("file-listings");
      8. for (z=1; z<window.localStorage.length; z++) {
      9. var li = document.createElement('li');
      10. var a = document.createElement('a');
      11. a.onclick = titel_handling(z);
      12. var titel = window.localStorage.getItem(z);
      13. var name_holen = titel.indexOf("|||||||");
      14. var titel_name = titel.substr(0, name_holen);
      15. a.innerHTML = titel_name.substr(0,titel_name.length-4);
      16. ul.appendChild(li);
      17. li.appendChild(a);
      18. }
      19. }
      Alles anzeigen


      Für uns wird jetzt das onClick-Ereignis aus „alleDateienlisten();“ interessant. Damit setzten wir jetzt fort.

      Achtung!!!

      Doch bevor wir fortsetzten, ist mir gerade aufgefallen, das mir ein kleine Fehler unterlaufen ist!!!!!
      Falls ihr euer Projekt kompiliert und gestartet habt, wird euch, besonders den Leuten, die ein [lexicon]Cordova[/lexicon]-Projekt erstellt hatten, aufgefallen sein, das keine Dateien gefunden werden. Wir müssen 2 Dinge in eurer main.[lexicon]js[/lexicon] fixen.

      Sucht euch die Funktion "erststartvergleich();"
      . Löscht die Zeile "alleDateienlisten();".

      Anschließend sucht ihr die Funktion "gotPath();". In der Zeile "window.resolveLocalFileSystemURI(directoryPath, getDirSuccess);" fügt ihr zur übergebenen Variable "directoryPath" noch "file:///" hinzu.

      Quellcode

      1. window.resolveLocalFileSystemURI("file:///" + directoryPath, getDirSuccess);


      Speichert jetzt alles, refresht euer Projekt nochmal. [lexicon]Cordova[/lexicon]-Projekte müssen jetzt nochmal über die [lexicon]CMD[/lexicon] mit dem Befehl [lexicon]cordova[/lexicon] build erneut kompiliert werden. Schließt euer Handy an, nochmals refreshen und das Projekt starten.


      Ich setzte das Tutorial in Kürze fort.

      Bis denne,

      Mario

      Dieser Beitrag wurde bereits 16 mal editiert, zuletzt von vtaker ()

    • Hallo Freunde und Willkommen zurück zum 6. Teil unseres Workshops!

      Schritt 7: Der Mediazugriff

      Bevor wir allerdings fortsetzten, möchte ich darauf hinweisen, dass mir im letzten Thread ein kleiner Fehler unterlaufen ist. Wie dieser korrigiert wird, habe ich im letzten Thread ganz unten beschrieben.

      Behebt diesen noch schnell und dann geht es auch schon weiter.

      Öffnet eure player.[lexicon]js[/lexicon]. Springt zur Funktion „alleDateienlisten();“. Dort haben wir ein onClick-Ereignis eingefügt und ruft die Funktion „titel_handling();“ auf. Diese legen wir jetzt an.

      Quellcode

      1. function titel_handling(aktuell){
      2. return function(){
      3. $("input#automatik_play").val("0");
      4. var aktueller_titel = aktuell;
      5. wiedergabe_start(aktueller_titel);
      6. }
      7. }


      Ich setzte einfach mal voraus, dass ihr in [lexicon]Javascript[/lexicon] einigermaßen mächtig seit, und den Code selbst interpretieren könnt. Ich kann nicht jede einzelne Zeile dokumentieren. Sonst werden wir nie fertig.

      Unsere Funktion ruft die Funktion „wiedergabe_start();“ auf. Und so sieht diese aus.

      Quellcode

      1. function wiedergabe_start(aktueller_titel_wiedergabe){
      2. var aktueller_song_id = aktueller_titel_wiedergabe;
      3. var aktueller_song_pfad = window.localStorage.getItem(aktueller_song_id);
      4. var pfad_ermitteln = aktueller_song_pfad.indexOf("|||||||");
      5. var song_pfad = aktueller_song_pfad.substr(pfad_ermitteln + 7);
      6. var titel_name2 = aktueller_song_pfad.substr(0, pfad_ermitteln);
      7. erst_wiedergabe(song_pfad, aktueller_song_id, titel_name2);
      8. }


      Die nächste Funktion „erst_wiedergabe();“ kümmert sich um die Wiedergabe des angeklickten Elements.

      Fügen wir nun die Funktion wie folgt ein.

      Quellcode

      1. function erst_wiedergabe(wiedergabe, aktueller_song_id, titel_name2){
      2. if ( mediaDat == null )
      3. {
      4. mediaDat = new Media(wiedergabe);
      5. mediaDat.play();
      6. }
      7. else
      8. {
      9. mediaDat.stop();
      10. mediaDat == null;
      11. mediaDat = new Media(wiedergabe);
      12. mediaDat.play();
      13. }
      14. window.location='#home';
      15. $("#home_meldung").html("");
      16. $("#home_meldung").html("Wiedergabe");
      17. $("#aktueller_titel").html(titel_name2.substr(0,titel_name2.length-4));
      18. $("input#automatik_play").val("1");
      19. $("input#player_status").val("1");
      20. $("#schalter_pause").css("background-color","#29c5ff");
      21. $("#aktueller_player").css("display","block");
      22. $("#schalter_pause").html("");
      23. $("#schalter_pause").html("||");
      24. $("input#song_id").val(aktueller_song_id);
      25. }
      Alles anzeigen


      Unser Player sollte, wenn wir jetzt alles speichern, neu kompilieren und starten würdet, angezeit werden und den ausgewählten Titel abspielen.

      Herzlichen Glückwunsch! Ihr habt zum ersten male Kontakt mit dem Media-[lexicon]Plugin[/lexicon] aufgenommen.

      Nun werden wir unsere Funktion vervollständigen. Zunächst übergeben wir unserem Player nur die Quelle. Wir möchten aber auch den Status überwachen und auf diesem reagieren.

      Wir übergeben also unsrem Player noch 3 weitere Parameter, wobei der letzte unseren Status überwacht. Desweiterem befüllen wir unsere „vor“ und „zurück“-Variable mit Werten. Auch möchten wir die Gesamtdauer, sowie die aktuelle Position ermitteln.

      Ich bitte euch, ab jetzt keinen vorschnellen Test vorzunehmen, da erst einige Funktionen hinzugefügt werden müssen!

      Hier die „fast“ vollständige Funktion:

      Quellcode

      1. function erst_wiedergabe(wiedergabe, aktueller_song_id, titel_name2){
      2. if ( mediaDat == null )
      3. {
      4. mediaDat = new Media(wiedergabe, null, null, stoppen);
      5. naechster_titel = aktueller_song_id + 1;
      6. vorheriger_titel = aktueller_song_id - 1;
      7. mediaDat.play();
      8. }
      9. else
      10. {
      11. mediaDat.stop();
      12. mediaDat == null;
      13. mediaDat = new Media(wiedergabe, null, null, stoppen);
      14. naechster_titel = aktueller_song_id + 1;
      15. vorheriger_titel = aktueller_song_id - 1;
      16. mediaDat.play();
      17. }
      18. window.location='#home';
      19. $("#home_meldung").html("");
      20. $("#home_meldung").html("Wiedergabe");
      21. $("#aktueller_titel").html(titel_name2.substr(0,titel_name2.length-4));
      22. $("input#automatik_play").val("1");
      23. $("input#player_status").val("1");
      24. $("#schalter_pause").css("background-color","#29c5ff");
      25. $("#aktueller_player").css("display","block");
      26. $("#schalter_pause").html("");
      27. $("#schalter_pause").html("||");
      28. $("input#song_id").val(aktueller_song_id);
      29. var timerDur = setInterval(function() {
      30. counter = counter + 100;
      31. if (counter > 2000) {
      32. clearInterval(timerDur);
      33. }
      34. var dur = mediaDat.getDuration();
      35. if (dur > 0) {
      36. clearInterval(timerDur);
      37. var seconds_gesamt = Math.round(dur);
      38. var minutes_gesamt = Math.floor(seconds_gesamt / 60);
      39. $('#time-slider').attr('max', Math.round(dur));
      40. //$('#time-slider').slider('refresh');
      41. seconds_gesamt = seconds_gesamt % 60;
      42. if (minutes_gesamt < 10)
      43. minutes_gesamt = '0' + minutes_gesamt;
      44. if (seconds_gesamt < 10)
      45. seconds_gesamt = '0' + seconds_gesamt;
      46. document.getElementById('gesamt_laenge').innerHTML = ('Länge: ' + minutes_gesamt + ':' + seconds_gesamt);
      47. }
      48. }, 100);
      49. if (mediaTimer == null) {
      50. mediaTimer = setInterval(function() {
      51. // get my_media position
      52. mediaDat.getCurrentPosition(
      53. // success callback
      54. function(position) {
      55. if (position > -1) {
      56. setAudioPosition((position));
      57. updateSliderPosition(position);
      58. }
      59. },
      60. // error callback
      61. function(e) {
      62. console.log("Error getting pos=" + e);
      63. setAudioPosition("Error: " + e);
      64. }
      65. );
      66. }, 1000);
      67. }
      68. }
      Alles anzeigen


      Einen Funktionsaufruf innerhalb dieser Funktion habe ich absichtlich noch weggelassen. Um den kümmern wir uns später.

      Kümmern wir um unseren Slider.

      Quellcode

      1. function updateSliderPosition(seconds){
      2. var $slider = $('#time-slider');
      3. if (seconds < $slider.attr('min'))
      4. $slider.val($slider.attr('min'));
      5. else if (seconds > $slider.attr('max'))
      6. $slider.val($slider.attr('max'));
      7. else
      8. $slider.val(Math.round(seconds));
      9. $slider.slider('refresh');
      10. mediaDat.seekPosition(seconds);
      11. }
      12. function sprung(position){
      13. var $slider = $('#time-slider');
      14. var neu = $slider.val();
      15. var neu2 = neu * 1000;
      16. mediaDat.seekTo(Math.round(neu2));
      17. }
      18. function seekPosition(seconds){
      19. mediaDat.seekTo(seconds * 1000);
      20. updateSliderPosition(seconds);
      21. }
      Alles anzeigen


      Jetzt reagieren wir auf den Playerstatus:

      Quellcode

      1. function stoppen(status){
      2. if (status === Media.MEDIA_STOPPED && document.getElementById("automatik_play").value == '1') {
      3. autonext(naechster_titel);
      4. }
      5. }


      Und lassen uns noch die aktuelle Position ausgeben.

      Quellcode

      1. function setAudioPosition(position) {
      2. var seconds = Math.round(position);
      3. var minutes = Math.floor(seconds / 60);
      4. seconds = seconds % 60;
      5. if (minutes < 10)
      6. minutes = '0' + minutes;
      7. if (seconds < 10)
      8. seconds = '0' + seconds;
      9. document.getElementById('aktuelle_position').innerHTML = 'Position: ' + minutes + ':' + seconds;
      10. }


      Kümmern wir uns nun um die Ereignisse Play, Pause, Stop, Vor und Zurück, sowie Loop.

      Unsere Play / Pause Funktion:

      Quellcode

      1. function pauseAudio(){
      2. $("#schalter_pause").css("background-color","#29c5ff");
      3. if ( document.getElementById("player_status").value=="0" ) {
      4. $("#home_meldung").html("Wiedergabe");
      5. $("input#player_status").val("1");
      6. $("input#automatik_play").val("1");
      7. $("#schalter_pause").html("");
      8. $("#schalter_pause").html("||");
      9. mediaDat.play();
      10. }
      11. else
      12. {
      13. $("#home_meldung").html("Pause");
      14. $("input#player_status").val("0");
      15. $("input#automatik_play").val("1");
      16. $("#schalter_pause").html("");
      17. $("#schalter_pause").html(">");
      18. mediaDat.pause();
      19. }
      20. }
      Alles anzeigen


      Unsere Stop Funktion:

      Quellcode

      1. function stopAudio(){
      2. $("#home_meldung").html("Stop");
      3. $("input#player_status").val("0");
      4. $("input#automatik_play").val("0");
      5. $("#schalter_pause").html("");
      6. $("#schalter_pause").html(">");
      7. $("#schalter_pause").css("background-color","#333333");
      8. $("#schalter_loop").css("background-color","#333333");
      9. $("input#wiederholen").val("0");
      10. mediaDat.stop();
      11. mediaDat.release();
      12. document.getElementById('aktuelle_position').innerHTML = 'Position: 00:00';
      13. updateSliderPosition(0);
      14. }
      Alles anzeigen


      Unsere Loop Funktion:

      Quellcode

      1. function loopAudio(){
      2. if ( document.getElementById("wiederholen").value=="0" ) {
      3. $("#schalter_loop").css("background-color","#29c5ff");
      4. $("input#wiederholen").val("1");
      5. }
      6. else
      7. {
      8. $("#schalter_loop").css("background-color","#333333");
      9. $("input#wiederholen").val("0");
      10. }
      11. }
      Alles anzeigen


      Unsere Vor und Zurück Funktion:

      Quellcode

      1. function nextAudio(){
      2. $("#home_meldung").html("Nächster Titel");
      3. $("input#player_status").val("0");
      4. $("#automatik_play").val('0');
      5. $("#schalter_pause").html("");
      6. $("#schalter_pause").html(">");
      7. $("#schalter_pause").css("background-color","#333333");
      8. $("#schalter_loop").css("background-color","#333333");
      9. $("input#wiederholen").val("0");
      10. if ( document.getElementById("datenbank_modus").value=="0" )
      11. {
      12. autonext(naechster_titel);
      13. }
      14. if ( document.getElementById("datenbank_modus").value=="1" )
      15. {
      16. autonext2(naechster_titel);
      17. }
      18. if ( document.getElementById("datenbank_modus").value=="2" )
      19. {
      20. autonext3(naechster_titel);
      21. }
      22. }
      23. function previousAudio(){
      24. $("#home_meldung").html("Voriger Titel");
      25. $("input#player_status").val("0");
      26. $("#automatik_play").val('0');
      27. $("#schalter_pause").html("");
      28. $("#schalter_pause").html(">");
      29. $("#schalter_pause").css("background-color","#333333");
      30. $("#schalter_loop").css("background-color","#333333");
      31. $("input#wiederholen").val("0");
      32. if ( document.getElementById("datenbank_modus").value=="0" )
      33. {
      34. manualprevious();
      35. }
      36. if ( document.getElementById("datenbank_modus").value=="1" )
      37. {
      38. manualprevious2();
      39. }
      40. if ( document.getElementById("datenbank_modus").value=="2" )
      41. {
      42. manualprevious3();
      43. }
      44. }
      Alles anzeigen


      Hier habe ich schon mal auf das Reagieren unseres SQLIte-Zugriffs vorgegriffen.

      Es folgt unsere „autonext();“ Funktion:

      Quellcode

      1. function autonext(naechster_titel_auto){
      2. if ( document.getElementById("wiederholen").value=="0" )
      3. {
      4. var aktueller_song_id = naechster_titel_auto;
      5. if ( naechster_titel >= window.localStorage.length )
      6. {
      7. var aktueller_song_id = 0;
      8. }
      9. else
      10. {
      11. var aktueller_song_id = naechster_titel_auto;
      12. }
      13. }
      14. else
      15. {
      16. var aktueller_song_id = naechster_titel_auto - 1;
      17. }
      18. mediaDat.release();
      19. var aktueller_song_pfad = window.localStorage.getItem(aktueller_song_id);
      20. var pfad_ermitteln = aktueller_song_pfad.indexOf("|||||||");
      21. var song_pfad = aktueller_song_pfad.substr(pfad_ermitteln + 7);
      22. var titel_name2 = aktueller_song_pfad.substr(0, pfad_ermitteln);
      23. var wiedergabe2 = song_pfad;
      24. var aktueller_song_id2 = aktueller_song_id;
      25. var titel_name3 = titel_name2;
      26. naechster_titel = aktueller_song_id + 1;
      27. vorheriger_titel = aktueller_song_id - 1;
      28. erst_wiedergabe(wiedergabe2, aktueller_song_id2, titel_name3);
      29. }
      Alles anzeigen


      Nun noch schnell die „manualprevious();“ Funktion:

      Quellcode

      1. function manualprevious(){
      2. var aktueller_song_id = vorheriger_titel;
      3. if ( aktueller_song_id <= 0 )
      4. {
      5. var aktueller_song_id = 0;
      6. }
      7. else
      8. {
      9. var aktueller_song_id = aktueller_song_id;
      10. }
      11. mediaDat.release();
      12. var aktueller_song_pfad = window.localStorage.getItem(aktueller_song_id);
      13. var pfad_ermitteln = aktueller_song_pfad.indexOf("|||||||");
      14. var song_pfad = aktueller_song_pfad.substr(pfad_ermitteln + 7);
      15. var titel_name2 = aktueller_song_pfad.substr(0, pfad_ermitteln);
      16. var wiedergabe2 = song_pfad;
      17. var aktueller_song_id2 = aktueller_song_id;
      18. var titel_name3 = titel_name2;
      19. naechster_titel = aktueller_song_id + 1;
      20. vorheriger_titel = aktueller_song_id - 1;
      21. erst_wiedergabe(wiedergabe2, aktueller_song_id2, titel_name3);
      22. }
      Alles anzeigen


      Wer möchte, kann jetzt die Anwendung testen. Aber benutzt noch nicht die Vor und Zurück Schaltfläche. Dann würde sich unsere App aufhängen!

      Und hier noch unsere vorläufige player.[lexicon]js[/lexicon] im Ganzen:

      Quellcode

      1. // JavaScript Document
      2. var mediaDat = null;
      3. var mediaTimer = null;
      4. var counter = 0;
      5. var titel;
      6. var naechster_titel;
      7. var vorheriger_titel;
      8. var aktueller_song_id;
      9. var letzte_wiedergabe_local;
      10. var favoriten_wiedergabe_local;
      11. var anzahl_wiedergabe_liste_letzte;
      12. var anzahl_wiedergabe_favoriten;
      13. var aktueller_song_id2;
      14. var aktueller_song_id3;
      15. zeiletitelidArr = new Array();
      16. zeiletitelidFavoritenArr = new Array();
      17. function alleDateienlisten(){
      18. $("#file-listings").html("");
      19. $("#anzahl_titels").html("");
      20. document.getElementById("datenbank_modus").value="0";
      21. var datenbank_len2 = window.localStorage.length;
      22. $("#anzahl_titels").html(datenbank_len2 + " Audio's synchronisiert");
      23. var ul = document.getElementById("file-listings");
      24. for (z=1; z<window.localStorage.length; z++) {
      25. var li = document.createElement('li');
      26. var a = document.createElement('a');
      27. a.onclick = titel_handling(z);
      28. var titel = window.localStorage.getItem(z);
      29. var name_holen = titel.indexOf("|||||||");
      30. var titel_name = titel.substr(0, name_holen);
      31. a.innerHTML = titel_name.substr(0,titel_name.length-4);
      32. ul.appendChild(li);
      33. li.appendChild(a);
      34. }
      35. }
      36. function titel_handling(aktuell){
      37. return function(){
      38. $("input#automatik_play").val("0");
      39. var aktueller_titel = aktuell;
      40. wiedergabe_start(aktueller_titel);
      41. }
      42. }
      43. function wiedergabe_start(aktueller_titel_wiedergabe){
      44. var aktueller_song_id = aktueller_titel_wiedergabe;
      45. var aktueller_song_pfad = window.localStorage.getItem(aktueller_song_id);
      46. var pfad_ermitteln = aktueller_song_pfad.indexOf("|||||||");
      47. var song_pfad = aktueller_song_pfad.substr(pfad_ermitteln + 7);
      48. var titel_name2 = aktueller_song_pfad.substr(0, pfad_ermitteln);
      49. erst_wiedergabe(song_pfad, aktueller_song_id, titel_name2);
      50. }
      51. function erst_wiedergabe(wiedergabe, aktueller_song_id, titel_name2){
      52. if ( mediaDat == null )
      53. {
      54. mediaDat = new Media(wiedergabe, null, null, stoppen);
      55. naechster_titel = aktueller_song_id + 1;
      56. vorheriger_titel = aktueller_song_id - 1;
      57. mediaDat.play();
      58. }
      59. else
      60. {
      61. mediaDat.stop();
      62. mediaDat == null;
      63. mediaDat = new Media(wiedergabe, null, null, stoppen);
      64. naechster_titel = aktueller_song_id + 1;
      65. vorheriger_titel = aktueller_song_id - 1;
      66. mediaDat.play();
      67. }
      68. window.location='#home';
      69. $("#home_meldung").html("");
      70. $("#home_meldung").html("Wiedergabe");
      71. $("#aktueller_titel").html(titel_name2.substr(0,titel_name2.length-4));
      72. $("input#automatik_play").val("1");
      73. $("input#player_status").val("1");
      74. $("#schalter_pause").css("background-color","#29c5ff");
      75. $("#aktueller_player").css("display","block");
      76. $("#schalter_pause").html("");
      77. $("#schalter_pause").html("||");
      78. $("input#song_id").val(aktueller_song_id);
      79. var timerDur = setInterval(function() {
      80. counter = counter + 100;
      81. if (counter > 2000) {
      82. clearInterval(timerDur);
      83. }
      84. var dur = mediaDat.getDuration();
      85. if (dur > 0) {
      86. clearInterval(timerDur);
      87. var seconds_gesamt = Math.round(dur);
      88. var minutes_gesamt = Math.floor(seconds_gesamt / 60);
      89. $('#time-slider').attr('max', Math.round(dur));
      90. //$('#time-slider').slider('refresh');
      91. seconds_gesamt = seconds_gesamt % 60;
      92. if (minutes_gesamt < 10)
      93. minutes_gesamt = '0' + minutes_gesamt;
      94. if (seconds_gesamt < 10)
      95. seconds_gesamt = '0' + seconds_gesamt;
      96. document.getElementById('gesamt_laenge').innerHTML = ('Länge: ' + minutes_gesamt + ':' + seconds_gesamt);
      97. }
      98. }, 100);
      99. if (mediaTimer == null) {
      100. mediaTimer = setInterval(function() {
      101. // get my_media position
      102. mediaDat.getCurrentPosition(
      103. // success callback
      104. function(position) {
      105. if (position > -1) {
      106. setAudioPosition((position));
      107. updateSliderPosition(position);
      108. }
      109. },
      110. // error callback
      111. function(e) {
      112. console.log("Error getting pos=" + e);
      113. setAudioPosition("Error: " + e);
      114. }
      115. );
      116. }, 1000);
      117. }
      118. }
      119. function updateSliderPosition(seconds){
      120. var $slider = $('#time-slider');
      121. if (seconds < $slider.attr('min'))
      122. $slider.val($slider.attr('min'));
      123. else if (seconds > $slider.attr('max'))
      124. $slider.val($slider.attr('max'));
      125. else
      126. $slider.val(Math.round(seconds));
      127. $slider.slider('refresh');
      128. mediaDat.seekPosition(seconds);
      129. }
      130. function sprung(position){
      131. var $slider = $('#time-slider');
      132. var neu = $slider.val();
      133. var neu2 = neu * 1000;
      134. mediaDat.seekTo(Math.round(neu2));
      135. }
      136. function seekPosition(seconds){
      137. mediaDat.seekTo(seconds * 1000);
      138. updateSliderPosition(seconds);
      139. }
      140. function stoppen(status){
      141. if (status === Media.MEDIA_STOPPED && document.getElementById("automatik_play").value == '1') {
      142. autonext(naechster_titel);
      143. }
      144. }
      145. function setAudioPosition(position) {
      146. var seconds = Math.round(position);
      147. var minutes = Math.floor(seconds / 60);
      148. seconds = seconds % 60;
      149. if (minutes < 10)
      150. minutes = '0' + minutes;
      151. if (seconds < 10)
      152. seconds = '0' + seconds;
      153. document.getElementById('aktuelle_position').innerHTML = 'Position: ' + minutes + ':' + seconds;
      154. }
      155. function pauseAudio(){
      156. $("#schalter_pause").css("background-color","#29c5ff");
      157. if ( document.getElementById("player_status").value=="0" ) {
      158. $("#home_meldung").html("Wiedergabe");
      159. $("input#player_status").val("1");
      160. $("input#automatik_play").val("1");
      161. $("#schalter_pause").html("");
      162. $("#schalter_pause").html("||");
      163. mediaDat.play();
      164. }
      165. else
      166. {
      167. $("#home_meldung").html("Pause");
      168. $("input#player_status").val("0");
      169. $("input#automatik_play").val("1");
      170. $("#schalter_pause").html("");
      171. $("#schalter_pause").html(">");
      172. mediaDat.pause();
      173. }
      174. }
      175. function stopAudio(){
      176. $("#home_meldung").html("Stop");
      177. $("input#player_status").val("0");
      178. $("input#automatik_play").val("0");
      179. $("#schalter_pause").html("");
      180. $("#schalter_pause").html(">");
      181. $("#schalter_pause").css("background-color","#333333");
      182. $("#schalter_loop").css("background-color","#333333");
      183. $("input#wiederholen").val("0");
      184. mediaDat.stop();
      185. mediaDat.release();
      186. document.getElementById('aktuelle_position').innerHTML = 'Position: 00:00';
      187. updateSliderPosition(0);
      188. }
      189. function loopAudio(){
      190. if ( document.getElementById("wiederholen").value=="0" ) {
      191. $("#schalter_loop").css("background-color","#29c5ff");
      192. $("input#wiederholen").val("1");
      193. }
      194. else
      195. {
      196. $("#schalter_loop").css("background-color","#333333");
      197. $("input#wiederholen").val("0");
      198. }
      199. }
      200. function nextAudio(){
      201. $("#home_meldung").html("Nächster Titel");
      202. $("input#player_status").val("0");
      203. $("#automatik_play").val('0');
      204. $("#schalter_pause").html("");
      205. $("#schalter_pause").html(">");
      206. $("#schalter_pause").css("background-color","#333333");
      207. $("#schalter_loop").css("background-color","#333333");
      208. $("input#wiederholen").val("0");
      209. if ( document.getElementById("datenbank_modus").value=="0" )
      210. {
      211. autonext(naechster_titel);
      212. }
      213. if ( document.getElementById("datenbank_modus").value=="1" )
      214. {
      215. autonext2(naechster_titel);
      216. }
      217. if ( document.getElementById("datenbank_modus").value=="2" )
      218. {
      219. autonext3(naechster_titel);
      220. }
      221. }
      222. function previousAudio(){
      223. $("#home_meldung").html("Voriger Titel");
      224. $("input#player_status").val("0");
      225. $("#automatik_play").val('0');
      226. $("#schalter_pause").html("");
      227. $("#schalter_pause").html(">");
      228. $("#schalter_pause").css("background-color","#333333");
      229. $("#schalter_loop").css("background-color","#333333");
      230. $("input#wiederholen").val("0");
      231. if ( document.getElementById("datenbank_modus").value=="0" )
      232. {
      233. manualprevious();
      234. }
      235. if ( document.getElementById("datenbank_modus").value=="1" )
      236. {
      237. manualprevious2();
      238. }
      239. if ( document.getElementById("datenbank_modus").value=="2" )
      240. {
      241. manualprevious3();
      242. }
      243. }
      244. function autonext(naechster_titel_auto){
      245. if ( document.getElementById("wiederholen").value=="0" )
      246. {
      247. var aktueller_song_id = naechster_titel_auto;
      248. if ( naechster_titel >= window.localStorage.length )
      249. {
      250. var aktueller_song_id = 0;
      251. }
      252. else
      253. {
      254. var aktueller_song_id = aktueller_song_id;
      255. }
      256. }
      257. else
      258. {
      259. var aktueller_song_id = naechster_titel_auto - 1;
      260. }
      261. mediaDat.release();
      262. var aktueller_song_pfad = window.localStorage.getItem(aktueller_song_id);
      263. var pfad_ermitteln = aktueller_song_pfad.indexOf("|||||||");
      264. var song_pfad = aktueller_song_pfad.substr(pfad_ermitteln + 7);
      265. var titel_name2 = aktueller_song_pfad.substr(0, pfad_ermitteln);
      266. var wiedergabe2 = song_pfad;
      267. var aktueller_song_id2 = aktueller_song_id;
      268. var titel_name3 = titel_name2;
      269. naechster_titel = aktueller_song_id + 1;
      270. vorheriger_titel = aktueller_song_id - 1;
      271. erst_wiedergabe(wiedergabe2, aktueller_song_id2, titel_name3);
      272. }
      273. function manualprevious(){
      274. var aktueller_song_id = vorheriger_titel;
      275. if ( aktueller_song_id <= 0 )
      276. {
      277. var aktueller_song_id = 0;
      278. }
      279. else
      280. {
      281. var aktueller_song_id = aktueller_song_id;
      282. }
      283. mediaDat.release();
      284. var aktueller_song_pfad = window.localStorage.getItem(aktueller_song_id);
      285. var pfad_ermitteln = aktueller_song_pfad.indexOf("|||||||");
      286. var song_pfad = aktueller_song_pfad.substr(pfad_ermitteln + 7);
      287. var titel_name2 = aktueller_song_pfad.substr(0, pfad_ermitteln);
      288. var wiedergabe2 = song_pfad;
      289. var aktueller_song_id2 = aktueller_song_id;
      290. var titel_name3 = titel_name2;
      291. naechster_titel = aktueller_song_id + 1;
      292. vorheriger_titel = aktueller_song_id - 1;
      293. erst_wiedergabe(wiedergabe2, aktueller_song_id2, titel_name3);
      294. }
      Alles anzeigen


      Im nächten Schritt kümmern wir uns um das Hinzufügen und Auslesen in unsere SQLite-Datenbank.

      Bis dann,

      Mario

      Dieser Beitrag wurde bereits 19 mal editiert, zuletzt von vtaker ()