Technische Universität Ilmenau Fakultät für ... - TU Ilmenau
Technische Universität Ilmenau Fakultät für ... - TU Ilmenau
Technische Universität Ilmenau Fakultät für ... - TU Ilmenau
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Technische</strong> <strong>Universität</strong> <strong>Ilmenau</strong><br />
<strong>Fakultät</strong> <strong>für</strong> Elektrotechnik und Informationstechnik<br />
Bachelorarbeit<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen<br />
Rundfunk<br />
vorgelegt von: Florian Schlembach<br />
eingereicht am: 02. 05. 2011<br />
geboren am:<br />
Studiengang: Medientechnologie<br />
Studienrichtung: Informations- und Kommunikationstechnik<br />
Matrikelnummer:<br />
Anfertigung im Fachgebiet: Kommunikationsnetze<br />
<strong>Fakultät</strong> <strong>für</strong> Elektrotechnik und Informationstechnik<br />
Verantwortlicher Professor: Prof. Dr. rer. nat. habil. Jochen Seitz<br />
Wissenschaftlicher Betreuer: Dipl.-Ing. Karsten Renhak
Kurzfassung<br />
Durch den demographischen Wandel und den damit verbundenen sinkenden Geburtenraten<br />
sowie einer steigenden Lebenserwartung unterliegt Deutschland einem Alterungsprozess.<br />
Es ist daher wichtig einen erhöhten Fokus auf das Gesundheitswesen,<br />
speziell die Altenpflege zu legen. Das WEITBLICK-Projekt, in dem die <strong>TU</strong> <strong>Ilmenau</strong><br />
als einer der Projektpartner fungiert, hat sich zum Ziel gesetzt ein zentralisiertes Assistenzsystem<br />
zu entwickeln, womit Senioren ihren Alltag leichter meistern können. U.<br />
a. bietet das Projekt WEITBLICK Vermittlung von Dienstleistungen (Pflege, soziale<br />
Kontakte, Hobby, Wellness, ...) und Assistenz bei der Wahrnehmung dieser Angebote<br />
an, welche Gegenstand dieser Bachelorarbeit sind.<br />
Ziel dieser Bachelorarbeit ist die Nutzung eines Smartphones als Rückkanal <strong>für</strong><br />
herkömmlichen Fernsehrundfunk, da sich Fernsehstandards, wie DVB-RCS/C/T oder<br />
HbbTV, zum Senden von Daten bisher nicht durchgesetzt haben bzw. nicht umgesetzt<br />
wurden. Demnach soll das Smartphone über das Internet einen Rückkanal zum<br />
Fernsehrundfunk bilden, um Buchungsinformationen senden zu können. Die Idee dabei<br />
ist eine über das Fernsehbild eingeblendete optische Marke mit dem Smartphone abzufotografieren,<br />
diese zu interpretieren und die Buchung in Form einer Nachricht mit<br />
einer auf dem Smartphone gespeicherten Nutzer-ID an eine vom WEITBLICK-Projekt<br />
entwickelte Middleware zu senden.<br />
Demnach gliedert sich die Arbeit in zwei Teile. Erstens in die Recherche, die Anforderungsanalyse<br />
und die Wahl einer geeigneten optischen Marke. Zweitens in die<br />
praktische Umsetzung, die das Dienstbuchungssystem sowohl auf der Client- als auch<br />
auf der Server-Seite behandelt.<br />
Im ersten Teil wurde nach Charakterisierung und Kategorisierung von optischen<br />
Marken eine Anforderungsanalyse <strong>für</strong> eine geeignete WEITBLICK Marke durchgeführt.<br />
Die sich daraus ergebenden Codes Code-128, Data Matrix und QR Code wurden<br />
in einer praktischen Testreihe gegenübergestellt. Die Wahl fiel letztendlich auf den QR<br />
Code, da sich dieser bzgl. des Leseabstands und des horizontalen Betrachtungswinkels<br />
am flexibelsten vom Fernsehgerät auslesen lässt.<br />
Der zweite Teil bezieht sich auf die praktische Umsetzung des Dienstbuchungssystems.<br />
Als Smartphone Betriebssystem wurde das von Google entwickelte Android OS<br />
verwendet. Zum Scannen des QR Codes wurde die Android App ZXing Barcode Scanner<br />
benutzt, die auf der Open-Source ZXing Bildverarbeitungsbibliothek basiert. Die<br />
buchbaren Dienstleistungen werden auf einem mySQL-Server zentral gespeichert. Die<br />
Dienstbuchung erfolgt durch das Senden einer Nachricht an eine vom WEITBLICK-<br />
Projekt verwendete Kommunikations-Middleware namens openMQ. Da Android zur<br />
Dienstabfrage und -buchung keine externen SQL-Anfragen unterstützt und kein JMS<br />
Interface implementiert hat, wurde ein Universal Message Service (UMS) und ein<br />
PHP-Skript zur Server-Seite hinzugefügt. Diese beiden Zwischeninstanzen fungieren<br />
dabei jeweils als ein RESTful Interface, womit der Android Client mittels einfacher<br />
HTTP-Nachrichten mit dem Dienstbuchungssystem kommunizieren kann.
Abstract<br />
Due to demographic change and associated factors like decreasing birthrates and increasing<br />
life expectancy, germany is subject of an aging process. Therefore, it is important<br />
to bring health care, especially elderly care, into focus. The WEITBLICK-Project the<br />
<strong>TU</strong> <strong>Ilmenau</strong> is involved in as one of the project partners, has targeted to build up<br />
a centralized assistence system for making elderlys’ lifes easier. Among other things<br />
the Project WEITBLICK is providing both the brokering of service offers (health care,<br />
social contacts, hobbies, wellness, ...) and the assistance for accepting these offers. This<br />
bachelor thesis is focussing on these subjects.<br />
The scope of this bachelor thesis is the use of a smartphone as a back channel<br />
for usual television broadcast because broadcasting standards like DVB-RCS/C/T or<br />
HbbTV for sending data haven’t been established yet. According to that, the smartphone<br />
should build a back channel of the television broadcast via internet for being<br />
able to send booking information. The idea is to scan an optical stamp shown on TV,<br />
to process it and to perform the booking. This is realized by sending the message<br />
with an user ID which is saved on the smartphone to a middleware developed for the<br />
WEITBLICK-Project.<br />
Thus, the thesis is splitted into two parts. First is transaction of an investigation, the<br />
requirement analysis and the choice for an appropriate WEITBLICK Code. Second is<br />
the practical application which envelops the service booking system both on its clientand<br />
its server-side.<br />
In the first part a definition and a classification in categories for an optical stamp<br />
and a further requirement analysis for an appropriate WEITBLICK Code was accomplished.<br />
The resultant Codes Code-128, Data Matrix and QR Code were compared in<br />
a practical test series. Finally, the choice was made in favor of the QR Code because<br />
it is, concerning the distance and the horizontal viewing angle to the TV screen, most<br />
flexibly readable.<br />
The second part is about the practical application of the service booking system.<br />
Android OS was employed as the smartphone operating system which was developed<br />
by Google. For scanning the QR Code the Android App ZXing Barcode Scanner which<br />
is based on the open-source ZXing image processing library was used. The bookable<br />
services are saved centrally on a mySQL-server. The service booking is transacted by<br />
sending a message to a middleware named openMQ which is used for the WEITBLICK-<br />
Project. Due to the fact that Android supports no external SQL-requests and that it<br />
has no JMS interface implemented for the service request and service booking, an<br />
Universal Message Service (UMS) and a PHP-script were added to the server-side.<br />
These two intermediate instances are acting each as a RESTful Interface which enables<br />
the Android client to communicate with the service booking system by just sending<br />
simple HTTP messages.
Inhaltsverzeichnis i<br />
Inhaltsverzeichnis<br />
1 Einführung 1<br />
2 Aufgabenstellung 2<br />
3 Diskussion der optischen Marke 4<br />
3.1 Merkmale einer optischen Marke . . . . . . . . . . . . . . . . . . . . . . 5<br />
3.1.1 Zeichensätze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />
3.1.2 Informationsdichte und zu codierende Nutzdatenmenge . . . . . 5<br />
3.1.3 Datensicherheit . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />
3.1.4 Flexibilität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />
3.1.5 Standardisierung . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />
3.2 Anforderungsanalyse <strong>für</strong> den WEITBLICK Code . . . . . . . . . . . . 7<br />
3.2.1 Standardisierung . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />
3.2.2 Datenmenge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />
3.2.3 Flexibilität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />
3.2.4 Fazit aus den gegebenen Anforderungen . . . . . . . . . . . . . 10<br />
3.3 Arten von optischen Marken . . . . . . . . . . . . . . . . . . . . . . . . 11<br />
3.3.1 Strichcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />
3.3.2 Stapelcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />
3.3.3 Matrixcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />
3.4 Praktischer Vergleich der Codes . . . . . . . . . . . . . . . . . . . . . . 17<br />
3.4.1 Vergleich der Codes in einer Testreihe . . . . . . . . . . . . . . . 18<br />
3.4.2 Auswertung der Testreihe und Auswahl der optischen Marke . . 19<br />
4 Praktische Umsetzung 21<br />
4.1 Anforderungen an das Dienstbuchungssystem . . . . . . . . . . . . . . 21<br />
4.2 Struktur des Dienstbuchungssystems . . . . . . . . . . . . . . . . . . . 22<br />
4.2.1 Client des Dienstbuchungssystems . . . . . . . . . . . . . . . . . 23<br />
4.2.1.1 Konventionen zur Generierung des QR Codes . . . . . 23<br />
4.2.1.2 Android als mobiles Betriebssystem . . . . . . . . . . . 23<br />
4.2.1.3 Fehlende Java-Bibliotheken . . . . . . . . . . . . . . . 24<br />
4.2.2 Server des Dienstbuchungssystems . . . . . . . . . . . . . . . . . 25<br />
4.2.2.1 UMS- und openMQ-Server als eigentliches Dienstbuchungssystem<br />
. . . . . . . . . . . . . . . . . . . . . . . 26<br />
4.2.2.2 SQL Server als Dienstserver . . . . . . . . . . . . . . . 29<br />
4.3 Die WEITBLICK CodeScanner App . . . . . . . . . . . . . . . . . . . 30<br />
4.3.1 Android Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . 31<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Inhaltsverzeichnis ii<br />
4.3.1.1 Android Manifest . . . . . . . . . . . . . . . . . . . . . 32<br />
4.3.1.2 Activities . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />
4.3.1.3 Application Resources . . . . . . . . . . . . . . . . . . 35<br />
4.3.2 Aufbau der CodeScanner App . . . . . . . . . . . . . . . . . . . 38<br />
4.3.3 Datenzugriffsklasse DataAccess . . . . . . . . . . . . . . . . . . 40<br />
4.3.3.1 Methode parseScanresult(...): Parsen der Scan-Ergebnisse 41<br />
4.3.3.2 Methode requestService(): Anforderung der Dienstinformationen<br />
. . . . . . . . . . . . . . . . . . . . . . . . 42<br />
4.3.3.3 Methode sendMessage(...): Buchen des Dienstes . . . . 43<br />
4.3.4 Main-Activity CodeScanner . . . . . . . . . . . . . . . . . . . . 46<br />
4.3.4.1 Methode initScanningLayout(): Aufruf der externen ZXing<br />
Barcode Scanner App . . . . . . . . . . . . . . . . . . 47<br />
4.3.4.2 Verarbeiten der Scan-Ergebnisse und Erstellen eines<br />
DataAccess-Objekts . . . . . . . . . . . . . . . . . . . 48<br />
4.3.4.3 Methode initBookingLayout(): Anzeige der Dienstleistung<br />
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 48<br />
4.3.4.4 Methode makeCall(): Verbindung mit einem Ansprechpartner<br />
. . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />
4.4 WEITBLICK QR Code-Generator . . . . . . . . . . . . . . . . . . . . 52<br />
5 Zusammenfassung und Ausblick 54<br />
A Quellcodes 57<br />
A.1 mySQL-Server und PHP-Server als Dienstserver . . . . . . . . . . . . . 57<br />
A.2 Android Manifest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57<br />
A.3 Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57<br />
A.4 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />
A.5 Datenzugriffsklasse DataAccess() . . . . . . . . . . . . . . . . . . . . . 60<br />
A.6 CodeScanner Activity-Klasse . . . . . . . . . . . . . . . . . . . . . . . . 65<br />
Literaturverzeichnis 72<br />
Abbildungsverzeichnis 75<br />
Tabellenverzeichnis 76<br />
Abkürzungsverzeichnis 77<br />
Quellcodeverzeichnis 79<br />
Thesen zur Bachelorarbeit 80<br />
Erklärung 81<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
1 Einführung 1<br />
1 Einführung<br />
Deutschland ist geprägt von einem demographischen Wandel, welcher sich auf die<br />
Veränderung der Zusammensetzung der Altersstrukturen in der Gesellschaft bezieht.<br />
Durch sinkende Geburtenraten und eine höhere Lebenserwartung unterliegt Deutschland<br />
einem Alterungsprozess. Umso wichtiger ist es daher einen erhöhten Fokus auf<br />
das Gesundheitswesen, speziell auf die Altenpflege, zu legen. Mit zunehmendem Alter<br />
sinken die geistigen, körperlichen und sozialen Fähigkeiten älterer Menschen. Sie haben<br />
demzufolge Schwierigkeiten Aktivitäten des Alltags selbstständig zu meistern. Die Kosten<br />
<strong>für</strong> die nötige Altenpflege werden zumeist nur <strong>für</strong> die grundlegenden Aufgabengebiete<br />
durch gesetzliche Sozialversicherungen abgedeckt. Für weitere Zusatzleistungen,<br />
die nötig wären, um älteren Menschen die Möglichkeit zu geben ein weitestgehend<br />
normales Leben zu führen, müssen eigene finanzielle Mittel bzw. eine private Altersvorsorge<br />
aufgebracht werden. ” Damit besteht Bedarf an kostengünstigen, kommerziell<br />
verfügbaren, persönlichen und technischen Assistenzangeboten als Dienstleistung <strong>für</strong><br />
den Alltag wie <strong>für</strong> Notfallsituationen.“ [Pro11]<br />
Das Projekt WEITBLICK hat sich zum Ziel gesetzt das Leben älterer Menschen<br />
durch Hinzunahme von technologisch modernen Lösungen zu vereinfachen. Über unterschiedliche<br />
Kommunikationskanäle sollen kostengünstig persönliche und technische<br />
Assistenzangebote als Dienstleistung gebucht, aber auch als zentrales Kommunikationssystem<br />
zum sozialen Austausch zwischen Gleichgesinnten, genutzt werden können.<br />
Als einer der Punkte <strong>für</strong> die Funktionalität des Assistenzsystems wird unter [Pro11]<br />
folgender genannt:<br />
• Interessen- und befähigungsorientierte Vermittlung von Dienstleistungsangeboten<br />
(Pflege, soziale Kontakte, Hobby, Wellness, ...) und Assistenz bei der Wahrnehmung<br />
dieser Angebote<br />
Gegenstand dieser Bachelorarbeit ist es Dienstleistungsangebote, die über den herkömmlich<br />
digitalen Fernsehrundfunk empfangen werden, direkt buchen zu können. Da<br />
Standards wie DVB-RCS/C/T, die einen Fernseh-Rückkanal beschreiben, sich nach<br />
aktuellem Stand nicht durchgesetzt haben bzw. umgesetzt wurden, ist es nicht so einfach<br />
möglich vom Fernsehgerät Buchungsinformation zu senden. Das folgende Kapitel<br />
beschreibt wie durch Nutzung eines Smartphones über das Internet ein Rückkanal zum<br />
Fernsehrundfunk gebildet wird.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
2 Aufgabenstellung 2<br />
2 Aufgabenstellung<br />
Gemäß einer Studie aus dem Jahr 2003 besitzen 95% der Haushalte in Deutschland<br />
einen Fernsehanschluss [PDK03, S. 97]. Demzufolge ist bereits ein Kommunikationskanal<br />
geschaffen, der <strong>für</strong> nahezu jeden erreichbar ist und vor allem wegen seiner Beliebtheit<br />
präferiert wird. Da der Fernsehrundfunk allerdings nur als unidirektionaler Kommunikationsweg<br />
fungiert, können Informationen nur empfangen werden. Um empfangene<br />
Dienstleistungsangebote buchen zu können, könnten demnach keine Informationen<br />
zur Buchung gesendet werden.<br />
Ziel dieser Bachelorarbeit ist es, durch Nutzung eines Smartphones 1 einen Rückkanal<br />
<strong>für</strong> den Fernsehkanal zu bilden. Abb. 2.1 veranschaulicht eine mögliche Realisierung<br />
eines solchen Rückkanals:<br />
Fernsehrundfunk<br />
TV<br />
(mit integriertem Receiver)<br />
Smartphone<br />
(z.B. iPhone, Android-Phone)<br />
einlesen interpretieren senden<br />
Dienstleistung<br />
mit bestimmter ID<br />
Abbildung 2.1: Veranschaulichter Ablauf des gebildeten Rückkanals<br />
anrufen<br />
Server<br />
des Dienstanbieters<br />
persönl. Telefongespräch<br />
<strong>für</strong> entspr. Dienstleistung<br />
Dabei wird eine einmalige ID-Nummer einer Dienstleistung in eine optische Marke<br />
codiert. Über den Fernsehrundfunk würde diese dann im Anwendungsfall in einer<br />
Fernsehsendung ausgestrahlt und eingeblendet werden. Nach Abfotografieren der optischen<br />
Marke mit dem Smartphone, erkennt dieses die optische Marke anhand eines<br />
Suchmusters, interpretiert diese und zeigt weitere Informationen zum entsprechenden<br />
Dienstleistungsangebot an. Der Nutzer hat nun zum Einen die Möglichkeit die Buchung<br />
direkt vorzunehmen und die Anfrage an einen Server des Dienstanbieters zu<br />
senden. Falls der Nutzer noch Fragen zum angebotenen Dienst hat, soll es zum Anderen<br />
möglich sein, eine der Dienstleistung entsprechende Telefonnummer anzurufen,<br />
um sich mit einem persönlichen Ansprechpartner verbinden zu lassen. Aus diesem Usecase<br />
(engl. Anwendungsfall) ergeben sich entsprechend der Aufgabenstellung folgende<br />
Teilaufgaben:<br />
1 Smartphone = fortschrittliches Mobiltelefon mit Computerfunktionalitäten und -konnektivitäten,<br />
das sich leicht durch Anwendungen (kurz: Apps) von Drittanbietern erweitern lässt[Wik11]<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
2 Aufgabenstellung 3<br />
1. Recherche möglicher Darstellungsformen <strong>für</strong> die optische Marke<br />
2. Codierung von Informationen mittels der optischen Marke<br />
3. Realisierung einer Anwendung auf dem Smartphone zur Erkennung der optischen<br />
Marke<br />
4. Übermittlung der Buchungsinformation an einen Server<br />
5. Anruf einer mitcodierten Telefonnummer<br />
Damit gliedert sich die Arbeit in zwei Teile: Der erste Teil beschäftigt sich mit der<br />
Recherche, Charakterisierung und Auswahl einer optischen Marke (Punkt 1 und 2).<br />
Dahingehend werden zuerst die Merkmale einer optischen Marke definiert. Um eine<br />
geeignete optische Marke evaluieren zu können, ist eine vorhergehende Anforderungsanalyse<br />
notwendig. Die sich daraus ergebenden, geeigneten Marken werden in einer<br />
Testreihe gegenübergestellt und letztlich wird die Wahl einer optischen Marke getroffen.<br />
Der zweite Teil beschäftigt sich mit der Entwicklung einer Anwendung <strong>für</strong> ein auf<br />
dem Android OS basierenden Smartphone, um eine optische Marke erkennen und interpretieren<br />
zu können. Die interpretierten Informationen des Dienstes sollen auf dem<br />
Smartphone angezeigt werden und der Nutzer soll eine Buchung direkt über eine Internetverbindung<br />
vornehmen können. Die Buchungsinformationen sollen dabei an eine<br />
vom WEITBLICK-Projekt entwickelte Middleware übermittelt werden. Alternativ soll<br />
es die Möglichkeit geben, sich über einen Telefonanruf persönlich mit einem Ansprechpartner<br />
verbinden zu lassen (Punkte 3-5). Um bei einer direkten Buchung die über<br />
eine Internetverbindung gesendeten Buchungsanfragen entgegenzunehmen und zu verarbeiten,<br />
muss eine entsprechende Serverinfrastruktur geschaffen werden.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 4<br />
3 Diskussion der optischen Marke<br />
Die Ursprünge einer optischen Marke liegen in der automatischen Identifikation. Die<br />
Industrie steht durch eine große Vielfalt an Produkten, immer kürzeren Produkt- und<br />
Innovationszyklen, Wettbewerbsdruck und die dadurch notwendigen kurzen Lieferzeiten<br />
unter Druck, immer kostengünstiger und schneller produzieren zu müssen. Dahingehend<br />
sind moderne Methoden gefordert, um die Prozesse in der Produktion und<br />
Logistik besser koordinieren zu können. Es sind Identifikationstechniken notwendig,<br />
mit Hilfe derer Materialien genau identifiziert werden können. In der Logistik, speziell<br />
auch bei Post-, Paket- und Kurierdiensten, werden Identifikationstechniken im Bereich<br />
des Tracking und Tracing (Sendungsverfolgung und Rückverfolgbarkeit) benutzt, um<br />
die Waren vom Absender bis zum Empfänger verfolgen zu können. In Branchen wie<br />
der Automobil- und Pharmaindustrie helfen diese Prozessketten effizient steuern und<br />
koordinieren zu können. Die Identifikationstechniken teilen sich in die Kategorien der<br />
magnetischen, optischen und RF (Radio Frequency)-Identifikation auf [Len05].<br />
Diese Bachelorarbeit beschäftigt sich ausschließlich mit der optischen Identifikation.<br />
Die Grundidee der optischen Identifikation ist Zeichen <strong>für</strong> eine Maschine lesbar<br />
zu machen. Ein Zeichen kann zum Einen optisch in Form eines Schriftzeichens oder<br />
zum Anderen ein codiertes optisches Zeichen sein. Da sich Schriftzeichen in ihrem<br />
Schriftbild sehr stark unterscheiden können, ist es <strong>für</strong> Computer nicht ganz unproblematisch<br />
die einzelnen Schriftzeichen korrekt erfassen zu können und es kommt zu<br />
Auslesefehlern. [Len05] Durch optische Codierung des Zeichens wird es nach einer von<br />
der Codeart abhängigen Bildungsvorschrift als Folge von hellen und dunklen Flächen<br />
binär dargestellt. Damit erfolgt sowohl der Druck als auch das Auslesen einer solchen<br />
optischen Marke in binärer Form. Da die Breiten der hellen und dunklen Flächen innerhalb<br />
von bestimmten Toleranzen konstant sind, wird die Eigensicherheit des Auslesens<br />
von codierten Zeichen erheblich gesteigert. [Len05] hat die Leseraten (Verhältnis richtig<br />
eingelesener zu allen Zeichen) und Fehlerraten (Verhältnis falsch interpretierter zu<br />
allen Zeichen) anhand eines Auslesetests von fünf Ziffern zwischen den Zeichenarten<br />
Klarschrift und OCR/True Type(Standardschriften) verglichen. Nach dem Vergleichstest<br />
in [Len05, S. 16] (Stand 2004) weisen die Strichcodes eine Leserate von nahezu<br />
100% auf, die Klarschrift und OCR/True Type dagegen nur etwa 40% und 80%. Der<br />
Auslesevorgang der Strichcodes wird anhand einer mitcodierten Prüfziffer verifiziert.<br />
Eine Fehlerrate liegt dabei nicht vor, da im Falle eines fehlerhaften Auslesens das Ergebnis<br />
wieder verworfen und der Barcode erneut ausgelesen wird. Eine entsprechende<br />
Fehlerrate ergibt sich dagegen beim Scannen von Klarschrift und OCR-Schriftarten,<br />
da Zeichen falsch interpretiert und deren Korrektheit nicht überprüft werden können.<br />
Im Laufe der Zeit wurden eine Vielzahl an Codes entwickelt. Je nach Branche und<br />
Anwendungsgebiet kommen verschiedene Codearten zum Einsatz. Im Grunde lassen<br />
sich die optischen Marken in eindimensionale Strichcodes und zweidimensionale Stapel-<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 5<br />
bzw. Matrixcodes einteilen. Die Anzahl der Dimensionen gibt an in wie viele optische<br />
Achsen die Informationen codiert sind. Durch zwei weitere Dimensionen werden zweidimensionale<br />
Matrixcodes zum Einen um einen Farbkanal (Farbe, Sättigung) bzw.<br />
Tiefenkanal erweitert und/oder zum Anderen in einer zeitlichen Abfolge dargestellt.<br />
Damit ergeben sich drei- bzw. vierdimensionale optische Marken.<br />
3.1 Merkmale einer optischen Marke<br />
Um aus der Vielzahl von Codes einen geeigneten auswählen zu können, sind vorhergehende<br />
Definitionen der Merkmale, Eigenschaften und vor allem die Art und Anzahl der<br />
zu codierenden Zeichen notwendig. Die Begriffsdefinition der optischen Marke bezieht<br />
sich auf eine Verallgemeinerung des Begriffes Code. Code impliziert dabei die Konvertierung<br />
(Codierung) nach einer bestimmten Vorschrift mit der Informationen in eine<br />
optische Marke (Zeichen) umgesetzt werden. Im allgemeinen Sprachgebrauch werden<br />
zweidimensionale Matrixcodes ebenso als ” Barcodes“ bezeichnet, obwohl diese wörtlich<br />
übersetzt nur <strong>für</strong> die Strichcodes stehen. Unter den Bezeichnungen ” Strich“-, ” Stapel“und<br />
” Matrix“code sind die jeweiligen Codearten gemeint.<br />
3.1.1 Zeichensätze<br />
Der Informationsgehalt einer optischen Marke teilt sich in mehrere einzelne Zeichen<br />
auf. Nach DIN 44300 und [Len02, S. 4] wird bei der Codierung von optischen Marken<br />
ein Zeichen aus einem festgelegten Zeichenvorrat X einem Zeichen aus einem festgelegten<br />
Zeichenvorrat Y zugeordnet. Der Zeichenvorrat X ist eine fest definierte Menge<br />
an Zeichen aus der sich der Anwender bedienen kann. Diese Menge wird daher Anwenderzeichensatz<br />
genannt. Je nach Anwendungszweck und Codeart finden verschiedene<br />
Variationen an standardisierten Zeichensätzen wie bspw. ein numerischer, ein<br />
alphanumerischer, der ASCII oder der ISO-Zeichensatz Verwendung. Die Nutzzeichen<br />
sowie weitere interne Steuer- und Sonderzeichen werden nach den Gesetzmäßigkeiten<br />
der verwendeten Codeart in die entsprechenden Codezeichen umgesetzt. Ein Codezeichen<br />
stellt bei Strichcodes eine bestimmte Sequenz aus unterschiedlichen Strichen und<br />
Lücken dar. Der Zeichensatz Y ist die Menge aller Codezeichen und wird als Codierungszeichensatz<br />
bezeichnet. Die maximal in den Code unterzubringende Anzahl an<br />
Zeichen ist vom verwendeten Anwenderzeichensatz abhängig und aufgrund der Spezifika<br />
des verwendeten Codes begrenzt. Je kleiner der Zeichenvorrat X ist, desto mehr<br />
Nutzzeichen können in einen Code untergebracht werden. [Len02]<br />
3.1.2 Informationsdichte und zu codierende Nutzdatenmenge<br />
Zur Codierung werden die Nutzzeichen in Codezeichen umgesetzt. Die Informationen<br />
werden je nach Codeart mehr oder weniger effizient codiert. Die Effizienz der Codierung<br />
spielt vor allem dann eine Rolle, wenn der zur Verfügung stehende Platz oder<br />
die optische Auflösung des Lesegerätes begrenzt ist. Bei der Herstellung der optischen<br />
Marke müssen bestimmte Toleranzgrenzen eingehalten werden, um den Barcode noch<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 6<br />
korrekt auslesen zu können. Die Codes variieren aufgrund ihres unterschiedlichen Aufbaus<br />
sehr stark. Um die Codes typenübergreifened vergleichen zu können, ist es daher<br />
nötig einen festen Bezugsrahmen zu definieren. Der Bezugsrahmen stellt das kleinste<br />
auftretende Element einer optischen Marke dar. Nach Abb. 3.1 wird dieses bei Strichund<br />
Stapelcodes als Modulbreite und bei zweidimensionalen Matrixcodes als Zellgröße<br />
bezeichnet.<br />
Abbildung 3.1: Modulbreite/Zellgröße einer optischen Marke (entnommen aus [Len02])<br />
Mit der gegebenen Modulbreite bzw. Zellgröße lässt sich nun eine sogenannte Informationsdichte<br />
formulieren. Gemessen an der Druckauflösung bzw. der Auflösung des<br />
verwendeten Herstellungsverfahren gibt die Informationsdichte an wie viele Zeichen<br />
innerhalb einer bestimmten Fläche codiert werden können. [Len02, S. 21 f.]<br />
3.1.3 Datensicherheit<br />
Die optische Identifikation wurde ursprünglich als eine Kategorie der Identifikationstechniken<br />
eingeführt, um Waren bzw. Materialien korrekt identifizieren zu können.<br />
Eine falsche Interpretation der in einer optischen Marke codierten Informationen würde<br />
gegen die Grundidee der optischen Identifikation verstoßen. Es ist daher unerlässlich<br />
die optische Marke mit allen codierten Informationen korrekt auszulesen. Auslesefehler<br />
können durch eine fehlerhaft codierte oder eine verschmutzte bzw. beschädigte optische<br />
Marke verursacht werden. Gleichermaßen kann das korrekte Einlesen der Marke durch<br />
technische Grenzen, wie eine begrenzte optische Auflösung des Lesegerätes, verhindert<br />
werden.<br />
Um Auslesefehler erkennen und korrigieren zu können, werden den Barcodes redundante<br />
Daten hinzugefügt. Mit einer zusätzlichen Prüfziffer, die bei fast allen Codes<br />
verwendet wird, lässt sich überprüfen, ob die ausgelesenen Informationen im Kontext<br />
einen Sinn ergeben. Bei linearen Strichcodes wird zusätzlich noch die Lesesicherheit<br />
erhöht, indem die Striche in ihrer Höhe vergrößert werden. Dies sind redundante Informationen,<br />
da sich der Informationsgehalt lediglich in der Strichbreite befindet. Durch<br />
die zweidimensionale Codestruktur ist es bei Matrixcodes nötig noch weitere Fehlerkorrekturalgorithmen<br />
wie den Cyclic Redundancy Check (CRC) oder einen Reed Solomon<br />
Code zu ergänzen, um Auslesefehler korrigieren zu können.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 7<br />
3.1.4 Flexibilität<br />
Ein weiteres wichtiges Merkmal stellt die Flexibilität beim Auslesen der optischen Marke<br />
dar. Je nach Anwendungszweck und Codeart kommen unterschiedliche Lesegeräte<br />
zum Einsatz. So kann das Auslesen statisch mit einem fest installiertem Lesegerät<br />
oder flexibel mit einem Handlesegerät (wie es auch bei einem Smartphone der Fall<br />
ist) geschehen. In beiden Fällen ist nicht immer gewährleistet, dass das Lesegerät eine<br />
optimale Ausleseposition zur optischen Marke hat. So wäre es möglich, dass der<br />
Barcode zu klein ist, um diesen mit der begrenzten optischen Auflösung des Lesegerätes<br />
einlesen zu können. Des Weiteren liegt durch eine schiefe Lage im Raum oft auch<br />
eine perspektivische Verzerrung vor. Hier kommt es auf die Art des Codes und das<br />
Lesegerät an, inwieweit die Verzerrung ausgeglichen werden kann, um einen erfolgreichen<br />
Auslesevorgang zu ermöglichen. Um die Lage der optischen Marken feststellen zu<br />
können, besitzen lineare Strichcodes am Anfang und Ende ein bestimmtes Start- und<br />
Stopmuster, Matrixcodes ein bestimmtes, charakteristisches Suchmuster. Damit wird<br />
bei linearen Codes die Leserichtung, bei Matrixcodes die konkrete Lage festgestellt.<br />
Durch das Suchmuster der Matrixcodes sind diese omnidirektional, d. h. in alle Richtungen<br />
lesbar, da diese nach dem Auslesen durch Bildverarbeitungsalgorithmen des<br />
Bildprozessors intern noch gedreht werden können. [Len05]<br />
3.1.5 Standardisierung<br />
[Len05, S. 31 f.] teilt die Standardisierung von optischen Marken in drei Bereiche ein:<br />
Code, Applikation und Syntax. Der Code-Bereich beschreibt den Aufbau des Codes,<br />
sowie die Bildungsvorschrift zur Codierung der Zeichen. Als Aufbau werden dabei geometrische<br />
Abmessungen, sowie Toleranzbereiche, Qualitätskriterien und weitere Randbedingungen<br />
festgelegt. Die Bereiche Applikation und Syntax definieren die Interpretation<br />
der Daten und gewährleisten bei Bedarf eine weltweite Eindeutigkeit. Besonders<br />
im Handel und in der Logistik ist eine eindeutige Zuweisung <strong>für</strong> das Tracking und Tracing<br />
von großer Bedeutung. Abhängig von Firma, Branche, Land und Codeart sind<br />
<strong>für</strong> die Vergabe von eindeutigen Identifikationsnummern unterschiedliche Vergabestellen<br />
zuständig. Die <strong>für</strong> den Handel vorgesehenen GTIN-14-Codes (Global Trade Item<br />
Number, ursprünglich EAN- und UPC-Codes) werden von der weltweiten Standardisierungsorganisation<br />
GS1 verwaltet. Der eigentlichen Identifikationsnummer wird bei<br />
den EAN- und UPC-Nummern eine Länderpräfixnummer vorangeführt. Diese besagt<br />
welcher nationalen GS1 Mitgliedsorganisation eine weltweit eindeutige EAN-Nummer<br />
zugeteilt wurde. Ebenso würde der Präfix ” (200-299)“ beispielsweise <strong>für</strong> eine firmeninterne<br />
Verwendung stehen, womit die Nummer weltweit nicht eindeutig sein müsste. Die<br />
GTIN-14 Nummern werden zusätzlich von einem Application Identifier (AI) angeführt.<br />
Dieses gibt an welche Art von Daten sich im Code befindet.<br />
3.2 Anforderungsanalyse <strong>für</strong> den WEITBLICK Code<br />
Nachdem die allgemeinen Merkmale einer optischen Marke erläutert wurden, erfolgt<br />
eine Analyse der an den WEITBLICK Code gestellten Anforderungen. Es gilt hierbei<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 8<br />
sich an den vorliegenden Usecase aus der Aufgabenstellung unter Kapitel 2 zu halten<br />
und diesen entsprechend der gegebenen Randbedingungen anzupassen.<br />
3.2.1 Standardisierung<br />
Die WEITBLICK Anwendung, die zum Scannen und Buchen des Dienstes erstellt<br />
wird, soll auf möglichst vielen Smartphones lauffähig sein. Das von Google aufgekaufte<br />
Android-Betriebssystem stellt <strong>für</strong> mobile Geräte eine weit verbreitete Plattform dar.<br />
Daher soll eine App <strong>für</strong> das Android Betriebssystem entwickelt werden, was in Kapitel<br />
4 noch näher erläutert wird. Nach eingehender Recherche bietet sich die bereits<br />
in Android implementiere App ” Barcode Scanner“ an, die auf der Open-Source 1D-<br />
/2D-Bildverarbeitungsbibliothek ZXing (siehe [ZXi11a]) basiert. Mit einer einfachen<br />
Anfrage aus der WEITBLICK App (einem sogenannten Intent, siehe auch Kapitel 4)<br />
lassen sich Barcodes über die externe ” Barcode Scanner“ App einscannen und die Ergebnisse<br />
des Scanvorgangs anschließend wieder zurückgeben. Der Barcode Scanner ist<br />
dadurch sehr leicht implementierbar.<br />
Aufgrund der gegebenen Implementierungsmöglichkeit sollte die Wahl der optischen<br />
Marke auf einen von der ZXing Barcode Scanner App unterstützten Code fallen. Da<br />
ZXing eine Open-Source Bildverarbeitungsbibliothek ist, werden nur Codes unterstützt,<br />
die ebenfalls frei zu verwenden sind und keine zu entrichtenden Lizenzgebühren<br />
erfordern. Damit sollte die Entscheidung auf eine ebenso frei verwendbare, optische<br />
Marke fallen.<br />
3.2.2 Datenmenge<br />
Nach [Len04, S. 12-15] wird die Auswahl einer optischen Marke in Abhängigkeit von der<br />
Anzahl der zu codierenden Nutzzeichen gesetzt. Diesbezüglich muss festgelegt werden,<br />
welche Arten von Informationen der Dienstleistung im Barcode gespeichert werden<br />
sollen. Um diese Frage klären zu können, muss zwischen zwei grundsätzlichen Methoden<br />
unterschieden werden: Der direkten Verlinkung und der indirekten Verlinkung. [Heg10,<br />
S. 34 f.]<br />
Bei der indirekten Variante werden die Barcodes lediglich mit einer eindeutigen<br />
ID-Nummer versehen. Ein Musterbeispiel hier<strong>für</strong> wären die üblichen EAN-13 Handelscodes.<br />
Durch die ID werden Daten wie Artikelname, Preis, Artikelinformationen usw.<br />
von einer (meist) externen Datenbank indirekt abgefragt.<br />
Bei der direkten Variante sind in der optischen Marke dagegen schon alle Informationen<br />
direkt in die Marke codiert. Es entfällt daher eine zusätzliche Abfrage über eine<br />
externe Datenbank. Dem liegt die Annahme zugrunde, dass die direkte Variante, wegen<br />
des geringeren Aufwands, die bessere sei. Dies hätte jedoch einen entscheidenden Nachteil:<br />
Es könnte nicht sichergestellt werden, dass der gebuchte Dienst vor der Buchung<br />
richtig angezeigt wird. Denkbar wäre demnach, dass sich der Preis einer Dienstleistung<br />
vor der Ausstrahlung der Fernsehsendung irrtümlicherweise geändert hat und der<br />
Nutzer demzufolge den Dienst zu dem im Barcode angegebenen, nicht mehr aktuellen<br />
Preis buchen würde. Ebenso könnte keine missbräuchliche Buchung einer Dienstleistung<br />
ausgeschlossen werden, bei der ein Barcode vom Nutzer selbst erstellt wird und<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 9<br />
der Dienst zu einem selbst angegebenen Preis gebucht werden kann. Der Nutzer könnte<br />
vorgeben, den Dienst zu einem günstigeren Preis gebucht zu haben. Eine weitere<br />
wichtige Information zum Dienst ist der Zeitpunkt zu welchem die Dienstleistung stattfindet.<br />
Auch hier ist eine korrekte Anzeige sicherzustellen. Demnach erfüllt eine rein<br />
direkte Verlinkungs-Variante nicht die Bedingungen der Authentizität und Integrität,<br />
die die Anzeige einer Dienstleistung auf dem Smartphone erfordert.<br />
Variante 1 Variante 2 Variante 3<br />
Verlinkung indirekt direkt hybrid<br />
Anzahl der Zeichen<br />
ID 5 5 5<br />
Kurztitel - 30 30<br />
Kurzbeschreibung - 500 -<br />
Telefonnummer - 20 20<br />
Zeichensatz numerisch ASCII ASCII<br />
Gesamt 5 555 55<br />
Tabelle 3.1: Anzahl der zu codierenden Zeichen<br />
Tab. 3.1 beschreibt die Informationen, die direkt in die optische Marke codiert werden.<br />
Dabei werden jeweils eine indirekte, eine direkte und eine hybride Verlinkungs-<br />
Variante gegenübergestellt.<br />
Der Kurztitel und die Kurzbeschreibung dienen dem Nutzer zur reinen Information,<br />
mit Hilfe der Telefonnummer könnte er sich dann persönlich mit einem Ansprechpartner<br />
verbinden lassen. Auf die Angabe des Termins und der Kosten <strong>für</strong> die Dienstleistung<br />
wurde aufgrund der oben genannten, nicht vorhandenen Bedingungen der Authentizität<br />
und Integrität verzichtet. In Variante 1 wird lediglich eine fünfstellige ID-Nummer<br />
gespeichert, durch die weitere Informationen von einer zentralen Datenbank abgefragt<br />
werden. Variante 2 beinhaltet als direkte Verlinkungs-Variante dagegen, abgesehen von<br />
einer gekürzten Version der Beschreibung, die vollständigen Dienstinformationen. Eine<br />
gekürzte Beschreibung wurde gewählt, um die Gesamtzeichenanzahl klein zu halten,<br />
da mit steigender Anzahl codierter Zeichen die Lesbarkeit des Codes abnimmt [Heg10,<br />
S. 35]. Vorwegnehmend zum nächsten Abschnitt wirkt sich dies auf die Anforderung<br />
der Flexibilität beim Auslesen aus, wodurch sich der maximal erreichbare Leseabstand<br />
zum Fernsehgerät verringert. Folglich ergibt sich die Hybrid-Variante 3, welche sowohl<br />
eine direkte als auch eine indirekte Verlinkungs-Methode kombiniert. Die Gesamtzeichenanzahl<br />
wird durch Weglassen der Kurzbeschreibung auf 55 begrenzt. Betrachtet<br />
man den Fall, dass keine Internetverbindung zur Verfügung steht, so hätte dies einen<br />
entscheidenden Vorteil: Durch die Direktcodierung in den Code könnte trotzdem der<br />
Kurztitel angezeigt werden. Der Nutzer kann damit sehen was sich hinter dem Barcode<br />
verbirgt und sich über die mitcodierte Telefonnummer mit einem persönlichen<br />
Ansprechpartner verbinden lassen, um den Dienst zu buchen.<br />
Abschließend wird damit festgelegt, dass die optische Marke eine fünfstellige ID,<br />
einen Kurztitel und eine Telefonnummer mit einer Gesamtanzahl von maximal 55 Zeichen<br />
speichern soll. Es kommt daher <strong>für</strong> die Codierung nur Variante 3 in Frage.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 10<br />
3.2.3 Flexibilität<br />
Das Merkmal der Flexibilität einer optischen Marke sagt aus, von welchem Lesegerät<br />
unter welchen Bedingungen diese gelesen werden kann.<br />
Im Falle des WEITBLICK-Projekts wird der Code mit einer CCD-Sensor-Kamera<br />
(CCD steht <strong>für</strong> Charge-coupled Device) des Smartphones ausgelesen. Aufgrund der<br />
begrenzten optischen Auflösung des Sensors ist die maximal erreichbare Entfernung,<br />
von der der Barcode ausgelesen werden kann, begrenzt. Zusätzlich ist davon auszugehen,<br />
dass der Nutzer nicht frontal zum Fernsehgerät sitzt. Damit kann die optische<br />
Marke nicht aus einer optimalen Position eingescannt werden und es ergibt sich eine<br />
perspektivische Verzerrung. Diese wird durch den integrierten Bildprozessor des<br />
Smartphones durch Bildverarbeitungsalgorithmen ausgeglichen. Ein weiterer Faktor,<br />
der das Auslesen des Codes erschwert, sind die zu berücksichtigenden Lichtverhältnisse<br />
denen das Fernsehgerät ausgesetzt ist. Je nach Beschaffenheit der Bildfläche reflektiert<br />
diese das seitlich einfallende Tageslicht was mit dem Auslesen eines beschädigten Codes<br />
bei optimalen Lichtverhältnissen gleichzusetzen ist. Die Barcodes besitzen je nach<br />
Codeart unterschiedliche Fähigkeiten perspektivische Verzerrungen und Beschädigungen<br />
auszugleichen. Abschnitt 3.3 erläutert den Aufbau der Codearten und die damit<br />
auftretenden Unterschiede im Lesekomfort.<br />
Der WEITBLICK Code sollte eine möglichst große Flexibilität besitzen. Zur Maximierung<br />
des Lesekomforts wird in Abschnitt 3.4.1 eine Testreihe durchgeführt in der<br />
die Barcodes im Anwendungsfall verglichen werden.<br />
3.2.4 Fazit aus den gegebenen Anforderungen<br />
Zusammenfassend aus der Anforderungsanalyse ergeben sich <strong>für</strong> den WEITBLICK<br />
Code folgende Kriterien:<br />
• hoher Standardisierungsgrad: bereits bestehende Implementierung<br />
in die ZXing-Bildverarbeitungsbibliothek<br />
• Fähigkeit, Zeichen mindestens im ASCII Zeichensatz zu speichern<br />
• Fähigkeit, eine ausreichend hohe Datenmenge (mindestens 55 Zeichen) zu speichern<br />
• hohe Flexibilität beim Auslesen: ausreichend großer Leseabstand und Ausgleich<br />
von perspektivischer Verzerrung und schlechten Lichtverhältnissen<br />
Die Wahl eines geeigneten Codes fordert daher einen Kompromiss aus Lesbarkeit und<br />
Gesamtzeichenanzahl. Die sich aus der Anforderungsanalyse ergebende Datenmenge<br />
aus 3.2.2 legt sich auf Variante 3 aus der Tabelle 3.1 und damit auf eine Gesamtzeichenanzahl<br />
von maximal 55 Zeichen fest. Nach Erläuterung der aus der Anforderungsanalyse<br />
relevanten optischen Marken, wird in der praktischen Testreihe (siehe 3.4.1)<br />
der bestgeeignetste WEITBLICK Code ermittelt.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 11<br />
3.3 Arten von optischen Marken<br />
Wie zu Beginn des Kapitels erwähnt lassen sich optische Marken gemäß ihrer Dimensionen,<br />
in denen die Informationen codiert sind, einteilen. Die einzelnen Codearten<br />
besitzen daher unterschiedliche Spezifika mit Vor- und Nachteilen. Um das Ganze<br />
einzugrenzen, wurde die Ausarbeitung auf diejenigen optischen Marken beschränkt,<br />
welche die im vorigen Abschnitt erläuterten Anforderungen erfüllen (könnten).<br />
3.3.1 Strichcodes<br />
Strichcodes sind eindimensionale Codes, die Informationen in nur einer Dimension in<br />
Form von Strichen codieren. Sie wurden Anfang der 70er Jahre in den USA mit dem<br />
Ziel eingeführt Artikel an der Supermarktkasse schnell und sicher einzuscannen. Bekannte<br />
Handelsstrichcodes wie EAN (European Article Number) oder UPC (Universal<br />
Product Code) sowie noch weitere sind Barcodes bei denen durch einen codierte ID<br />
auf externe Inhalte verwiesen wird. Dadurch lassen sich Artikel weltweit eindeutig zuordnen<br />
und Artikeldaten, wie Artikelname und Preis, aus einer zentralen Datenbank<br />
abfragen. Aus diesem Grund wurden die meisten der linearen Codes <strong>für</strong> numerische<br />
Zeichensätze spezifiziert. Nur wenige Codes, wie beispielsweise der Code-39, Code-93,<br />
Code-128, verwenden einen ASCII Zeichensatz [Len00]. Dieser Abschnitt geht exemplarisch<br />
auf den Code-128 ein, da dieser der fortschrittlichste lineare Code zu sein scheint,<br />
da neuere lizenzpflichtige Standards wie der GS1-128 den Code-128 in seinen technischen<br />
Spezifikationen übernommen und um Inhaltsspezifikationen erweitert haben.<br />
[HBF07, S. 57]<br />
Codeaufbau Code-128<br />
Der Code-128 ist ein alphanumerischer Strichcode. Die Codierung der Zeichen findet in<br />
der Variation der Breiten der Striche und Lücken statt. Ein Zeichen wird beim Code-<br />
128 in elf Module eingeteilt. Ein Strich besteht dabei immer aus einer geraden Anzahl,<br />
eine Lücke aus einer ungeraden Anzahl an Modulen, womit der Code selbstüberprüfend<br />
ist. [Len05, S. 107] Er besitzt drei verschiedene Zeichensätze A, B und C. Die<br />
Zeichensätze A und B besitzen alle alphanumerischen Zeichen, jeweils mit und ohne<br />
Kleinbuchstaben. Der dritte Zeichensatz C ist ein rein numerischer. Wie auf Abb. 3.2<br />
zu sehen, wird der Nutzinhalt Code-128, wie bei fast allen anderen Strichcodes, von<br />
einer Ruhezone und einem Start-und Stoppzeichen umschlossen. Start- und Stoppzeichen<br />
helfen den Lesegeräten (bei linearen Strichcodes sind dies meist Laserscanner)<br />
bei der Bestimmung der Codeart und der Leserichtung. Drei verschiedene Startzeichen<br />
geben an welche der drei Zeichensätze verwendet werden.<br />
Da sich die Informationen lediglich in der Breites des Codes befinden, wirkt sich eine<br />
Vergrößerung der Codehöhe nicht auf den Informationsgehalt aus. Dagegen erhöht sich<br />
mit wachsender Höhe die Lesbarkeit des Codes, um beispielsweise Beschädigungen am<br />
Code ausgleichen zu können. Zudem ist der Code-128, wie auch andere lineare Codes,<br />
mit einer Prüfziffer abgesichert, die eine Art Quersumme der codierten Zeichen ist.<br />
Bei Berechnung der Prüfziffer des Code-128 werden die mit der Position des Nutzzei-<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 12<br />
Abbildung 3.2: Codeaufbau Code-128<br />
chens gewichteten Referenzzahlen (aus der entsprechenden Zeichensatztabelle) addiert<br />
und nach Modulo 103 berechnet. Mit dem Vergleich der errechneten und mitcodierten<br />
Prüfziffer lässt sich überprüfen, ob alle Nutzzeichen des Codes richtig eingelesen<br />
wurden.<br />
Zeichensätze und Datenkapazität<br />
Wie schon in Abschnitt 3.1.1 erläutert, hängt die Anzahl der in einen Code maximal<br />
zu codierenden Zeichen von der Größe des Anwenderzeichensatzes ab. Je kleiner der<br />
Anwenderzeichensatz, desto mehr Zeichen können codiert werden. Dies zeigt auch die<br />
Formel zur Codelängenbestimmung 1 L aus [Len05, S. 109]:<br />
L = ((5, 5Nc + 11Nab + 35)X) + 2R<br />
Anhand der Formel ist zu erkennen, dass <strong>für</strong> eine festgelegte Codelänge erheblich mehr<br />
Zeichen aus Zeichensatz C als aus A oder B codiert werden können. Eine Maximierung<br />
der Informationsdichte wird erreicht, indem je nach Art der codierten Daten innerhalb<br />
des Codes zwischen den drei Zeichensätzen gewechselt wird. Durch Steuerzeichen, die<br />
in den einzelnen Zeichensätzen definiert sind, wird ein Zeichensatzwechsel signalisiert,<br />
um so numerische Zeichen effizient codieren zu können.<br />
Die Eigenschaft der Strichcodes, dass diese mit steigender Anzahl codierter Zeichen<br />
immer breiter werden, hat zur Folge, dass diese immer schlechter von den Lesegeräten<br />
aufgelöst werden. Vor allem Lesegeräte mit CCD-Sensor, wie bei einem Smartphone,<br />
besitzen ein begrenztes, optisches Auflösungsvermögen. Die mit vergrößertem<br />
Leseabstand immer kleiner werdenden Modulbreiten sind ab einem gewissen Abstand<br />
nicht mehr auflösbar. Infolgedessen wird die Lesbarkeit linearer Strichcodes stark eingeschränkt,<br />
wie die Testreihe in Abschnitt 3.4.1 zeigt.<br />
Zusammenfassend lässt sich sagen, dass das WEITBLICK-Projekt gemäß der Anforderungsanalyse<br />
einen maximalen Leseabstand fordert und damit, aufgrund der erhöhten<br />
Breite von Strichcodes, die maximale Anzahl zu codierender Nutzzeichen beschränkt.<br />
1 Nc,Nab: Anzahl der Zeichen aus den Zeichensätzen C und A/B, X: Modulbreite, R: Ruhezone (10X)<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 13<br />
Abbildung 3.3: ” Projekt WEITBLICK“ codiert mit dem Stapelcode PDF417 (erstellt<br />
mit [TEC11])<br />
3.3.2 Stapelcodes<br />
Durch die in Strichcodes begrenzte Anzahl an zu codierenden Nutzzeichen wurden neue<br />
Codes entwickelt, die die bisherigen linearen Strichcodes in mehreren Zeilen stapeln,<br />
um so die Informationsdichte zu erhöhen. Diese Art von zweidimensionalen Strichcodes<br />
werden daher Stapelcodes genannt. Eine in der Logistik, beim Transport und<br />
Paketdiensten häufig verwendete Stapelcodeart ist PDF417, wie Abb. 3.3 beispielhaft<br />
zeigt.<br />
Wie auch lineare Strichcodes werden Stapelcodes von einer Ruhezone und jeweils<br />
einem Start- und Stoppzeichen umschlossen. Der Code kann insgesamt drei bis 90 Zeilen<br />
umfassen. Dadurch kann neben einer zusätzlichen Datenkompression eine größere<br />
Anzahl an Zeichen codiert werden. 2 Des Weiteren kommen Fehlerkorrekturverfahren<br />
wie der Reed Solomon Code in mehreren Fehlerkorrekturstufen zum Einsatz, was den<br />
Code sehr datensicher macht. [Len05, S. 129]<br />
Die ZXing-Bildverarbeitungsbibliothek führt den PDF417 Code als unterstütztes<br />
Codeformat auf. Leider konnte das PDF417-Format in der Testreihe in Abschnitt 3.4.1<br />
vom ZXing Barcode Scanner nicht erfolgreich eingescannt werden. Es wird an dieser<br />
Stelle daher auf eine nähere Erläuterung des Codes verzichtet.<br />
3.3.3 Matrixcodes<br />
Strich- und Stapelcodes besitzen aufgrund Ihrer Eigenschaft, die Informationen nur<br />
in ihrer Breite zu speichern, eine gewisse vertikale Redundanz. Die Höhe des Codes<br />
trägt dabei nicht zum Informationsgehalt bei. Um die Informationsdichte noch weiter<br />
zu erhöhen und den Platz effizienter zu nutzen, wurden echt-zweidimensionale Matrixcodes<br />
bzw. Punktcodes entwickelt. Dem Namen nach werden hier die Informationen in<br />
Form von Punkten bzw. Pixeln 3 in einer Matrixstruktur angeordnet. Ein ausgefüllter<br />
schwarzer Pixel würde als binärer Wert ” 1“ interpretiert werden. Zum Auslesen der Matrixcodes<br />
werden CCD-Matrixsensoren verwendet, wodurch diese auch omnidirektional<br />
lesbar sind.<br />
Neben zahlreichen proprietären Formaten wie zum Beispiel BeeTag, Shotcode, EZ-<br />
Code haben die standardisierten Codeformate Aztec Codes, QR Code und Data Matrix<br />
Code die weiteste Verbreitung gefunden [Heg10, S. 48]. Alle drei Codeformate werden in<br />
der Dokumentation der ZXing-Bibliothek unter den unterstützten Formaten genannt.<br />
Leider konnte der Aztec Code in der Testreihe unter 3.4.1 mit dem ZXing Barcode<br />
2numerisch: max 2710 Ziffern, alphanumerisch: 1850 Zeichen, ASCII: 1400 Zeichen, ISO: 1108 Bytes<br />
[Len05, S. 120]<br />
3abhängig von Codeart, bspw. bei Maxicode auch in hexagonaler Form<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 14<br />
Abbildung 3.4: Data Matrix und QR Code: Suchmuster mit Taktzellen (entnommen<br />
aus [Len05, S. 140 und 150])<br />
Scanner nicht gelesen werden. Es wird in diesem Abschnitt daher auf die Erläuterung<br />
des Aztec Codes verzichtet.<br />
Der im Jahre 1989 von der Firma International Data Matrix entwickelte gleichnamige<br />
Code hat sich bereits in vielen Branchen wie der Industrie, der Logistik und bei<br />
Paketdiensten durchgesetzt. In vielen industriellen Bereichen wird dieser zur Kennzeichnung<br />
von Produkten eingesetzt. Kleinere Produkte werden mittels Lasergravur<br />
gekennzeichnet, wodurch die Anwendungsmöglichkeiten sehr vielfältig sind. In weiteren<br />
Branchen findet der Data Matrix bspw. beim elektronischem Ticketing oder bei<br />
der elektronischen Briefmarke der Deutschen Post Verwendung. [Len05, S. 131] Wohingegen<br />
der Data Matrix eher im europäischem Raum verbreitet ist, hat sich der QR<br />
Code (Quick-Response Code) eher im asiatischen Raum durchgesetzt. Er wurde von<br />
der Firma Denso Wave in Japan ursprünglich <strong>für</strong> die Automobilindustrie entwickelt.<br />
Sowohl Data Matrix als auch QR Code sind in ihren Anwendungsgebieten sowie in<br />
ihrem Aufbau sehr ähnlich. Beide Codes wurden patentiert, sind aber durch Nichtausübung<br />
der Patentrechte kommerziell verwendbar [Wan11, S. 34]. Nachfolgend werden<br />
beide Codearten auf ihre Merkmale untersucht und verglichen.<br />
Codeaufbau Data Matrix und QR Code<br />
Beide Codes besitzen eine quadratische Matrixstruktur. Die Zellen der Matrizen sind<br />
schwarze oder weiße Pixel, die jeweils ein Bit darstellen. Zur Erfassung der Lage und<br />
der Position sind Suchmuster integriert, wodurch auch perspektivische Verzerrungen<br />
ausgeglichen werden. Abb. 3.4 zeigt die Suchmuster der beiden Codevarianten Data<br />
Matrix EC200 und QR Code v2 4 im Vergleich. Da beide Suchmuster sehr charakteristisch<br />
sind, stellen diese ein Hauptunterscheidungsmerkmal beider Codes dar.<br />
Die linke Seite der Abb. 3.4 zeigt das L-förmige Suchmuster mit einer zusätzlichen,<br />
leeren, weißen Zelle in der rechten oberen Ecke (welche die Kennung <strong>für</strong> die aktuelle,<br />
zweite Variante EC200 darstellt) des Data Matrix zu sehen. Das Suchmuster dient<br />
dem schnellen Auffinden des Codes. Die nicht zum L gehörenden, alternierend hellen<br />
und dunklen Zellen sind die sogenannten Taktzellen. Dadurch kann beim Decodieren<br />
des Codes eine Referenzmatrix erzeugt werden, die über die eingelesene Matrix gelegt<br />
4 EC200 und v2 stehen <strong>für</strong> die verbesserten Versionen der ursprünglichen Codespezifikationen<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 15<br />
wird. Damit wird festgestellt, ob es sich um eine helle oder eine dunkle Zelle handelt,<br />
d. h. ob eine binäre 1 oder 0 codiert wurde. [Len05, S. 128 f.]<br />
Der QR Code hat im Gegensatz zum Data Matrix ein viel auffälligeres Suchmuster.<br />
Dem Namen des Codes nach soll der Code damit noch schneller eingelesen werden<br />
können. Es besteht aus drei charakteristischen 3 mal 3 breiten Zellen mit einem weißen<br />
und einem schwarzen Zellrand. Zusätzlich hilft eine einzelne Orientierungszelle mit<br />
einem weißen und schwarzen Zellrand im rechten unteren Bereich des Codes dazu,<br />
perspektivische Verzerrungen ausgleichen zu können. Das Taktmuster dient wie beim<br />
Data Matrix zur Erzeugung einer Referenzmatrix und zum Decodieren des Codes.<br />
[Len05, S. 151 f.]<br />
In den verbleibenden Platz der Matrixcodes werden neben den eigentlichen Datenzellen<br />
noch Versions- und Steuerinformationen untergebracht. Für genaue Definitionen<br />
sei hier auf die Spezifikationen in ISO/IEC 16022:2000/24720:2008 (Data Matrix) und<br />
ISO/IEC 18004:2006 (QR Code) verwiesen.<br />
Aufgrund des größeren Suchmusters des QR Codes hat der Data Matrix einen entscheidenden<br />
Vorteil: Bei der Codierung des gleichen Inhalts ist der Data Matrix nach<br />
[Son10, S. 31] gegenüber dem QR Code zwischen 30% bis 60% platzeffizienter, wie<br />
auch auf Abb. 3.5 zu erkennen ist.<br />
Abbildung 3.5: ” Projekt WEITBLICK“ codiert in Data Matrix und QR Code, Vergleich<br />
der Platzeffizienz<br />
Wird im Hinblick auf die Wahl einer optischen Marke der Usecase der Aufgabenstellung<br />
betrachtet, so hat die Platzeffizienz des Data Matrix folgende Konsequenzen:<br />
Durch einen bestimmten, maximal zur Verfügung stehenden Platz und einer festgelegten,<br />
bestimmten Anzahl an zu codierender Zeichen, werden die beiden Barcodes auf<br />
die gleiche Größe skaliert. Das bedeutet <strong>für</strong> den Data Matrix, dass die Zellgröße (Größe<br />
einer elementaren Zelle) zunimmt bzw. die des QR Codes abnimmt. Infolgedessen<br />
liegt die Vermutung nahe, dass bei begrenzter optischer Auflösung des Lesegerätes die<br />
Lesbarkeit des Data Matrix besser wäre. Inwiefern dies dem besseren Suchmusters des<br />
QR Codes entgegensteht, zeigt die Testreihe in Abschnitt 3.4.1.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 16<br />
Zeichensätze und Datenkapazität<br />
Die beiden Matrixcodes Data Matrix und QR Code sind in der Lage den numerischen,<br />
alphanumerischen, ASCII und ISO Zeichensatz zu codieren. Aufgrund der asiatischen<br />
Herkunft kann der QR Code zudem den Zeichensatz Kanji codieren. [Len05, S. 132]<br />
Um die Datensicherheit zu gewährleisten, wird bei beiden Codearten ein Reed Solomon<br />
Code verwendet.<br />
Durch ihre hohen Informationsdichten können beide Barcodes je nach verwendeten<br />
Zeichensätzen eine größere Zeichenanzahl speichern. Mit einer maximalen Matrixgröße<br />
von 144 mal 144 kann der Data Matrix bis zu 3116 numerische, 2335 alphanumerische<br />
Zeichen oder 1556 Bytes speichern. [Len05, S. 133] Der QR Code ist mit einer Matrixgröße<br />
von 21 bis 177 Zellen in der Lage, 7089 numerische, 4296 alphanumerische<br />
Zeichen oder 2953 Bytes zu codieren. [Len05, S. 147] Hierbei sei angemerkt, dass die<br />
Zahlen alle nur von theoretischem Belange sind. Aufgrund technischer Grenzen (begrenzte<br />
optische Auflösung bei den Herstellungs- und Einleseverfahren) und der damit<br />
verbundenen begrenzten Lesbarkeit ist die Nutzzeichenanzahl eingeschränkt nutzbar.<br />
Eine weitere Vergrößerung der Datenkapazität wird wie in Abschnitt 3.3.3 durch dreibzw.<br />
vierdimensionale Codes erreicht.<br />
Sowohl Data Matrix als auch QR Code finden im Bereich des Mobile Tagging eine<br />
weite Verbreitung. Beim mobilen Tagging ( ” Markieren“) werden Informationen in<br />
Barcodes codiert, um diese <strong>für</strong> Mobiltelefone zur Verfügung zu stellen. Dabei kommen<br />
direkte sowie indirekte Verlinkungs-Varianten zum Einsatz. Informationen können<br />
entweder als Texte, Kontaktinformationen (entspricht einer Visitenkarte im Codeformat),<br />
Termine, WLAN-Netzwerk Daten direkt codiert oder durch Internetadressen,<br />
Geodaten, Applikationen in den App Stores (abhängig vom jeweiligen verwenden<br />
Smartphone-System), YouTube-Videos, Twitter- oder Facebook-Accounts auf Informationen<br />
im Internet indirekt verlinkt werden. Damit ergeben sich eine Vielzahl von<br />
Anwendungsgebieten. Um eine konsistente Interpretation der optischen Marken zu gewährleisten,<br />
geben Präfixe, vergleichbar mit dem Application Identifier der GTIN-14<br />
Nummern (siehe 3.1.5), an, welcher Inhalt im Code gespeichert ist. Der datenbezeichnende<br />
Präfix wird mit den eigentlichen Daten als reiner Text in den Code untergebracht.<br />
Konventionen zur Codierung der verschiedenen Inhalte fasst [ZXi11b] zusammen.<br />
Da es sich beim WEITBLICK Dienst um einen proprietären Inhalt handelt, werden<br />
die Dienstinformationen als reine Textinformationen im Code gespeichert. Wie die Datenfelder<br />
in der optischen Marke als Text gespeichert und diese durch das Smartphone<br />
decodiert werden, wird in Kapitel 4 erläutert.<br />
3D/4D Codes<br />
Zur weiteren Erhöhung der Datenkapazität von zweidimensionalen Matrixcodes wurden<br />
dreidimensionale Codes entwickelt. Die dritte Dimension bildet dabei einen Farbkanal,<br />
in dem die Elementarzellen codiert sind. Dadurch können noch weitere Informationen<br />
untergebracht werden. Meist bauen diese auf die Matrixcodes Data Matrix<br />
oder QR Code auf, es gibt aber auch proprietäre optische Marken. So z. B. der von Mi-<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 17<br />
crosoft entwickelte High Capacity Color Barcode (HCCB). Durch eine Verschachtelung<br />
von farbigen Dreiecken ist die Informationsdichte drei mal so hoch wie die des Data<br />
Matrix. [TCK10, S. 89] Der HCCB wurde im Jahre 2007 von der Standardisierungsbehörde<br />
ISAN International Agency (ISAN-IA) in Vereinbarung mit Microsoft lizenziert<br />
und steht damit den offenen Formaten Data Matrix und QR Code gegenüber [TCK10,<br />
S. 92].<br />
Die Erweiterung des Data Matrix auf einen Farbkanal als dritte und sogar vierte<br />
Dimension hat die Bauhaus <strong>Universität</strong> in Weimar (siehe [LT07]) untersucht. Die<br />
vierte Dimension stellt dabei eine Integration der Zeit dar und soll die Datenkapazität<br />
noch weiter erhöhen. In einer praktischen Versuchsreihe mit einem Nokia 6630<br />
mit VGA-CCD-Kamera (640 mal 480 Pixel) wurde bei unerfahrenen Benutzern bei<br />
einer Übertragungssicherheit von 82% eine Übertragungsgeschwindigkeit von 23 Zeichen<br />
pro Sekunde ermittelt [LT07, S. 11]. Schwierigkeiten gibt es bei den Verfahren,<br />
wenn Darstellungsgeräte mit geringerer Wiederholungsrate von unter 85 Hz (ältere<br />
CRT-Monitore, ältere Röhrenfernsehgeräte mit 60 Hz) verwendet werden [LT07, S. 4].<br />
Die zeitlich aufeinanderfolgenden Codes können nicht richtig erkannt werden und es<br />
kommt zu Fehlinterpretationen. Gemäß der Aufgabenstellung dieser Arbeit wäre eine<br />
Verwendung eines Röhrenfernsehers mit 60 Hz (älterer Bauart) denkbar. Demnach<br />
kommt die Verwendung einer vierten, zeitlichen Dimension <strong>für</strong> den WEITBLICK Code<br />
nicht in Frage.<br />
Ein weiterer Nachteil von 3D/4D Codes ist die mangelnde Verbreitung. Der Bereich<br />
des Mobile Tagging wird von den zweidimensionalen Codeformaten Data Matrix und<br />
QR Code dominiert. Drei- und vierdimensionale Codes werden kaum bis gar nicht verwendet.<br />
Demnach konnte in keinem der App Stores der Smartphone-Betriebssysteme 5<br />
eine nennenswerte Barcode Scanner App ausfindig gemacht werden, die dreidimensionale<br />
Codes liest. Einzig die HCCB Reader App von Microsoft wurde im Android<br />
Market als 3D Code Scanner gefunden.<br />
Zusammenfassend lässt sich sagen, dass der HCCB-Code und die dreidimensionalen<br />
Data Matrix und QR Codes wegen fehlender Implementierungsmöglichkeiten und<br />
mangelnder Verbreitung als WEITBLICK Codes ebenfalls nicht geeignet sind.<br />
3.4 Praktischer Vergleich der Codes<br />
Nach der Anforderungsanalyse (siehe 3.2) und der Erläuterung der verschiedenen Arten<br />
von optischen Marken im letzten Abschnitt, erweisen sich der lineare Strichcode<br />
Code-128 und die beiden zweidimensionalen Matrixcodes Data Matrix und QR Code<br />
als mögliche WEITBLICK Codes. Die drei Barcodes erfüllen die festgelegten, theoretischen<br />
Anforderungen. Damit ist die Lesbarkeit der optischen Marke das entscheidende<br />
Auswahlkriterium. Um den Code mit der besten Lesbarkeit ermitteln zu können, werden<br />
in diesem Abschnitt die drei Codes in einer praktischen Testreihe gegenübergestellt.<br />
5 Apple iOS, Microsoft Windows Phone 7, Nokia Symbian, RIM Blackberry OS, Samsung Bada<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 18<br />
3.4.1 Vergleich der Codes in einer Testreihe<br />
Die Lesbarkeit von optischen Marken ist stark davon abhängig, wie viele Zeichen darin<br />
codiert sind. In Abschnitt 3.2.2 wurde bereits die Gesamtzeichenanzahl auf 55 begrenzt.<br />
Um dem Nutzer ein einwandfreies Nutzungserlebnis zu bieten, wird der komfortabelste<br />
Fall betrachtet. Folglich sollte der Leseabstand vom Sitzplatz zum Fernseher maximal<br />
groß sein und die optische Marke auch von Positionen schräg zur Bildfläche des Fernsehgeräts<br />
abgescannt werden können. Durch die Testreihe soll damit der maximale<br />
Leseabstand sowie der maximale (horizontale) Betrachtungswinkel ermittelt werden.<br />
(Der vertikale Betrachtungswinkel wird auf 0 ◦ festgesetzt.) Die Testbedingungen beschreiben<br />
folgende Punkte:<br />
• Verwendetes Smartphone: HTC Wildfire mit 5 MP CCD-Kamera und der Android<br />
Firmware 2.2.22<br />
• Verwendete Barcode-Scan App: ZXing Barcode Scanner<br />
• Darstellungsgerät: analoger Röhrenfernseher mit einer Diagonale von 42 cm<br />
• Darstellung eines von einem PC analog eingespeisten PAL Signals (mit einer<br />
äquivalenten Auflösung von 768 mal 576 Bildpunkten)<br />
• Effektive Bildfläche der Codes: Breite des Data Matrix und QR Codes: 20,5 cm;<br />
Codelänge/-höhe des Code-128 (mit nur fünf Ziffern): 29,5/14,5 cm<br />
• Seitlich einfallendes Tageslicht<br />
Damit wurde vom Worst Case ausgegangen: Röhrenfernseher werden heutzutage<br />
nicht mehr produziert. Stattdessen besitzen immer mehr Haushalte einen hochauflösenden<br />
Flachbildfernseher, der zudem mit einem qualitativ hochwertigeren digitalen<br />
Fernsehsignal versorgt wird. Da das HTC Wildfire mit seiner 5 MP Kamera eher zu<br />
den Smartphones aus der (Low-Budget)Einsteiger-Klasse zählt, ist schließlich davon<br />
auszugehen, dass die eingebaute 5 MP CCD-Kamera ebenfalls nicht zu den besten<br />
ihrer Klasse gehört.<br />
Zur Ermittlung des maximalen Leseabstands wurde bei der Testreihe folgendermaßen<br />
vorgegangen:<br />
1. Beginn der Ermittlung durch Scannen (aus freier Hand) aus übergroßem Abstand,<br />
sodass der Code nicht erkannt werden kann<br />
2. Schrittweise Annäherung an den Fernseher, bis der Barcode nach einem Annäherungsschritt<br />
innerhalb von 10 Sekunden erkannt wird<br />
3. Notierung des Abstands<br />
4. Wiederholung der Ermittlung mit allen drei Codearten mit Variation des horizontalen<br />
Betrachtungswinkels (0 ◦ , 25 ◦ und 35 ◦ )<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 19<br />
Winkel<br />
Code<br />
0◦ 25◦ 35◦ Code-128 90 85 75<br />
Data Matrix 115 90 -<br />
QR Code 135 115 65<br />
Tabelle 3.2: Vergleich des maximalen Leseabstands (in cm) der Codes Code-128, Data<br />
Matrix, QR Code in Abhängigkeit vom horizontalen Betrachtungswinkel<br />
Aus der Testreihe wurden die Ergebnisse aus Tab. 3.2 ermittelt. Die Gesamtzeichenanzahl<br />
musste beim Code-128 auf die fünfstellige ID beschränkt werden, da der<br />
Code-128 bei der Codierung von vollen 55 Zeichen unverhältnismäßig breit geworden<br />
wäre. Ein folglich zu kurzer Leseabstand würde <strong>für</strong> den Usecase keinen Sinn ergeben.<br />
Angemerkt sei hierbei noch, dass das Auslesen von Strichcodes mit dem ZXing Scanner<br />
in einer bestimmten Lage erfolgen muss. Im Scandialog wird dabei ein fiktiver Laserstrahl<br />
eingeblendet, der die Striche quer durchsetzen muss. Die beiden Matrixcodes<br />
sind dagegen omnidirektional lesbar.<br />
3.4.2 Auswertung der Testreihe und Auswahl der optischen Marke<br />
Werden die Ergebnisse aus 3.2 bildlich dargestellt, ergibt sich die Abb. 3.6. Die roten<br />
Kreuze stellen die Messpunkte dar. Daraus ergibt sich <strong>für</strong> die drei optischen Marken<br />
jeweils ein approximierter Bereich innerhalb dessen die Lesbarkeit des auf dem Fernsehgerät<br />
dargestellten Code gewährleistet ist. Dabei liegt die Annahme zugrunde, dass<br />
die Randbedingungen auf beiden Seiten gleich sind und der Bereich damit symmetrisch<br />
ist.<br />
115 cm<br />
135 cm<br />
90 cm<br />
TV<br />
QR Code<br />
Data Matrix<br />
Code 128<br />
Messpunkt<br />
Abbildung 3.6: Anschaulich dargestellte Testreihe (aus Tab. 3.2) des praktischen Vergleichs<br />
von Code-128, Data Matrix und QR Code<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
3 Diskussion der optischen Marke 20<br />
Der lineare Code-128 zeigt trotz der nur fünf codierten Ziffern die schlechteste Lesbarkeit.<br />
Als die optische Marke mit der besten Lesbarkeit erweist sich der QR Code. In<br />
der Testreihe hat dieser gegenüber dem Data Matrix eine um 20 cm weitere Lesbarkeit<br />
und zudem ein besseres Verhalten in Abhängigkeit des horizontalen Betrachtungswinkels.<br />
Der Vorteil des Data Matrix gegenüber dem QR Code platzeffizienter zu sein,<br />
um damit durch eine größere Elementarzellgröße besser aufgelöst werden zu können,<br />
gleicht den Vorteil des besseren Suchmusters des QR Codes nicht aus.<br />
Die Wahl der optischen Marke fällt hiermit auf den QR Code.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 21<br />
4 Praktische Umsetzung<br />
4.1 Anforderungen an das Dienstbuchungssystem<br />
Im letzten Abschnitt hat sich der QR Code als bestgeeignetste optische Marke herausgestellt.<br />
Es verbleiben laut Aufgabenstellung aus Kapitel 2 noch folgende drei Punkte:<br />
3. Realisierung einer Anwendung auf dem Smartphone zur Erkennung der optischen<br />
Marke<br />
4. Übermittlung der Buchungsinformation an einen Server<br />
5. Anruf einer mitcodierten Telefonnummer<br />
Demnach ergibt sich die Aufgabe eine Anwendung auf einem Smartphone-Betriebssystem<br />
zu entwickeln, die einen QR Code einscannt und die codierten Informationen<br />
weiter verarbeitet. Nachdem die eingelesenen Informationen interpretiert wurden, wird<br />
eine entsprechende Dienstleistung angezeigt. Der Nutzer hat dann die Möglichkeit den<br />
Dienst entweder direkt über ein IP-Netz (Internet über WLAN oder UMTS) zu buchen<br />
oder sich mit einem Gesprächspartner persönlich verbinden zu lassen, falls er noch<br />
Fragen zur angebotenen Dienstleistung hat. Aus dieser Aufgabenstellung ergibt sich<br />
ein Dienstbuchungssystem, das die Buchung der Smartphone-Clients verarbeiten kann.<br />
An das Dienstbuchungssystem werden bestimmte Anforderungen gestellt, auf die in<br />
den folgenden Absätzen näher eingegangen wird.<br />
Zur Buchung eines Dienstes ist die Integrität der angezeigten Dienstleistunginformationen<br />
sicherzustellen. Dies ist vor allem dann wichtig, wenn sich die Dienstleistung<br />
vor der Ausstrahlung des QR Codes in einer Fernsehsendung kurzfristig ändert. Um<br />
zu verhindern, dass der Nutzer eine Dienstleistung auf Basis von nicht mehr aktuellen<br />
Dienstinformationen falsch buchen kann, hat vor Anzeige und Buchung des Dienstes<br />
die Dienstabfrage von einem zentralen Server zu erfolgen. Durch die Integrität der<br />
Dienstinformationen ist gleichzeitig die Authentizität des angezeigten Dienstes gesichert.<br />
Möchte der Nutzer eine direkte Dienstbuchung vornehmen, so wird vom Client eine<br />
Nachricht an eine vom WEITBLICK-Projekt entwickelte Kommunikations-Middleware<br />
gesendet, die die Nachricht wiederum an einen Buchungsserver weiterleitet. Die Middleware<br />
ist genau genommen eine Message Oriented Middleware (MOM), mit Hilfe<br />
welcher Nachrichten asynchron versendet und empfangen werden können, unabhängig<br />
von welcher Netzwerkschnittstelle die Nachrichten kommen. Das WEITBLICK-<br />
Projekt verwendet dazu eine von der Softwarefirma Oracle entwickelte Open-Source-<br />
MOM namens Open Message Queue (openMQ). Durch die Middleware ist damit eine<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 22<br />
gemeinsame Kommunikationsschnittstelle geschaffen, die Telefondienste sowie auch Internetdienste<br />
miteinander vereint und kommunizieren lässt.<br />
Eine weitere wichtige Anforderung stellt die Authentifizierung und Autorisierung des<br />
Nutzers dar. Hierbei muss bei der Buchung eines Dienstes festgestellt werden von wem<br />
der Dienst gebucht wird. Ein reines Senden der UserID würde nicht ausreichen, um<br />
die Authentizität des Nutzer zu gewährleisten. Das System wäre im Falle der Beschaffung<br />
einer fremden ID anfällig <strong>für</strong> missbräuchliche Zugriffe. Es muss demzufolge eine<br />
serverseitige Nutzerauthentifizierung mit einer UserID und einem geheimen Passwort<br />
stattfinden. Ist der Nutzer authentifiziert, muss dieser noch autorisiert werden, um<br />
bestimmte Dienste buchen zu können. Eine Nutzerauthentifizierung erfordert sowohl<br />
eine client- als auch eine serverseitige Anpassung. Ebenso muss die Dienstbuchung<br />
über eine gesicherte, verschlüsselte Verbindung erfolgen, um missbräuchliche Nutzung<br />
zu verhindern.<br />
Zusammenfassend werden als Anforderungen an das Dienstbuchungssystem folgende<br />
Punkte festgelegt:<br />
• Buchung des Dienstes über eine vom WEITBLICK-Projekt entwickelte<br />
Kommunikations-Middleware<br />
• Sicherstellung der Authentizität und Integrität der zu buchenden Dienste<br />
• Authentifizierung des Nutzers<br />
• Gesicherte Übertragung der Dienstbuchung<br />
4.2 Struktur des Dienstbuchungssystems<br />
Die im letzten Abschnitt festgelegten Anforderungen erfordern eine getrennte Betrachtung<br />
der Client- und Serverseite des Dienstbuchungssystems, wie in Abb. 4.1 dargestellt.<br />
QR Code<br />
1##Kaeefahrt##49-1234-5678 Smartphone<br />
Android OS<br />
Internet über WLAN,UMTS<br />
Internet<br />
Client<br />
gagarin.e-technik.tu-ilmenau.de<br />
JMS Nachricht<br />
mit UserLogin+ServiceID<br />
JMS Nachricht<br />
mit Bestätigung<br />
SQL Anfrage<br />
mit ID<br />
SQL Antwort<br />
mit Dienst<br />
openMQ Server<br />
Queue: DVB_Rueckkanal<br />
mySQL Server<br />
Dienstserver<br />
Server<br />
Abbildung 4.1: Struktur des Dienstbuchungssystems<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 23<br />
Für die Anfrage und Buchung eines Dienstes muss das Smartphone über WLAN<br />
bzw. UMTS mit dem Internet (als gemeinsamer Übertragungskanal von Client und<br />
Server) verbunden sein. Der zentrale Server ist über einen festen Hostnamen (hier<br />
gagarin.e-technik.tu-ilmenau.de) über das Internet erreichbar. Auf diesem Server laufen<br />
verschiedene Anwendungen, mit denen der Android Client über einen bestimmten Port<br />
kommuniziert. Zur Vereinfachung werden im Folgenden die einzelnen Anwendungen als<br />
einzelne Serverinstanzen betrachtet, obwohl diese gemeinsam auf dem zentralen Server<br />
unter gagarin.e-technik.tu-ilmenau.de erreichbar sind.<br />
4.2.1 Client des Dienstbuchungssystems<br />
Die Clientseite besteht aus dem QR Code, in dem der Dienst codiert ist, und dem<br />
Android Client mit der WEITBLICK App. Die Erzeugung des QR Codes muss bereits<br />
im Produktionsstudio erfolgen und in das Fernsehbild mit eingeblendet werden. Eine<br />
einfache Möglichkeit die QR Code-Generierung in digitale Compositing-Systeme 1 zu<br />
implementieren wird in Abschnitt 4.4 erläutert.<br />
4.2.1.1 Konventionen zur Generierung des QR Codes<br />
Um sowohl <strong>für</strong> die Generierung als auch <strong>für</strong> die Interpretation der QR Codes ein einheitliches<br />
Format zu schaffen, müssen <strong>für</strong> die in den QR Code codierten Informationen<br />
Konventionen getroffen werden. Der Inhalt wurde bereits in 3.2.2 ausreichend diskutiert.<br />
Dieser besteht aus einer fünfstelligen ID, einem Kurztitel sowie einer Telefonnummer<br />
aus insgesamt 55 Zeichen. Nachdem der QR Code vom Smartphone eingescannt<br />
wurde, liegt der Inhalt als Zeichenkette vor. Um ID, Kurztitel und Telefonnummer<br />
voneinander trennen zu können, sind Trennzeichen zwischen den Inhalten einzufügen.<br />
Der Aufbau des QR Code-Inhalts setzt sich <strong>für</strong> einen Dienst beispielhaft wie folgt zusammen:<br />
1##Kaffeefahrt##49-1234-5678<br />
(Dienst mit ID=1, Kurztitel=“Kaffeefahrt“ und Telefonnummer ” 49-1234-5678“)<br />
4.2.1.2 Android als mobiles Betriebssystem<br />
In Kapitel 3 wurde bereits vorweggenommen, dass es sich bei der WEITBLICK App<br />
um eine Anwendung handelt, die auf dem mobilen Betriebssystem Android OS basiert.<br />
Android ist ein von Google veröffentlichtes Betriebssystem <strong>für</strong> mobile Endgeräte<br />
wie Smartphones, Netbooks und Tablets. Google hat sich mit 33 anderen Mitgliedern<br />
der Open Handset Alliance zum Ziel gesetzt ein frei verfügbares und quelloffenes Betriebssystem<br />
zu entwickeln. Hersteller von mobilen Endgeräten können Android <strong>für</strong><br />
ihre Geräte kostenlos verwenden. Laut einer Marktforschungsstudie der Firma Canalys<br />
kletterte der Marktanteil an Smartphone-Neuverkäufen von Android mit 32,9% an<br />
1 Compositing bezeichnet das Zusammenmischen verschiedener Bildteile<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 24<br />
erste Stelle, womit die Neuverkäufe von Android-Smartphones vor Nokias Symbian<br />
und RIMs Blackberry liegen [Can11].<br />
Aus technischer Sicht besteht Android aus dem Betriebssystem, einem Anwendungs-<br />
Framework und zahlreichen Schlüsselanwendungen (Telefonieanwendung, Kontaktmanager,<br />
Kalender, Internetbrowser usw.). Es baut auf einem Linux Kernel 2.6 auf. Die<br />
Laufzeitumgebung ist auf der virtuellen Maschine Dalvik Virtual Machine (DVM) realisiert.<br />
Die DVM wurde von einem Google Mitarbeiter namens Dan Bornstein entwickelt.<br />
Im Gegensatz zur Java Virtual Machine (JVM) führt sie einen vorher konvertierten<br />
DEX-Bytecode (DEX = dalvik executables) anstelle eines Java Bytecodes aus. [BP09,<br />
S. 17 f.] Aus diesem Grund und dem der fehlenden Namensgebung ” Java“, umgeht<br />
Android lizenzrechtliche Probleme mit dem Lizenzinhaber Oracle 2 .<br />
Für die Entwicklung einer Android Applikation wird der Quellcode wie üblich in Java<br />
geschrieben, ein normaler Java Compiler übersetzt diesen Code und das Tool ” dx“ des<br />
Android Standard Development Kit (SDK) konvertiert die Java-compilierte .class in<br />
den Android-üblichen DEX-Bytecode. Damit kann jede Java-Entwicklungsumgebung<br />
zur Erstellung einer Android Applikation verwendet werden. Benötigt wird neben einer<br />
Java-SDK zusätzlich die Android-SDK, die von der offiziellen Android Developers<br />
Homepage unter [Goo11] zu beziehen ist. Zur Entwicklung der Android WEITBLICK<br />
App wurde die quelloffene, integrierte Entwicklungsumgebung Eclipse verwendet. Für<br />
eine Installationsanleitung des Android-SDK, eine API-Dokumentation (API steht <strong>für</strong><br />
Application Program Interface) sowie Codebeispiele und alle weiteren Hinweise zur<br />
Android Entwicklung sei an dieser Stelle auf die offizielle Android Developers Homepage<br />
[Goo11] verwiesen. Dies gilt folgend <strong>für</strong> alle weiteren Android Erläuterungen, falls<br />
nicht anders vermerkt.<br />
4.2.1.3 Fehlende Java-Bibliotheken<br />
Mobile Endgeräte wie Smartphones, Netbooks und Tablets sind <strong>für</strong> den mobilen Betrieb<br />
ausgelegt. Daher sind sie in ihren Ressourcen, wie bspw. einer begrenzten Akkulaufzeit<br />
sowie einer beschränkten Rechenleistung und einem beschränkten Speicher,<br />
limitiert. Android wurde daher <strong>für</strong> einen möglichst ressourcensparsamen Betrieb optimiert.<br />
Folglich wurde nicht die vollständige Java-API übernommen.<br />
Demnach wurde bei der Erstellung der WEITBLICK App festgestellt, dass die <strong>für</strong> die<br />
Erstellung einer JMS-Nachricht zwingend benötigte javax.naming Bibliothek von Android<br />
nicht unterstützt wird. Eine einfache Einbindung aus der Java-API schlägt fehl,<br />
da es unter den Paketen zu viele Abhängigkeiten gibt. 4.2.2.1 erläutert den Standard<br />
JMS und wie der Android Client trotz fehlender Unterstützung mit der Middleware<br />
kommuniziert.<br />
Die Dienstabfrage soll der Android Client wie in Abb. 4.1 über SQL-Datenbankabfrage<br />
an einen mySQL-Datenbankserver stellen. Eine solche externe SQL Anfrage<br />
stellt <strong>für</strong> einen Android-Client einen besonders ressourcenintensiven Prozess dar und<br />
wird aus diesem Grund nicht unterstützt. Für die Speicherung lokaler Daten stellt<br />
Android stattdessen eine lokale, ressourcensparsame, relationale Datenbank SQLite<br />
2 ursprünglich Sun, wurde Anfang 2010 aber von Oracle übernommen<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 25<br />
bereit. Eine Dienstanforderung über eine externe Datenbank wurde nichtsdestotrotz<br />
über einen Web-Service in Form eines PHP-Skripts 3 , wie in 4.2.2.2 erläutert, realisiert.<br />
4.2.2 Server des Dienstbuchungssystems<br />
Aus dem Schluss des letzten Abschnitts sind aufgrund fehlender Java-Bibliotheken<br />
im Android System Anpassungen an die Serverstruktur des Dienstbuchungssystem<br />
nötig, damit der Android Client sowohl <strong>für</strong> die Abfrage als auch <strong>für</strong> die Buchung<br />
des Diensts mit dem Server kommunizieren kann. Beide Anpassungen schalten eine<br />
weitere Serverinstanz zwischen Client-openMQ Server und Client-SQL Server. Das<br />
Dienstbuchungssystem wird dann wie folgt erweitert:<br />
QR Code<br />
1##Kaeefahrt##49-1234-5678<br />
Client<br />
Internet<br />
Smartphone<br />
Android OS<br />
Internet über WLAN,UMTS<br />
HTTPS Anfrage (SSL)<br />
mit UserLogin+ServiceID<br />
HTTPS Antwort (SSL)<br />
mit Bestätigung<br />
HTTP Anfrage<br />
mit ID<br />
HTTP Antwort<br />
mit Dienst<br />
gagarin.e-technik.tu-ilmenau.de<br />
UMS Server<br />
Tomcat Webserver<br />
PHP-Skript<br />
HTTP Webserver<br />
JMS Nachricht<br />
mit UserLogin+ServiceID<br />
JMS Nachricht<br />
mit Bestätigung<br />
SQL Anfrage<br />
mit ID<br />
SQL Antwort<br />
mit Dienst<br />
Server<br />
openMQ Server<br />
Queue: DVB_Rueckkanal<br />
mySQL Server<br />
Dienstserver<br />
Abbildung 4.2: Erweiterte Struktur des Dienstbuchungssystems<br />
Die Erweiterung liegt einem sogenannten RESTful Interface zu Grunde. REST steht<br />
<strong>für</strong> Representational State Transfer und beschreibt ein Softwarearchitektur-Prinzip,<br />
durch das Web-Anwendungen auf möglichst einfache Weise miteinander kommunizieren<br />
können. Dabei sollen die Anwendungen mittels einfacher HTTP-Verbindungen<br />
Ressourcen (im Begriff einer Informationsressource) austauschen können. Es ist daher<br />
ressourcenorientiert und benutzt, je nachdem welche Aktion mit der entsprechenden<br />
Ressource durchgeführt werden soll, die HTTP Methoden POST, GET, PUT oder DE-<br />
LETE. Folglich kann eine große Anzahl an unterschiedlicher Clients mit dem auf dem<br />
REST-basierten Web-Service kommunizieren. Mittlerweile verwenden zahlreiche Web-<br />
Services eine solche Schnittstelle. Bspw. stellt die Suchmaschine Google bzw. Google<br />
Maps eine RESTful Interface API zur Verfügung. Suchanfragen können dann mittels<br />
einfacher und schneller HTTP Anfragen gesendet und empfangen werden. [Rod08]<br />
Die Struktur des WEITBLICK Dienstbuchungssystem wurde damit um ein RESTful<br />
Interface erweitert.<br />
3 PHP bezeichnet eine serverseitig interpretierte Skriptsprache<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 26<br />
4.2.2.1 UMS- und openMQ-Server als eigentliches Dienstbuchungssystem<br />
Um über das Dienstbuchungssystem einen Dienst buchen zu können, muss an die<br />
openMQ Middleware eine JMS Nachricht geschickt werden. JMS steht <strong>für</strong> Java Message<br />
Service und stellt einen auf Java basierenden Standard dar, der eine standardisierte,<br />
asynchrone Nachrichtenübertragung zwischen einer MOM (aus Abschnitt 4.1)<br />
und Clients definiert. Da JMS einen API Standard und keinen Protokollstandard beschreibt,<br />
können alle Clients, die ein JMS Interface implementieren, mit der MOM<br />
kommunizieren [Ora11a, S. 26].<br />
Abbildung 4.3: Architektur eines Universal Message Service (UMS) (entnommen aus<br />
[Ora11b])<br />
OpenMQ stellt <strong>für</strong> Anwendungen, deren Clients kein JMS Interface implementieren,<br />
einen sogenannten Universal Message Service (UMS) bereit. Wie in Abb. 4.3 zu sehen,<br />
fungiert das UMS Interface dabei als transparente Instanz zwischen den Non-JMS-<br />
Clients und dem JMS Provider 4 . Der UMS stellt <strong>für</strong> die Clients dabei ein RESTful<br />
Interface dar. Mittels der UMS-API greifen die Clients auf das UMS zu, das diese<br />
HTTP Anfragen in eine JMS Nachricht konvertiert und an den JMS Provider weiterleitet.<br />
Damit kann fast jede Anwendung mit der Zuverlässigkeit und sicheren Zustellung<br />
eines JMS Services mit der openMQ kommunizieren. Zur Einrichtung und Konfiguration<br />
ist ein Apache Tomcat Server nötig. Der Tomcat Server ist eine Art Webserver,<br />
der Java Servlets bzw. JavaServer Pages ausführen kann. Dies sind serverseitige, in<br />
Java-geschriebene Applets 5 , die auf Anfragen aus dem Internet einen dynamischen Inhalt<br />
generieren und ausgeben. Das UMS stellt einen solchen Servlet-Container bereit,<br />
welcher auf dem Tomcat Server installiert und konfiguriert werden muss. Für genaue<br />
Hinweise zur Installation und Konfiguration des UMS und Tomcat Servers sei hier auf<br />
die Dokumentationen [Ora11b] und [The11] verwiesen.<br />
Ein JMS Provider kann die Nachrichten der Clients auf zwei verschiedene Arten<br />
synchron bzw. asynchron empfangen und senden. Es wird dabei zwischen der point-topoint-Verbindung<br />
und der publish/subscribe-Verbindung unterschieden. Abb. 4.4 verdeutlicht<br />
den Unterschied beider Übertragungsarten.<br />
4 hier der openMQ Server, wird oft auch als Broker bezeichnet<br />
5 Applet = Mischung aus Application und Snippet (dt. ” Schnipsel“)<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 27<br />
Abbildung 4.4: JMS Nachrichten Domänen (entnommen aus [Ora11a, S. 27])<br />
Die elementaren Bestandteile einer JMS Anwendung sind Messages, Messageproducer<br />
und -consumer, Connections, Destinations und Sessions. Bei der point-to-point-<br />
Verbindung eröffnet ein Messageproducer eine Session mit einem Broker und sendet<br />
mehrere Nachrichten an eine Queue (engl. Warteschlange). Die Nachrichten können<br />
dann von mehreren Messageconsumern abgeholt werden. Keiner der Messageconsumer<br />
erhält die gleiche Nachricht. Im Gegensatz dazu werden bei einer publish/subscribe-<br />
Verbindung die an ein Topic gesendeten Nachrichten an alle Messageconsumer (hier:<br />
die Subscriber des Topics) weitergeleitet. [Ora11a, S. 27 f.]<br />
Die Middleware des WEITBLICK-Projekts verwendet bei der vorliegenden Aufgabenstellung<br />
eine point-to-point-Verbindung. Die Nachrichten, in denen sich die Buchungen<br />
der Dienste befinden, werden an eine bestimmte Queue (hier: ” DVB Rueckkanal“ )<br />
gesendet. Die Nachrichten in der Queue werden folglich von einem Messageconsumer<br />
synchron bzw. asynchron abgeholt, um die Buchungsanforderung des Nutzers weiter<br />
zu verarbeiten.<br />
Zur Buchung eines Dienstes ist es zudem nötig, dass der Nutzer serverseitig vom<br />
Dienstbuchungssystem authentifiziert und zur Buchung eines Dienstes autorisiert wird.<br />
Demnach muss sich der Nutzer mit einem UserLogin authentifizieren. Beim JMS Standard<br />
erfolgt die Authentifizierung bei der Erstellung einer Connection. Hierbei muss ein<br />
beim JMS Provider angelegter UserLogin (mit User und Passwort) angegeben werden,<br />
um anschließend eine Session zu eröffnen. Der UMS Server des erweiterten Dienstbuchungssystem<br />
wurde so konfiguriert, dass die Clients sich über das REST Interface<br />
authentifizieren müssen. Nach der UMS-API (siehe [Ora11b]) wird der Benutzername<br />
und das Passwort direkt als Schlüsselwertpaar übergeben.<br />
Die HTTP-POST Nachricht, die vom Android Clienten an den UMS gesendet wird,<br />
sieht <strong>für</strong> die Dienstbuchung folgendermaßen aus:<br />
Listing 4.1: Buchung des Dienstes als HTTP Request<br />
1 POST /imqums/ simple ? s e r v i c e=send&d e s t i n a t i o n=DVB Rueckkanal&u s e r=Hans&password=Dampf<br />
HTTP/ 1 . 1<br />
2 Content−Type : t e x t / p l a i n ; c h a r s e t=UTF−8<br />
3 Host : g a g a r i n . e−t e c h n i k . tu−ilmenau . de : 8 4 4 3<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 28<br />
4<br />
5 WEITBLICK<br />
Ein HTTP Post teilt sich in die beiden Teile Header und Body. Die erste Zeile beinhaltet<br />
die Art dieses HTTP Requests ( ” POST“ ), dessen Zielpfad des Servers ( ” imqums“<br />
), den aufrufenden API-Befehl ( ” simple“ ) mit den dazugehörigen Attributen als<br />
Schlüsselwertpaare im sogenannten HTTP Query String und schließlich die verwendete<br />
HTTP Protokollversion. Die weiteren Headers legen die Art des Inhalts (Text<br />
im Zeichensatz UTF-8 ) und den Host als Zielserver (gagarin.e-technik.tu-ilmenau.de<br />
mit Port 8443 ) fest. Der Body ist der Inhalt der Nachricht ( ” WEITBLICK“) und wird<br />
von den Headers durch eine Leerzeile getrennt. In diesem Beispiel wird die Funktion<br />
send aus der UMS-API (siehe [Ora11b]) mit den Attributen destination, user und<br />
password aufgerufen. Durch einen send-Request wird der Body der HTTP Nachricht<br />
durch den UMS in eine JMS TextMessage umgewandelt und an die im HTTP Query<br />
String angegebene Destination, die in diesem Fall die im JMS Provider angelegte<br />
Queue ” DVB Rueckkanal“ bezeichnet, gesendet. Die ebenfalls im Query angegeben Logindaten<br />
benutzt der UMS, um sich beim JMS Provider einzuloggen und den Nutzer<br />
zu authentifizieren. Wurde die Operation erfolgreich durchgeführt, d. h. der Nutzer erfolgreich<br />
authentifiziert und autorisiert (vorausgesetzt die nötigen Rechte sind gesetzt),<br />
so sendet der UMS dem Android Client eine Bestätigung:<br />
Listing 4.2: HTTP Bestätigungsantwort vom UMS an den Android Client<br />
1 HTTP/ 1 . 1 200 OK<br />
2 S e r v e r : Apache−Coyote / 1 . 1<br />
3 ums . s e r v i c e : s e n d r e p l y<br />
4 ums . d e s t i n a t i o n : DVB Rueckkanal<br />
5 ums . domain : queue<br />
6 ums .mom: openmq<br />
7 ums . s t a t u s : 200<br />
8 Content−Type : t e x t / p l a i n ; c h a r s e t=UTF−8<br />
9 Content−Length : 0<br />
10 Date : Thu , 24 Mar 2011 1 7 : 4 3 : 2 2 GMT\ r \n<br />
Jeder HTTP Request wird vom Server mit einer Statusnachricht beantwortet. Diese<br />
enthält einen der in der HTTP Spezifikation festgelegten HTTP Statuscodes. In diesem<br />
Fall wurde vom UMS die HTTP Anfrage mit dem Statuscode 200 beantwortet, der <strong>für</strong><br />
eine erfolgreich übertragene Operation steht. Die HTTP Antwort des UMS enthält<br />
keine Information, da<strong>für</strong> zusätzliche Headers, die Auskunft über den Status der JMS<br />
Connection geben (hier Zeile 3-7). So zeigt der zusätzliche Header ” ums.status“ einen<br />
erfolgreichen Transfer des Service Requests ” send reply“ (Header ” ums.service“ ) an die<br />
Destination ” DVB Rueckkanal“ (Header ” ums.destination“ ) an. Um dementsprechend<br />
feststellen zu können, ob der Dienst richtig gebucht wurde, muss sowohl der HTTP<br />
Header als auch der zusätzliche Header ” ums.status“ auf den Statuscode 200 geprüft<br />
werden.<br />
Bei der Buchung eines Dienstes gibt es zusätzlich noch einen sicherheitsrelevanten<br />
Aspekt zu betrachten. Die Übermittlung von HTTP Requests findet unverschlüsselt<br />
statt, womit das HTTP Protokoll als unsicher gilt. Werden also sicherheitssensible<br />
Daten wie Passwörter bzw. Logindaten übertragen, so könnten diese Daten durch<br />
einen ” Man-in-the-Middle“ -Angriff ausgespäht werden [Sch06, S. 243]. Leicht möglich<br />
wäre dies bspw., wenn sich der Nutzer in einem unverschlüsseltem WLAN-Netzwerk<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 29<br />
befindet und einen Dienst bucht. Dabei würde ein Angreifer den Netzwerkverkehr<br />
mithören und die Logindaten, die sich im Klartext in der HTTP POST Nachricht<br />
befinden, auslesen und missbräuchlich nutzen können. Es muss daher bei der Buchung<br />
eines Dienstes eine sichere, verschlüsselte Verbindung verwendet werden. Dazu eignet<br />
sich die Verwendung des HyperText Transfer Protocol Secure (HTTPS) Protokolls.<br />
HTTPS verwendet das Verschlüsselungsprotokoll Secure Sockets Layer (SSL) 6 und<br />
wird genutzt, um sowohl den Verbindungspartner zu authentifizieren als auch um eine<br />
verschlüsselte Verbindung aufbauen zu können. [Int11a] Um eine Verbindung über<br />
HTTPS herstellen zu können, muss auf dem Server ein Zertifikat installiert und dieser<br />
entsprechend konfiguriert werden. Damit kann sich der Server gegenüber dem Client<br />
authentifizieren. Nach Aufruf einer HTTPS Seite im Browser eines Clients wird der<br />
Nutzer aufgefordert das SSL Zertifikat des Servers zu installieren. Darüberhinaus gibt<br />
es die Möglichkeit sich von Zertifizierungsstellen, den CA (Certification Authority),<br />
ein zertifiziertes Zertifikat ausstellen zu lassen. Diese sind bei Internetbrowsern schon<br />
vorinstalliert, sodass dem Nutzer beim Aufrufen der Seite ein Dialog zur Bestätigung<br />
der Zertifikatinstallation erspart bleibt. Eine HTTPS Verbindung wird durch einen<br />
SSL Handshake auf Basis eines asymmetrischen Verschlüsselungsverfahrens initiiert.<br />
Mit dem dadurch generierten Sitzungsschlüssel wird zwischen dem Client und dem<br />
Server eine verschlüsselte Verbindung aufgebaut. [BP09, S. 293]<br />
Im vorliegenden Usecase muss zur verschlüsselten Übertragung der Buchung eine<br />
HTTPS Verbindung zwischen dem Android Client und dem UMS Server aufgebaut<br />
werden. Dazu ist es notwendig den <strong>für</strong> das UMS verwendeten Tomcat Server <strong>für</strong> die SSL<br />
Verbindung zu konfigurieren. Es wird ein von der <strong>TU</strong> <strong>Ilmenau</strong> CA erstelltes Zertifikat<br />
verwendet, wodurch sich das Dienstbuchungssystem gegenüber dem Android Client als<br />
vertrauensvolle Instanz der <strong>TU</strong> <strong>Ilmenau</strong> CA authentifizieren kann.<br />
4.2.2.2 SQL Server als Dienstserver<br />
Die bereits in Abschnitt 4.2.1.3 erwähnte fehlende Unterstützung von externen SQL-<br />
Anfragen beim Android System erfordern Anpassungen der Serverstruktur des Dienstbuchungssystem<br />
wie in Abb. 4.2 gezeigt. Demnach wird zwischen Android Client und<br />
openMQ-Server ein HTTP Webserver geschalten, welcher dem Android Client als ein<br />
vereinfachtes RESTful Interface (siehe 4.2.2.1) dient. Nachdem das Smartphone den<br />
QR Code eingelesen und daraus eine ID geparst hat, wird diese mittels einer HTTP<br />
Anfrage an den HTTP Webserver (ebenfalls erreichbar unter gagarin.e-technik.tuilmenau.de)<br />
gesendet. Ein auf dem Webserver gespeichertes PHP-Skript (Voraussetzung<br />
<strong>für</strong> den Webserver ist ein installiertes PHP-Modul) bildet einen Web-Service.<br />
Dieser stellt, basierend auf der in der HTTP Nachricht enthaltenen ID, eine dynamische<br />
SQL Anfrage an den mySQL-Server. Der SQL-Server (der eigentliche Dienstserver)<br />
wählt den angeforderten Dienst-Datensatz aus und gibt diesen an das PHP-Skript zurück,<br />
welches den Datensatz ausgibt. Die Ausgabe erhält der Android Client wiederum<br />
als HTTP Nachricht, die den angefragten Dienst anzeigt und weiter verarbeitet.<br />
Die SQL-Tabelle des SQL-Servers als Dienstdatenbank ist wie folgt aufgebaut:<br />
6 SSL wird ab Protokollversion 3.1 unter dem Namen Transport Layer Security (TLS) verwendet<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 30<br />
weitblick services<br />
Feld Typ<br />
ID int(5)<br />
title varchar(100)<br />
shorttitle varchar(30)<br />
descr varchar(5000)<br />
date datetime<br />
duration double<br />
costs int(5)<br />
phonenr varchar(20)<br />
Tabelle 4.1: SQL-Tabelle des mySQL-Servers als Dienstserver<br />
Jeder Datensatz bzw. Dienst der SQL-Tabelle 4.1 erhält durch das Attribut ” primary<br />
key“ (des Feldes ID) eine eindeutige ID. Die weiteren Felder dienen der Beschreibung<br />
des Dienstes, die das PHP-Skript über die folgende SQL-Anfrage abfragt:<br />
Listing 4.3: SQL Anfrage im PHP-Skript<br />
1 $myquery = " SELECT title , descr , DATE_FORMAT (date , ’%e.%c.%y um %k:%i Uhr ’) AS fdate ,<br />
costs , phonenr , duration<br />
2 FROM weitblick_services<br />
3 WHERE id=’" . $id . "’" ;<br />
4<br />
5 $ r e s u l t=mysql query ( $myquery ) or d i e ( m y s q l e r r o r ( ) ) ;<br />
6 $output [ ] = m y s q l f e t c h a s s o c ( $ r e s u l t ) ;<br />
Durch die SQL Anfrage in Zeile 1-3 wird aus der SQL-Tabelle weitblick services ein<br />
Dienst (basierend auf der in Zeile 3 übergebenen ID) mit den Informationen Titel,<br />
Beschreibung, Zeitangabe, Kosten, Telefonnummer und Dauer abgefragt. Die ID wird<br />
vorher auf den Datentyp geprüft (siehe im Anhang unter A.1), um das Skript vor<br />
sogenannten SQL-Injections 7 zu schützen. Die Ergebnisse der SQL Anfrage werden im<br />
Array $output[] gespeichert und weiterverarbeitet.<br />
4.3 Die WEITBLICK CodeScanner App<br />
Nach Erläuterung der Struktur und der Serverseite des Dienstbuchungssystems im<br />
letzten Abschnitt, wird im Folgenden auf die Entwicklung der Android WEITBLICK<br />
App eingegangen, mit der der Nutzer interagiert und einen Dienst buchen kann. Dabei<br />
wurde folgende Entwicklungsumgebung verwendet:<br />
• Testgerät HTC Wildfire<br />
• Android 2.2.1 (Froyo)<br />
• Eclipse IDE (Helios) mit Android Development Tools (ADT) - Plugin<br />
7 Eine SQL-Injection bezeichnet einen Angriff bei dem versucht wird einen bösartigen Code einzu-<br />
schleusen<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 31<br />
• Android SDK Plattform Android 2.2, API 8<br />
• Testen und Debuggen der App auf dem direkt per USB angeschlossenen HTC<br />
Wildfire<br />
Zur Erläuterung der Entwicklung der WEITBLICK App ist es notwendig auf die<br />
Grundlagen des Android Systems und die Android Programmierung einzugehen. Dies<br />
hat keinen Anspruch auf Vollständigkeit und ist lediglich auf die <strong>für</strong> das Verständnis<br />
nötigen Grundlagen eingeschränkt. Für eine vollständige Referenz zum Thema Android<br />
Programmierung sei hiermit auf die offizielle Android Developers Homepage unter<br />
[Goo11] verwiesen. Die Informationen aus diesem Abschnitt entstammen dieser Referenz.<br />
4.3.1 Android Grundlagen<br />
Um eine Applikation <strong>für</strong> Android entwickeln zu können, sind neben der eigentlichen<br />
Programmiersprache Java noch weitere Kenntnisse über die Android Systemarchitektur<br />
nötig. Abb. 4.5 gibt dazu einen Überblick.<br />
Abbildung 4.5: Android Systemarchitektur (entnommen aus [Goo11])<br />
Die unterste Ebene bildet den schon in 4.2.1.2 erwähnten Linux Kernel, der die<br />
Schnittstelle zwischen Software und Hardware darstellt. Er kümmert sich um die Sicherheit,<br />
das Speicher-, Prozess- und Netzwerkmanagement sowie die nötigen Gerätetreiber<br />
der Systemkomponenten. Darüber folgen verschiedene Bibliotheken mit dem<br />
Hauptbestandteil der Android-Laufzeitumgebung DVM mit den aus der Java-API<br />
übernommenen Kernbibliotheken. Die oberen beiden Schichten bilden das Application<br />
Framework mit Schlüsselanwendungen <strong>für</strong> Telefonie, Kontaktverwaltung, Internetbrowser<br />
usw. Diese (Key-)Applications, wie auch Anwendungen Dritter, benutzen<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 32<br />
beide die gleichen Funktionalitäten aus dem Application Framework, womit alle Anwendungen<br />
ersetzt werden können. Somit kann jede Anwendung bspw. auf die Gerätehardware<br />
oder die aktuelle Geoposition (GPS-Modul) zugreifen sowie einen Anruf<br />
tätigen oder auch eine SMS senden. Dadurch ergeben sich <strong>für</strong> Entwickler eine Vielzahl<br />
von Anwendungsmöglichkeiten, welche die Entwicklung innovativer Anwendungen erlauben.<br />
4.3.1.1 Android Manifest<br />
Das Android Manifest ist eine XML-Datei im Root (engl. Stammverzeichnis) des<br />
Projektverzeichnisses, welche Android Anwendungen in ihren Komponenten (mit deren<br />
Eigenschaften) sowie Anforderungen der gesamten Application beschreibt. Als<br />
Anwendungs-Komponenten werden folgende bezeichnet:<br />
• Activities<br />
• Services<br />
• Broadcast Receiver<br />
• Content Provider<br />
Das Manifest der CodeScanner App sieht wie folgt aus:<br />
Listing 4.4: Das Android Manifest der CodeScanner App<br />
1 <br />
2 <br />
6 <br />
7 <br />
8 <br />
9 <br />
10 <br />
11 <br />
13 <br />
14 <br />
15 <br />
16 <br />
17 <br />
18 <br />
19 <br />
Aus den XML-Tags ist ersichtlich, dass die CodeScanner App als Komponente nur eine<br />
einzige Activity (siehe 4.3.1.2) besitzt. Die Anwendung trägt den im Attribut android:label<br />
gespeicherten Wert ” CodeScanner“. android:icon zeigt auf eine Ressource<br />
(im Abschnitt 4.3.1.3 wird darauf genauer eingegangen), in der sich das Launcher-Icon<br />
(Startsymbol auf dem Android-“Desktop“) befindet. Als Eigenschaft bzw. Fähigkeit<br />
der Activity wird hier ein aufgeführt.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 33<br />
Intents sind eine Art Anfragen, die an die eigene oder eine externe Anwendung<br />
(die ebenfalls auf dem Android Smartphone installiert ist) gestellt werden. Als Eigenschaften<br />
besitzen Activities u. a. . In diesen werden Bedingungen<br />
<strong>für</strong> ein Intent festgelegt, durch das die Activity gestartet werden soll. Wird ein Intent<br />
durch eine App abgeschickt, so sucht das System eine Activity bzw. Application mit<br />
einem passenden aus und ruft diese auf. Kommen mehrere Activities<br />
bzw. Anwendungen in Frage, so bietet Android eine Auswahl derer an. Diese Art<br />
von Intents werden implizite Intents genannt, weil diese eine abstrakte Angabe der<br />
auszuführenden Operation beinhalten und damit in den Raum“ gestellt werden. Ein<br />
”<br />
Anruf kann bspw. durch das Abschicken eines impliziten Intents mit dem Inhalt an-<br />
”<br />
droid.intent.action.CALL“ getätigt werden, wodurch sich die Telefonie App mit einem<br />
Anruf an die übergebene Telefonnummer öffnet. Daneben gibt es noch den Typ der<br />
expliziten Intents. Dabei wird eine konkrete Klasse aufgerufen, die eine neue Activity<br />
startet.<br />
Im -Tag wird das Android Manifest selbst definiert. xmlns:android legt<br />
den Namespace der XML-Datei fest, der die verwendbaren beschreibt. Zudem<br />
stehen im der Java-Package Name und die Versionsinformationen zur Application.<br />
Anhand des android:versionCode wird eine Versionsnummer relativ zur<br />
vorhergehenden Version und mit android:versionName ein <strong>für</strong> den Nutzer ersichtlicher<br />
Versionscode festgelegt.<br />
Weitere in der festzulegende, wichtige Eigenschaften der Application<br />
sind die Berechtigungen der Anwendung - die Permissions. Standardmäßig hat eine<br />
Anwendung nach dem Android Application Framework keine Berechtigungen, um auf<br />
Systemkomponenten zuzugreifen. Für jede Aktion muss daher im Manifest eine Permission<br />
eingetragen werden, was <strong>für</strong> einen Internetzugriff durch INTERNET“, <strong>für</strong> das<br />
”<br />
Tätigen von Telefonanrufen durch CALL PHONE“, <strong>für</strong> die Abfrage des Netzwerksta-<br />
”<br />
tus durch ACCESS NETWORK STATE“ oder <strong>für</strong> das Lesen des Telefonstatus durch<br />
”<br />
” READ PHONE STA<strong>TU</strong>S“ geschieht. Möchte der Nutzer die CodeScanner App auf<br />
seinem Android Phone installieren, so wird er vor der Installation um die Freigabe dieser<br />
Berechtigungen einmalig gefragt. Dem Nutzer bleibt hiermit das ständige Erfragen<br />
von Berechtigungen durch ein Pop-up-Fenster erspart.<br />
4.3.1.2 Activities<br />
Eine Activity ist eine der Hauptkomponenten einer Android Application. Sie stellt <strong>für</strong><br />
den Nutzer eine Präsentationsschicht, ein Graphical User Interface (GUI), dar, mit dem<br />
dieser interagieren kann. Eine Activity beinhaltet eine Art Ansichtsfenster (View), in<br />
dem wiederum einzelne UI-Elemente platziert werden. Diese Elemente sind z. B. Buttons,<br />
TextViews oder ImageViews, stellen Inhalte dar und können durch Aktivierung<br />
Aktionen ausführen. Innerhalb einer Anwendung können sich mehrere Activities befinden,<br />
die jeweils <strong>für</strong> sich stehen, aber miteinander agieren können. Wird eine andere<br />
Activity aufgerufen, so wird die aktuelle gestoppt und auf einen sogenannten ” Back<br />
Stack“ (engl. Stapel) gelegt. Die aufgerufene wird aktiviert und ist <strong>für</strong> den Nutzer<br />
sichtbar. Der ” Back Stack“ funktioniert nach dem ” Last in, First out“-Prinzip. Das<br />
heißt, wenn der User die ” BACK“-Taste des Smartphones drückt, wird die zuletzt auf<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 34<br />
dem ” Back Stack“ abgelegte Activity wieder reaktiviert und die Anzeige springt in den<br />
letzten Zustand zurück. Beim Stoppen einer Activity wird der Status dieser destroyed<br />
(engl. zerstört). Damit werden alle Objekte und Attribute, die innerhalb dieser Activity<br />
erstellt wurden, gelöscht. Für eine Speicherung des Activity-Status gibt es verschiedene<br />
Möglichkeiten dessen Zustand zu übergeben. Eine Option wäre die Callback-Methoden<br />
des Activity Lifecycles (siehe [Goo11]) zu überschreiben, um eine persistente Speicherung<br />
von bspw. Objekten durchzuführen. Destroyed wird eine Activity auch, wenn<br />
ein Configuration Change ausgeführt wird. Eine Änderung der Screen Orientation 8<br />
wäre ebenfalls ein Configuration Change und hätte eine Zerstörung der Activity zur<br />
Folge. Die CodeScanner Activity würde damit die Informationen eines bereits angefragten<br />
Dienstes verlieren und der Code müsste erneut gescannt werden. Um dies zu<br />
verhindern, werden die Dienstinformationen wie folgt übergeben:<br />
Listing 4.5: Übergabe eines Objekts bei Stoppen einer Activity<br />
1 @Override<br />
2 p u b l i c Object onRetainNonConfigurationInstance ( ) {<br />
3 f i n a l DataAccess data = da ;<br />
4 r e t u r n data ;<br />
5 }<br />
Die Lifecycle Callback-Methode onRetainNonConfigurationInstance() wird im Falle<br />
eines Screen Orientation Change durch @Override überschrieben. Diese Methode wird<br />
beim Stoppen und Zerstören der Activity aufgerufen. In Zeile 3 wird ein neues Objekt<br />
des Typs DataAccess erzeugt, um es persistent in einer höheren Ebene zu speichern<br />
und anschließend nach einem Configuration Change wieder abrufen zu können. Durch<br />
Aufruf der Methode getLastNonConfigurationInstance() kann das Objekt in der<br />
reaktivierten Anwendung dann zurück gespeichert und der Zustand (d. h. die bereits<br />
angefragten Dienstinformationen) wiederhergestellt werden.<br />
Ebenso gibt es in jeder Anwendung eine Main-Activity (definiert durch einen <br />
wie in A.2, Zeile 13-16), die als Einstiegspunkt 9 beim Starten einer Anwendung<br />
dient. Dazu muss in der Main-Activity-Klasse die onCreate(...) Methode wie im<br />
Programmcode unter 4.6 überschrieben werden. Eine Klasse wird durch Vererbung der<br />
Basisklasse Activity aus der Android-API mit public class CodeScanner extends<br />
Activity zu einer Activity-Klasse.<br />
Listing 4.6: Einstiegspunkt einer Anwendung: die onCreate(...)-Methode<br />
1 @Override<br />
2 p u b l i c void onCreate ( Bundle s a v e d I n s t a n c e S t a t e ) {<br />
3 super . onCreate ( s a v e d I n s t a n c e S t a t e ) ;<br />
4 setContentView (R. l a y o u t . codescanner ) ;<br />
5<br />
6 ( . . . )<br />
7 }<br />
Beim Aufrufen der onCreate(...)-Methode wird ein Parameter savedInstanceState<br />
des Typs Bundle (ein ” Bündel“ an Datentypen) übergeben. Damit könnte ebenfalls<br />
ein zuvor gespeicherter Zustand einer Activity (diesmal mit der Speicherung durch<br />
8 falls der Nutzer sein Smartphone in der Hand dreht, ändert sich entsprechend die Screen Orientation,<br />
d. h. die Ausrichtung des UIs, zwischen dem Modus Portrait und Landscape<br />
9 vergleichbar mit public static void main (String[] args) in Java<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 35<br />
die Lifecycle Callback-Methode onSaveInstanceState(Bundle)) geladen werden. Die<br />
View der Activity wird durch setContentView(R.layout.codescanner) aus einer<br />
Layout-Ressource geladen. Dieses Layout (siehe 4.3.1.3) ist in der XML-Datei codescanner.xml<br />
definiert und befindet sich im Projektverzeichnis im Unterverzeichnis<br />
/res/layout.<br />
4.3.1.3 Application Resources<br />
Unter dem Begriff Resources (engl. Ressourcen) werden in der Informatik im Allgemeinen<br />
Quellen bezeichnet, die nichts mit dem eigentlichen, in einer Programmiersprache<br />
geschriebenen Quellcode zu tun haben. So werden auch in Android Ressourcen definiert,<br />
auf die vom Quellcode (auch: source) aus getrennt zugegriffen wird und welche<br />
daher auch getrennt abgespeichert werden. Als Resources werden Video-/Bildund<br />
Audiodateien sowie andere Inhalte wie Animationen, Menüs, UI-Styles, Farben<br />
und Layouts behandelt. Vorteile der getrennten Behandlung von Sourcecode und Resources<br />
liegen vor allem darin, Inhalte schnell verändern und die App auf die Vielzahl<br />
der Gerätekonfigurationen (z. B. Bildschirmauflösung, verwendete Sprache) dynamisch<br />
anpassen zu können. Die Resources werden als XML-Dateien erstellt und im Projektverzeichnis<br />
im Unterverzeichnis /res/ wiederum in einem, dem Typ der Resource<br />
entsprechenden, Unterverzeichnis abgespeichert. Eine Layout-Datei codescanner.xml<br />
befindet sich dann bspw. im Verzeichnis /res/layout/. Die Verzeichnisnamen sind<br />
in der Android Dokumentation [Goo11] definiert und können ebenso durch einen im<br />
Verzeichnisnamen zusätzlichen Qualifier <strong>für</strong> eine spezielle Gerätekonfiguration 10 konkretisiert<br />
werden. Je nach Gerätekonfiguration sucht sich das Android System dann die<br />
entsprechende Resource aus. Das Android Asset Packaging Tool (aapt) generiert eine<br />
Android-interne R.class-Datei, in der <strong>für</strong> alle Resource IDs erzeugt werden. Diese Resource<br />
IDs können dann entweder in den Resource XML-Dateien oder direkt im Code<br />
verwendet werden. Auf die im Android Manifest aufgeführten Namen der Anwendung<br />
wird durch<br />
@string/app name<br />
zugegriffen. Das @ leitet die Resource ein, string ist der Resource-Typ und app_name<br />
der Name der Resource. Ein Beispiel <strong>für</strong> die Referenzierung auf eine Layout-Resource<br />
aus dem Java-Quellcode wurde bereits im letzten Abschnitt unter 4.6 verwendet:<br />
setContentView(R.layout.codescanner);<br />
Dadurch wird beim Erstellen der Main-Activity die View initialisiert. Der Initialisierungs-Methode<br />
setContentView wird dabei die Resource ID R.layout.codescanner<br />
zu der sich im Unterverzeichnis /res/layout/ befindenden Layout-XML-Datei codescanner.xml<br />
übergeben.<br />
10 das Unterverzeichnis /res/layout-land/ definiert bspw. ein <strong>für</strong> die Screen Orientation ” Landscape“<br />
angepasstes Layout<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 36<br />
Layout Resources und das XML-Layout Das Layout als User Interface des Android<br />
System wird durch die Android-Klasse android.View beschrieben. Diese dient als<br />
Basisklasse aller weiteren davon abgeleiteten Unterklassen wie bspw. die der View-<br />
Group. Diese beinhaltet voll-implementierte Basisobjekte als UI-Elemente wie Text-<br />
Views, Buttons, ListViews usw. Zudem dient die ViewGroup-Klasse als Basis <strong>für</strong> bspw.<br />
LinearLayout und RelativeLayout.<br />
Abbildung 4.6: Verschachtelung von UI-Elementen (entnommen aus [Goo11])<br />
Durch Klassenvererbung sind UI-Elemente View-Objekte und Childs einer View-<br />
Group bzw. Layouts (siehe Abb. 4.6). Als View-Objekte bestimmen sie den Bereich,<br />
den sie innerhalb des Layouts einnehmen sowie ihre Eigenschaften. Ebenso werden User<br />
Interaktionen immer auf ein View-Objekt angewendet. Möglich wäre bspw. ein Event<br />
Listener, der auf einen Button als View-Objekt angewendet wird und beim Klicken auf<br />
diesen die Callback-Methode onClick(...) aufruft. Abb. 4.7 zeigt je nach Zustand der<br />
CodeScanner App zwei Screenshots der beiden möglichen Layouts - das Scanning- und<br />
das BookingLayout.<br />
Abbildung 4.7: Scanning- und BookingLayout des User Interface<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 37<br />
Das BookingLayout besteht aus vier TextViews <strong>für</strong> die Anzeige der Dienstinformationen<br />
(Titel, Beschreibung, Zeitangabe und Kosten) sowie drei Buttons, die jeweils<br />
mit einem OnClickListener belegt sind.<br />
Das ScanningLayout dient als Initialisierungslayout zum Einstieg in die CodeScanner<br />
App. Es besteht aus einer ImageView und einem Button. Durch Klicken auf den ” Code<br />
scannen“-Button, wird der OnClickListener aktiviert und die onClick(...) Callback-<br />
Methode aufgerufen, die den Scanvorgang initiiert. Damit wird die externe ZXing Barcode<br />
Scanner App gestartet. Der folgende Programmcode 4.7 zeigt den Teil aus der<br />
codescanner.xml, der das ScanningLayout definiert.<br />
Listing 4.7: Auszug aus codescanner.xml<br />
1 <br />
2 <br />
8 <br />
13 <br />
17 <br />
18 <br />
24 <br />
25 <br />
Verschachtelt in einem RelativeLayout befindet sich das Bild (das wiederum verschachtelt<br />
in einem LinearLayout ist, um das Bild vertikal zu zentrieren) sowie der<br />
Button. Das RelativeLayout hat die Besonderheit, dass sich die Child-Elemente durch<br />
entsprechende XML-Attribute (android:layout_above, androidParentBottom usw.)<br />
relativ zueinander positionieren lassen. Durch das zusätzliche ” +“ in der Angabe der<br />
android:id wird dem aapt-Tool (siehe 4.3.1.3) signalisiert, eine neue Resource ID<br />
zu erzeugen. Die Größe eines Elements wird durch die XML-Attribute android:layout_width<br />
und android:layout_height angegeben. Sie ist mit fill_parent/wrap_content<br />
entweder Elternelement-füllend bzw. Inhalts-umschließend oder kann auch<br />
absolut angegeben werden. Statt einer absoluten Pixelangabe empfiehlt [Goo11] hingegen<br />
die Einheit dip zu verwenden. Dip steht <strong>für</strong> density independent pixel und bezeichnet<br />
einen Pixel, der unabhängig von der Dichte des Displays des Smartphones<br />
ist. Ein dpi ist äquivalent zu einem Pixel auf einem 160-dpi-Bildschirm (also zu einer<br />
Bildschirmauflösung von 160 Pixel pro Zoll). Damit wird sichergestellt, dass auf<br />
jedem Smartphone die UI-Elemente unabhängig von der Displayauflösung gleich groß<br />
dargestellt werden. Die Umrechnung von Pixel und Dips erfolgt in Abhängigkeit der<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 38<br />
Displayauflösung durch die Formel pixels = dips ∗ (density/160) 11 .<br />
In der codescanner.xml befindet sich sowohl das Scanning- (unter 4.7) als auch das<br />
BookingLayout. Initialisiert wird die CodeScanner App mit dem ScanningLayout. Nach<br />
Scannen des QR Codes (durch die ZXing App) und Rückgabe der Ergebnisse wechselt<br />
das Layout zum BookingLayout. Da unabhängig vom jeweiligen Status durch setContentView(R.layout.codescanner)<br />
die codescanner.xml initialisiert wird, müssen<br />
die einzelnen Layouts ausgehend vom Quellcode gesteuert und ein- bzw. ausgeblendet<br />
werden. Auf die Attribute der Layouts als View-Objekte wird im Quelltext wie folgt<br />
zugegriffen:<br />
Listing 4.8: Zugriff auf UI-Elemente aus einer Layout-XML-Datei<br />
1 RelativeLayout l a y o u t s c a n n i n g = ( RelativeLayout ) findViewById (R. i d . l a y o u t s c a n n i n g ) ;<br />
2 l a y o u t s c a n n i n g . s e t V i s i b i l i t y ( View . VISIBLE ) ;<br />
Dazu müssen die UI-Elemente bzw. Layouts im Quellcode zunächst initialisiert (siehe<br />
Zeile 1) und mit der entsprechenden ID (hier: layout scanning, definiert im Programmcodeabschnitt<br />
4.7, Zeile 3) verknüpft werden, um anschließend auf die Methoden dieses<br />
UI-Elements zugreifen zu können. Je nach Zustand der CodeScanner App werden die<br />
Layouts mit setVisibility(...) ein- bzw. ausgeblendet.<br />
Andere Resources Neben den Layout-Resources verwendet die CodeScanner App<br />
noch weitere Resource-Typen. So werden bspw. die konstanten Datentypen Strings<br />
in einer String-Resource unter /res/values/strings.xml zusammengefasst. Diese<br />
Strings ändern sich während der Laufzeit nicht und sind damit als Resource zentral<br />
auffind- und veränderbar. Durch die Verlagerung der verwendeten Strings vom Quellcode<br />
in eine String-Resource, wäre ebenso eine Erweiterung der App auf die englische<br />
Sprache leicht implementierbar. Diese würde durch einen zusätzlichen Qualifier im Namen<br />
des Unterverzeichnis /res/values-en/ gekennzeichnet werden. Bei entsprechend<br />
eingestelltem Sprachraum würde das Android System die in diesem Verzeichnis deponierte<br />
strings.xml wählen und die speziell angepassten, englischen String-Werte<br />
einsetzen.<br />
Des Weiteren werden Grafiken unterschiedlicher Auflösungen in verschiedenen Ressourcenverzeichnissen,<br />
deren Name einen zusätzlichen Density Qualifier (wie hdpi, mdpi<br />
und ldpi) besitzt, unter /res/drawable-qualifier/ abgelegt. Android wählt hier<br />
wieder ein <strong>für</strong> die aktuelle Gerätekonfiguration passendes Ressourcenverzeichnis aus.<br />
Durch die zusätzlichen Qualifiers in den Namen der Ressourcen-Unterverzeichnisse,<br />
lassen sich Anwendungen erstellen, die auf eine Vielzahl von Geräten angepasst sind.<br />
4.3.2 Aufbau der CodeScanner App<br />
In Abschnitt 4.3.1.2 wurde bereits vorweggenommen, dass die CodeScanner App aus<br />
nur einer Main-Activity besteht. Eine Klasse ist eine Activity-Klasse, falls diese durch<br />
” extends Activity“ von der Basisklasse Activity erbt. Zudem muss sie als Main-<br />
Activity im Android Manifest durch einen speziellen (siehe A.2,<br />
11 Bsp.: 1 dip entspricht auf einem 240 dpi Display 1.5 physikalische Pixel (siehe [Goo11])<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 39<br />
Zeile 13-16) gekennzeichnet werden. Eine Activity soll laut Definition die Präsentationsschicht<br />
der App darstellen, mit der der Nutzer interagieren kann. Um <strong>für</strong> die<br />
CodeScanner Activity eine übersichtliche und einfache Programmstruktur zu schaffen,<br />
wurde die CodeScanner App in folgende zwei Klassen aufgeteilt:<br />
Main-Activity CodeScanner Darstellung des User Interface<br />
• Initialisierung aller UI-Elemente<br />
• Initialisierung des Scanvorgangs: Aufruf der ZXing Barcode Scanner App<br />
• Erstellen eines DataAccess Objekts<br />
• Darstellung des angefragten Dienstes<br />
• Dialoge zur Rückmeldung geben<br />
• Initialisierung eines Anrufs<br />
• Hinzufügen eines Kalendertermins<br />
Datenzugriffsklasse DataAccess Durchführen von Datenzugriffsoperationen<br />
• Verarbeiten der Scanresults<br />
• Anfragen der Dienstinformationen<br />
• Handling der Nutzerauthentifizierung<br />
• Buchung des Dienstes<br />
Zur weiteren Übersicht wurde aus dem CodeScanner-Quellcode mit dem Eclipse-<br />
Plugin eUML2 der Firma Soyatec (siehe [Soy11]) ein Klassendiagramm erstellt, welches<br />
Abb. 4.8 zeigt. Zu sehen ist die Struktur der beiden Klassen CodeScanner und<br />
DataAccess.<br />
Neben den verwendeten Methoden- und Attributsnamen verdeutlichen die Pfeile die<br />
Abhängigkeiten der beiden Klassen. Die in der CodeScanner-Klasse definierten Attribute<br />
stellen bis auf das DataAccess-Objekt alle UI-Elemente dar, die Aktionen ausführen,<br />
Inhalte darstellen oder durch Pop-up-Fenster Rückmeldungen geben. Dahinführend<br />
wird, nach Initialisierung des Scanvorgangs (durch Aufruf der externen ZXing App)<br />
und Rückgabe der Ergebnisse des QR Code-Scans, ein DataAccess Objekt erzeugt.<br />
In diesem Objekt werden alle Informationen des Dienstes gespeichert und durch die<br />
DataAccess-Klasse gehandelt. Die CodeScanner Activity greift auf die im DataAccess-<br />
Objekt gespeicherten Informationen zu und stellt diese dar. Das Enumeration-Feld<br />
Status aus der DataAccess-Klasse zeigt dabei den Status der Dienstabfrage an und<br />
passt die Anzeige darauf an. Falls bspw. keine Internetverbindung vorhanden ist oder<br />
kein gültiger Code gescannt wurde, wird das Feld mStatus auf einen entsprechenden<br />
Wert aus der Enumeration Status gesetzt. Die Main-Activity kann dementsprechend<br />
den Nutzer auffordern die Internetverbindung zu überprüfen oder einen gültigen QR<br />
Code zu scannen.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 40<br />
Abbildung 4.8: Klassendiagramm der CodeScanner App<br />
4.3.3 Datenzugriffsklasse DataAccess<br />
Nach Abschluss eines erfolgreichen Scanvorgangs wird innerhalb der CodeScanner<br />
Activity-Klasse ein DataAccess-Objekt erzeugt und dabei der DataAccess-Konstruktor<br />
aufgerufen:<br />
Listing 4.9: Konstruktor der DataAccess-Klasse<br />
1 DataAccess ( Context context , S t r i n g s c a n r e s u l t ) {<br />
2 mContext = c o n t e x t ;<br />
3 p a r s e S c a n r e s u l t ( s c a n r e s u l t ) ;<br />
4 }<br />
Dem Konstruktur werden zwei Parameter übergeben. Zum Einen ein sogenanntes<br />
Context-Objekt, zum Anderen das Scan-Ergebnis als String (Codierung des Inhalts<br />
als Text, siehe Abschnitt 4.2.1.1). Beim Context wird in Android dabei zwischen<br />
dem Activity-Context und dem Application-Context unterschieden. Der Context einer<br />
Application ist über die Laufzeit der Anwendung immer gleich und stellt <strong>für</strong> jede<br />
Komponente (siehe 4.3.1.1) einen Verweis auf diese dar. Der Activity-Context (durch<br />
Vererbung ist eine Activity ein Context-Objekt) dient dabei als Schnittstelle <strong>für</strong> die<br />
UI-Elemente zur Activity. Oft muss in Android der Context übergeben werden, um<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 41<br />
auf Methoden (bspw. zur Einblendung eines Pop-up-Fenster) oder Resources (bspw.<br />
String-Resources) der Main-Activity zugreifen zu können. Der Context wird neben<br />
den anderen Dienstinformationen in einer Membervariable 12 innerhalb des erzeugten<br />
DataAccess-Objekts gespeichert. Anschließend wird zur Objektinitialisierung die Methode<br />
parseScanresult(scanresult) mit dem QR Code String-Parameter aufgerufen.<br />
4.3.3.1 Methode parseScanresult(...): Parsen der Scan-Ergebnisse<br />
Nach dem Scanvorgang liefert die ZXing Barcode Scanner App der Main-Activity einen<br />
Text mit dem in den QR Code codierten Inhalt zurück. Dieser Inhalt liegt als String<br />
vor und muss geparst werden. Parsen bedeutet, maschinenlesbaren Code zu analysieren<br />
und diesen in einzelne elementare Felder, die sogenannten Tokens zu trennen. Wie<br />
bereits in Abschnitt 4.2.1.1 diskutiert wurde, liegt der String nach der Decodierung<br />
wie folgt vor:<br />
1##Kaffeefahrt##49-1234-5678<br />
Die parseScanresult(...)-Methode interpretiert das Scan-Ergebnis wie folgt:<br />
Listing 4.10: Methode parseScanresult(...)<br />
1 p r i v a t e void p a r s e S c a n r e s u l t ( S t r i n g s c a n r e s u l t ) {<br />
2 boolean r e s u l t = t r u e ;<br />
3 S t r i n g [ ] s p l i t p h o n e n r = n u l l ;<br />
4<br />
5 S t r i n g [ ] s p l i t r e s u l t = s c a n r e s u l t . s p l i t ( "##" ) ;<br />
6 i f ( s p l i t r e s u l t . l e n g t h==3) s p l i t p h o n e n r = s p l i t r e s u l t [ 2 ] . s p l i t ( "-" ) ;<br />
7<br />
8 i f ( s p l i t r e s u l t . l e n g t h==3 && s p l i t p h o n e n r . l e n g t h==3) {<br />
9 mId=new I n t e g e r ( s p l i t r e s u l t [ 0 ] ) ;<br />
10 mTitle=s p l i t r e s u l t [ 1 ] ;<br />
11 mPhonenr=" tel :+"+s p l i t p h o n e n r [0]+ " ("+s p l i t p h o n e n r [1]+ ") "+<br />
s p l i t p h o n e n r [ 2 ] ;<br />
12 }<br />
13 e l s e r e s u l t = f a l s e ;<br />
14<br />
15 i f ( r e s u l t ) mStatus=Status . VALID ;<br />
16 e l s e mStatus=Status . INVALID ;<br />
17 }<br />
Zum Parsen wird die Methode split(String s) verwendet und das Scan-Ergebnis<br />
gleichzeitig auf seine Gültigkeit überprüft. Gültig ist der QR Code, wenn er nach dem<br />
Parsen durch die Trennzeichen ” ##“ in drei Teile, sowie die Telefonnummer als drittes<br />
Element nochmals in drei Abschnitte (mit ” -“ als Trennzeichen), getrennt werden kann.<br />
Es liegt dann ein gültiges Ergebnis vor und die Inhalte werden in die Membervariablen<br />
mId, mTitle und mPhonenr gespeichert. Die Telefonnummer wird dabei in das von<br />
der Internet Engineering Taskforce (IETF) vorgeschlagene Standardformat tel:(49)<br />
1234 5678 gebracht. [Int11b] Zeile 15 und 16 speichert letztlich noch den Status der<br />
Dienstabfrage in die Status-Membervariable.<br />
12 engl. Feldvariable, beginnen nach Java-Namenskonventionen mit einem kleinen m, gefolgt von einem<br />
großen Buchstaben<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 42<br />
4.3.3.2 Methode requestService(): Anforderung der Dienstinformationen<br />
Nach Parsen des Strings liegen nun die ID, der Titel und die Telefonnummer des<br />
Dienstes vor. Ist das Smartphone nicht mit dem Internet verbunden, so wird lediglich<br />
der Kurztitel angezeigt sowie die Möglichkeit gegeben sich mit einem Ansprechpartner<br />
verbinden zu lassen. Der Normalfall ist dagegen, dass eine Internetverbindung besteht<br />
und der Nutzer die vollständigen Dienstinformationen angezeigt bekommt. Diese auf<br />
der codierten ID basierenden Informationen werden, wie in Abschnitt 4.2.2.2 erläutert,<br />
über das PHP-Skript vom SQL Server abgefragt.<br />
Die Anfrage an das PHP-Skript weitblick_services.php (auf dem Webserver unter<br />
gagarin.e-technik.tu-ilmenau.de) erfolgt durch einen HTTP POST, dem ein Schlüsselwertpaar<br />
mit der ID (Zeile 6) übergeben wird:<br />
Listing 4.11: HTTP POST zur Anfrage der Dienstinformation über das PHP-Skript<br />
1 POST / w e i t b l i c k s e r v i c e s . php HTTP/ 1 . 1<br />
2 Host : g a g a r i n . e−t e c h n i k . tu−ilmenau . de<br />
3 Content−type : a p p l i c a t i o n /x−www−form−urlencoded<br />
4 Content−l e n g t h : 4<br />
5<br />
6 i d=1<br />
Der HTTP POST wird mit dem HTTP-Client, der in Android standardmäßig implementierten,<br />
externen Library org.apache.http.*, realisiert:<br />
Listing 4.12: Auszug aus Methode requestService()<br />
1 HttpClient c l i e n t = new D e f a u l t H t t p C l i e n t ( ) ;<br />
2 HttpPost post = new HttpPost (SQLHOST) ;<br />
3 L i s t nameValuePair = new ArrayList () ;<br />
4 nameValuePair . add ( new BasicNameValuePair ( "id" , mId . t o S t r i n g ( ) ) ) ;<br />
5 post . s e t E n t i t y ( new UrlEncodedFormEntity ( nameValuePair ) ) ;<br />
6 HttpResponse r e s p o n s e = c l i e n t . e x e c u t e ( post ) ;<br />
7<br />
8 HttpEntity e n t i t y = r e s p o n s e . g e t E n t i t y ( ) ;<br />
9 Inputstream i s = e n t i t y . getContent ( ) ;<br />
10<br />
11 BufferedReader s e r v i c e r e a d e r = new BufferedReader ( new InputStreamReader ( i s , "UTF -8" ) , 8 )<br />
;<br />
12 S t r i n g r e s u l t=s e r v i c e r e a d e r . readLine ( ) ;<br />
13 i s . c l o s e ( ) ;<br />
Zeile 1 und 2 erstellen eine Instanz des HTTP-Clients und einen HTTP POST (mit<br />
der Adresse gagarin.e-technik.tu-ilmenau.de des SQL Servers). Nachdem dem HTTP<br />
POST das Schlüsselwertpaar mit der ID aus mId hinzugefügt wurde, wird dieser abgeschickt<br />
(Zeile 3-6) und die HTTP Antwort des PHP Skripts über einen InputStream<br />
und einen BufferedReader in einen String geladen (Zeile 8-12). Dieser beinhaltet (siehe<br />
PHP-Skript unter A.1) den Titel, die Beschreibung, den Zeitpunkt, die Kosten, die<br />
Telefonnummer sowie die Dauer des angefragten Dienst (basierend auf dem in mId gespeicherten<br />
Wert). Nach Parsen dieses zusammenhängenden Strings werden die einzelnen<br />
Datenfelder in einem Array mService des Typs ArrayList gespeichert.<br />
Die Dienstinformationen können durch den Zugriff auf die Array-Elemente von mService<br />
des erzeugten DataAccess-Objekts nun von der Activity abgerufen und angezeigt<br />
werden.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 43<br />
Das Absenden der Anfrage kann je nach Güte der Verbindung einige hundert Millisekunden<br />
dauern. Die Android App wird zur Laufzeit so lange warten, bis die HTTP Anfrage<br />
abgeschickt und wieder eine Antwort zurückgekommen ist. Dies bedeutet gleichzeitig,<br />
dass das User Interface <strong>für</strong> diesen Moment stehen bleibt und nicht reagiert.<br />
Der Grund hier<strong>für</strong> liegt darin, dass alle Operationen in einem einzigen Main-Thread,<br />
auch UI-Thread genannt, ausgeführt werden. Dies betrifft sowohl Operationen, die<br />
das User Interface zeichnen, als auch zeitintensive Netzwerkzugriffe wie eine solche<br />
Datenbankabfrage. Für den Nutzer stellt sich ein Einfrieren des UIs als ein sehr unangenehmes<br />
Nutzungserlebnis dar. Um das Blockieren dieses UI-Threads beim Anfragen<br />
der Dienstinformationen zu verhindern, wird die Datenbankabfrage in einen separaten<br />
Worker-Thread ausgelagert. Statt requestService() direkt aufzurufen, wird der<br />
Aufruf über die Methode requestServiceThread() (über einen Thread) umgeleitet:<br />
Listing 4.13: Methode requestServiceThread()<br />
1 p r i v a t e void r e q u e s t S e r v i c e T h r e a d ( ) {<br />
2 ( ( CodeScanner ) mContext ) . showProgressDialog ( showProgressDlgMsg .LOADSERVICE) ;<br />
3 // s t a r t a worker−thread<br />
4 Thread t = new Thread ( ) {<br />
5 p u b l i c void run ( ) {<br />
6 r e q u e s t S e r v i c e ( ) ;<br />
7 mHandler . post ( mUpdateBookingLayout ) ;<br />
8 }<br />
9 } ;<br />
10 t . s t a r t ( ) ;<br />
11 }<br />
Innerhalb dieser wird ein neuer Worker-Thread gestartet, der den zeitintensiven Datenbankzugriff<br />
ausführt (Zeile 4). Das Attribut mHandler startet die Runnable mUpdateBookingLayout<br />
(eine Art Methode), die die Funktion initBookingLayout() aus<br />
der CodeScanner Klasse aufruft. Um dem Nutzer eine Rückmeldung über die andauernde<br />
Operation zu geben, wird durch das Starten einer showProgressDialog(...)-<br />
Methode (Zeile 2) aus der CodeScanner Activity eine Fortschrittsanzeige angezeigt.<br />
4.3.3.3 Methode sendMessage(...): Buchen des Dienstes<br />
Nachdem der Dienst auf dem UI angezeigt wird, hat der Nutzer die Möglichkeit den<br />
Dienst direkt über das Internet zu buchen. Dazu müssen die Dienstinformationen mit<br />
der Nutzer-ID an den openMQ Server übermittelt werden. Den Inhalt der Nachricht<br />
formatiert die Funktion formatMessage(), die die formatierte Nachricht als String<br />
zurückgibt:<br />
Listing 4.14: Methode formatMessage()<br />
1 p u b l i c S t r i n g formatMessage ( ) {<br />
2 // i f confirmmail i s s e t to true , a booking c o n f i r m a t i o n i s s e n t by mail<br />
through email−gateway<br />
3 S t r i n g confirmmail = mContext . g e t R e s o u r c e s ( ) . g e t S t r i n g (R. s t r i n g . confirmMail ) .<br />
t o S t r i n g ( ) ;<br />
4 S t r i n g B u f f e r m = new S t r i n g B u f f e r ( ) ;<br />
5 m. append ( " User :"+mLogin . get ( 0 )+"; " ) ;<br />
6 m. append ( " ServiceID :"+mId+"; " ) ;<br />
7 m. append ( " ServiceTitle :"+mService . get ( 0 )+"; " ) ;<br />
8 m. append ( " ServiceDate :"+mService . get ( 2 )+"; " ) ;<br />
9 m. append ( " SendConfMail :"+confirmmail ) ;<br />
10 r e t u r n m. t o S t r i n g ( ) ;<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
11 }<br />
4 Praktische Umsetzung 44<br />
Die zu sendenden Informationen sind in den Attributen mLogin und mService des<br />
DataAccess-Objekts gespeichert. Dies betrifft den vom Nutzer eingegebenen Loginnamen<br />
(als Login <strong>für</strong> den openMQ Server), die ID sowie den Zeitpunkt des Dienstes.<br />
Zuletzt wird noch ein Boolean-Wert eingesetzt, welcher anzeigt, ob die Buchung durch<br />
eine E-Mail-Nachricht an den Nutzer sowie den Dienstanbieter bestätigt werden soll.<br />
Der Boolean-Wert wird in einer String-Resource der Anwendung gespeichert, um diesen<br />
zentral in der Resource-Datei setzen zu können.<br />
Die formatierte Nachricht wird anschließend der Sende-Methode sendMessage (String<br />
message) übergeben. Diese baut mit dem unter 4.2.2.1 erläuterten UMS Server<br />
eine verschlüsselte SSL Verbindung auf und übermittelt den Inhalt der formatierten<br />
Nachricht durch einen HTTP POST (siehe Programmcodeabschnitt 4.1) an den UMS<br />
Server, der diese in einer JMS-konformen Nachricht zum openMQ Server weiterleitet.<br />
Um mit dem UMS Server eine gesicherte SSL Verbindung aufbauen zu können, muss<br />
der Tomcat Server (auf dem der UMS läuft) <strong>für</strong> die SSL Verbindung konfiguriert sein<br />
und ein SSL Zertifikat installiert werden. Auf Basis dieses Zertifikats findet zunächst ein<br />
asymmetrischer Schlüsselaustausch statt. Wie in 4.2.2.1 bereits erläutert, gibt es zertifizierte<br />
Zertifizierungsstellen (Certification Authority, kurz CA), wie z. B. thawte.com,<br />
die solche ” trusted“ Zertifikate gegen eine jährliche Gebühr ausstellen. Zertifikate der<br />
meisten CAs sind bereits in den Internetbrowsern sowie SDKs integriert, wodurch der<br />
Client vor dem Verbindungsaufbau das Zertifikat nicht mehr herunterladen muss. Das<br />
vorinstallierte Zertifikat wird mit dem sich auf dem Server befindlichen gegengeprüft<br />
und der Server damit authentifiziert. Die Zertifikate werden beim Client in einem sogenannten<br />
Keystore, dem Zertifikatsspeicher, aufbewahrt. Wird eine Webseite aufgerufen<br />
und ist das Zertifikat nicht im Keystore des Browser gespeichert, so wird der Nutzer<br />
aufgefordert das Zertifikat zu akzeptieren und in den Browser zu importieren. Eine<br />
Importierung eines Zertifikats in den Android Keystore würde ein erhebliches Sicherheitsrisiko<br />
darstellen, da alle anderen Anwendungen dem Server des dazugehörigen<br />
Zertifikats vertrauen würden. Es ist daher bei Android nicht gestattet, Zertifikate in<br />
den Android Keystore zu importieren. [BP09, S. 295]<br />
Für die WEITBLICK CodeScanner App wird ein von der <strong>TU</strong> <strong>Ilmenau</strong> CA ausgestelltes<br />
Zertifikat verwendet. Das Zertifikat der <strong>TU</strong> <strong>Ilmenau</strong> CA ist als Zwischenzertifizierungsstelle<br />
standardmäßig nicht in den Keystore der Browser und auch nicht in den<br />
von Android integriert. Um die CodeScanner App dennoch mit dem UMS Server über<br />
HTTPS kommunizieren zu lassen, muss hier<strong>für</strong> ein eigener Keystore mit dem Zertifikat<br />
der <strong>TU</strong> <strong>Ilmenau</strong> CA erstellt und dieser in die App integriert werden. Dazu wird, wie<br />
in [BP09, S. 297-299] beschrieben, vorgegangen:<br />
1. Aufruf des Tomcat Webservers mit dem Internet Explorer unter https://gagarin.etechnik.tu-ilmenau.de:8443<br />
2. Speicherung und Konvertierung des Zertifikats in das Format ” DER-codiert-binär<br />
X.509 (.CER)“<br />
3. Installation des Bouncy-Castle-Provider ins JDK<br />
Das JDK beinhaltet das Java Cryptography Extension (JCE)-Modul, welches<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 45<br />
ebenfalls durch das Android SDK implementiert ist. Im JCE sind Verschlüsselalgorithmen,<br />
die sogenannten Provider implementiert. Da Android den ” Bouncy<br />
Castle Provider“ verwendet, muss dieser zunächst in das JDK integriert werden,<br />
um mit dem JDK einen Keystore erzeugen zu können.<br />
4. Erstellen des Keystores mit dem Keytool des JDK<br />
keytool -v -import -storetype BKS -storepass KSPASS -trustcacerts -alias weitblick<br />
-file saved cert.cer -keystore weitblick.bks<br />
Der Parameter ” storetype BKS“ steht <strong>für</strong> den verwendeten ” Bouncy Castle Provider“.<br />
Das angegebene Passwort ” Storepass KSPASS“ wird zur Importierung<br />
des Keystores in die Android App benötigt.<br />
Die damit erstellte Keystore-Datei weitblick.bks wird in das ” /res/raw/“ Verzeichnis<br />
des Android-Projekts kopiert. Die Implementierung des Keystores in die Android<br />
App, das Herstellen der SSL Verbindung sowie das Senden der Nachricht zeigt der<br />
folgende Quellcode:<br />
Listing 4.15: Methode sendMessage(String message)<br />
1 p u b l i c void sendMessage ( S t r i n g message ) {<br />
2 s e n t = f a l s e ;<br />
3 f i n a l S t r i n g UMSSERVER = mContext . g e t R e s o u r c e s ( ) . g e t S t r i n g (R. s t r i n g .<br />
UMSSERVER) ;<br />
4<br />
5 t r y {<br />
6 // Creates k e y s t o r e<br />
7 InputStream i s = mContext . g e t R e s o u r c e s ( ) . openRawResource (R. raw<br />
. w e i t b l i c k ) ;<br />
8 KeyStore k e y s t o r e = KeyStore . g e t I n s t a n c e ( " BKS " ) ;<br />
9 k e y s t o r e . load ( i s , " w31tbl1ck " . toCharArray ( ) ) ;<br />
10<br />
11 // Creates SSL c o n n e c t i o n<br />
12 SSLSocketFactory s o c k e t F a c t o r y = new org . apache . http . conn . s s l .<br />
SSLSocketFactory ( k e y s t o r e ) ;<br />
13 s o c k e t F a c t o r y . s e t H o s t n a m e V e r i f i e r ( org . apache . http . conn . s s l .<br />
SSLSocketFactory . STRICT HOSTNAME VERIFIER) ;<br />
14<br />
15 f i n a l Scheme h t t p s = new Scheme ( " https " , socketFactory , 8443) ;<br />
16<br />
17 HttpClient c l i e n t = new D e f a u l t H t t p C l i e n t ( ) ;<br />
18 c l i e n t . getConnectionManager ( ) . getSchemeRegistry ( ) . r e g i s t e r (<br />
h t t p s ) ;<br />
19 HttpPost post = new HttpPost (UMSSERVER+"/ imqums / simple ? service = send &<br />
destination = DVB_Rueckkanal & user ="+mLogin . get ( 0 )+"& password ="+<br />
mLogin . get ( 1 ) ) ;<br />
20 post . addHeader ( " Content - Type " , " text / html ; charset =utf -8" ) ;<br />
21 HttpEntity e n t i t y = new S t r i n g E n t i t y ( message , "UTF -8" ) ;<br />
22 post . s e t E n t i t y ( e n t i t y ) ;<br />
23 HttpResponse r e s p o n s e = c l i e n t . e x e c u t e ( post ) ;<br />
24<br />
25 S t a t u s L i n e s t a t u s = r e s p o n s e . g e t S t a t u s L i n e ( ) ;<br />
26 Header umsservice = r e s p o n s e . g e t F i r s t H e a d e r ( " ums . service " ) ;<br />
27 Header umsstatus = r e s p o n s e . g e t F i r s t H e a d e r ( " ums . status " ) ;<br />
28 boolean i s s t a t u s o k = s t a t u s . t o S t r i n g ( ) . c o n t a i n s ( " 200 " ) ;<br />
29 boolean i s r e p l y o k = u msservice . getValue ( ) . t o S t r i n g ( ) . e q u a l s ( "<br />
send_reply " ) ;<br />
30 boolean i s u m s s t a t u s o k = umsstatus . getValue ( ) . t o S t r i n g ( ) . e q u a l s<br />
( " 200 " ) ;<br />
31<br />
32<br />
33 i f ( i s s t a t u s o k && i s r e p l y o k && i s u m s s t a t u s o k ) s e n t = t r u e ;<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 46<br />
34 } catch ( Exception e ) {<br />
35 Log . e ( " httppost " , " Error in https connection :"+e . t o S t r i n g ( ) ) ;<br />
36 }<br />
37 }<br />
Zunächst wird in den Zeilen 7-9 der Keystore aus der als Raw-Resource abgelegten<br />
Keystore-Datei geladen. Die SSLSocketFactory, die als Basis der SSL Verbindung<br />
dient, wird anschließend in Zeile 12 mit dem zuvor eingelesenen Keystore<br />
initialisiert. SSL-Zertifikate sind normalerweise an einen DNS-Namen gebunden.<br />
Das Zertifikat wurde <strong>für</strong> den DNS-Namen gagarin.e-technik.tu-ilmenau.de von der<br />
<strong>TU</strong> <strong>Ilmenau</strong> CA ausgestellt, wodurch der HostnameVerifier der SSLSocketFactory<br />
auf STRICT_HOSTNAME_VERIFIER gesetzt wird, um als zusätzliche Sicherheitsstufe den<br />
Servernamen gegenzuprüfen. Die Erzeugung eines Apache HTTP-Clients erfolgt analog<br />
zur requestService()-Methode (siehe Programmcodeabschnitt 4.12). Zusätzlich<br />
muss der Client allerdings mit dem HTTPS-Schema der SSLSocketFactory mit dem<br />
Keystore und dem Port 8443 (entsprechend der Konfiguration des Tomcat/UMS Servers)<br />
registriert werden. In Zeile 19 wird die HTTP Anfrage gemäß des POSTs im<br />
Programmcodeabschnitt 4.1 erstellt. Im Unterschied zum HTTP POST in der requestService()-Methode<br />
wird statt einem Schlüsselwertpaar ein String mit der über<br />
formatMessage()-erstellten Nachricht gesendet. Um zu überprüfen, ob die Nachricht<br />
an den openMQ Server erfolgreich übermittelt wurde, wird in Zeile 25-33 die HTTP<br />
Antwort des UMS Servers auf den HTTP Statuscode sowie die zusätzlichen Header<br />
” ums.service“ und ums.status“ untersucht und das Ergebnis in der Boolean-Variablen<br />
”<br />
sent gespeichert. Da dieser HTTP Request ebenfalls eine zeitintensive Operation darstellt<br />
und ein Einfrieren des UI zu vermeiden ist, wird das Ausführen dieser Operation<br />
über den Aufruf der sendMessageThread()-Methode in einen separaten Worker-<br />
Thread ausgelagert. Nach Beendigung der sendMessage()-Funktion ruft eine Runnable<br />
die Methode showBooked(sent) aus der Activity-Klasse auf. Dadurch wird in<br />
Abhängigkeit des übergebenen Boolean-Parameters über die Activity-Klasse ein entsprechender<br />
Buchungsbestätigungsdialog (oder im negativem Fall ein Buchungsfehler)<br />
angezeigt.<br />
4.3.4 Main-Activity CodeScanner<br />
Im letzten Abschnitt wurde erläutert, wie die Datenzugriffe der DataAccess-Klasse<br />
funktionieren. Alle angefragten Daten werden dabei in einem einzigen DataAccess-<br />
Objekt gespeichert. Die Aufgabe der Main-Activity CodeScanner ist es in Abhängigkeit<br />
von der im DataAccess-Objekt gesetzten Attribute die Inhalte entsprechend<br />
darzustellen. Des Weiteren gibt sie über Pop-ups bzw. Dialoge Rückmeldungen zu den<br />
in der DataAccess-Klasse ausgeführten Aktionen. In diesem Abschnitt wird dabei auf<br />
Methoden eingegangen, die <strong>für</strong> die Erfüllung der verbleibenden Teilaufgaben<br />
3. Realisierung einer Anwendung auf dem Smartphone zur Erkennung der optischen<br />
Marke<br />
4. Übermittlung der Buchungsinformation an einen Server<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 47<br />
5. Anruf einer mitcodierten Telefonnummer<br />
nötig sind. Zusätzlich wurde bspw. eine addEvent()-Methode implementiert. Der<br />
Nutzer hat demnach die Möglichkeit den Termin der gebuchten Dienstleistung in dessen<br />
Kalender auf dem Smartphone eintragen und sich so automatisch an diesen erinnern<br />
zu lassen. Für diese und weitere Funktionalitäten sowie der Erläuterung des gesamten<br />
Quellcodes (siehe Kommentarzeilen) sei hiermit auf den Anhang verwiesen.<br />
4.3.4.1 Methode initScanningLayout(): Aufruf der externen ZXing Barcode<br />
Scanner App<br />
Nach Starten der CodeScanner App wird die onCreate(...)-Methode der Activity<br />
aufgerufen. Nach Initialisierung der UI-Elemente und Prüfung auf ein nicht vorhandenes<br />
DataAccess-Objekt wird die initScanningLayout()-Prozedur aufgerufen. Diese<br />
blendet das in der codescanner.xml definierte ScanningLayout ein und belegt den<br />
Scan-Button wie folgt mit einem onClick Listener:<br />
Listing 4.16: onClick Listener und Initiierung des Scanvorgangs<br />
1 btn scan . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n er ( ) {<br />
2 @Override<br />
3 p u b l i c void onClick ( View v ) {<br />
4 S t r i n g [ ] d l g s c a n n e r d l = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R. array . d l g s c a n n e r d l ) ;<br />
5 I n t e n t I n t e g r a t o r . i n i t i a t e S c a n ( CodeScanner . t h i s , d l g s c a n n e r d l [ 0 ] , d l g s c a n n e r d l<br />
[ 1 ] , d l g s c a n n e r d l [ 2 ] , d l g s c a n n e r d l [ 3 ] , " QR_CODE " ) ;<br />
6 }<br />
7 }) ;<br />
Nach Klicken des Buttons wird die statische Methode initiateScan(...) aus der<br />
Klasse IntentIntegrator aufgerufen. Der Scanvorgang der externen ZXing Barcode<br />
Scanner App könnte auch mit einem einfachen Intent gestartet werden. Der Intent<br />
würde allerdings ins Leere laufen, falls die ZXing App nicht auf dem Smartphone installiert<br />
ist. Aus diesem Grund wird die Utility-Klasse IntentIntegrator aus dem ZXing<br />
Projekt mit in die CodeScanner App implementiert. Drückt der Nutzer den ” Code<br />
scannen“ -Button, so wird die statische Methode initiateScan(...) mit dem aktuellen<br />
Activity-Context, den Strings zur Darstellung eines Download-Dialogs und die zu<br />
scannende Codeart ” QR CODE“ (dadurch wird das Scannen eines QR Codes erzwungen)<br />
aufgerufen. Ist der ZXing Barcode Scanner nicht auf dem Smartphone installiert,<br />
so blendet die IntentIntegrator Klasse einen Download-Dialog mit den übergebenen<br />
Strings ein, welcher eine Installation der ZXing App über den Android Market initiiert.<br />
Nach der Installation kann der QR Code mit der CodeScanner App gescannt<br />
werden.<br />
Die initiateScan(...)-Methode der IntentIntegrator-Klasse sendet durch<br />
Intent intentScan = new Intent( ” com.google.zxing.client.android.SCAN“);<br />
startActivityForResult(intentScan, REQUEST CODE);<br />
einen impliziten Intent und ruft damit den Scandialog der ZXing App auf, wodurch<br />
die CodeScanner Activity pausiert und der Nutzer den WEITBLICK QR Code<br />
scannen kann. Zusätzlich wird der startActivityForResult(...)-Methode ein<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 48<br />
” REQUEST CODE“ vom Typ Integer übergeben. Nach Abschluss des Scanvorgangs<br />
schließt sich diese Activity wieder und die Scan-Ergebnisse werden an die reaktivierte<br />
CodeScanner Activity gesendet. Anhand des vorher übergebenen REQUEST CODE“<br />
”<br />
wird die Rückgabe der Scan-Activity identifiziert und gehandelt.<br />
4.3.4.2 Verarbeiten der Scan-Ergebnisse und Erstellen eines<br />
DataAccess-Objekts<br />
Durch Starten einer anderen Activity wird durch startActivityForResult(...) statt<br />
mit startActivity(...) von der aufzurufenden Activity ein Ergebnis erwartet. Nach<br />
Beendigung dieser Activity und beim Reaktivieren der aufrufenden Activity wird in<br />
dieser die Methode onActivityResult(...) aufgerufen. Diese muss demnach überschrieben<br />
werden, um die Scan-Ergebnisse der Barcode Scanner App abzufangen:<br />
Listing 4.17: Überschriebene Methode onActivityResult(...): Abfangen der Scan-<br />
Ergebnisse und Erstellen eines DataAccess-Objekts<br />
1 @Override<br />
2 p u b l i c void o n A c t i v i t y R e s u l t ( i n t requestCode , i n t resultCode , I n t e n t i n t e n t ) {<br />
3 I n t e n t R e s u l t s c a n R e s u l t = I n t e n t I n t e g r a t o r . p a r s e A c t i v i t y R e s u l t ( requestCode ,<br />
resultCode , i n t e n t ) ;<br />
4 i f ( s c a n R e s u l t != n u l l ) {<br />
5 S t r i n g mScanresult=s c a n R e s u l t . getContents ( ) ;<br />
6 da = new DataAccess ( t h i s , mScanresult ) ;<br />
7 initBookingLayout ( ) ;<br />
8 }<br />
9 e l s e Log . e ( " scan_error " , " scanning error " ) ;<br />
10 }<br />
Dabei werden durch die ZXing Activity die Integer-Werte requestCode und result-<br />
Code sowie ein Intent zurückgegeben, welche durch die statische Methode parseActivityResult<br />
aus der IntentIntegrator Klasse geparst werden. Diese überprüft den requestCode<br />
(ein beliebig festgelegter Integer-Wert) auf den durch die IntentIntegrator<br />
Klasse zuvor übergebenen ” REQUEST CODE“ und den resultCode auf den Wert<br />
” RESULT OK“ und gibt eine Instanz der Klasse IntentResult 13 zurück. Durch Anwendung<br />
der Funktion getContents() auf das IntentResult-Objekt wird im String<br />
mScanresult das Ergebnis des Scanvorgangs (in textueller Form) gespeichert. Folglich<br />
erzeugt Zeile 6 das DataAccess-Objekt da und übergibt dem DataAccess-Konstruktor<br />
den Activity-Context sowie den String mScanresult. Eine Instanziierung führt gleichzeitig<br />
zum Parsen der Scan-Ergebnisse durch die DataAccess-Methode parseScanresult(...)<br />
(siehe Abschnitt 4.3.3.1).<br />
Ab dieser Stelle der Anwendung greift die Main-Activity auf das da-Objekt zu, um<br />
die gescannten Daten abzufragen. Durch Abschluss des Scanvorgangs wird zuletzt noch<br />
das BookingLayout zur Anzeige der Dienstleistung initialisiert.<br />
4.3.4.3 Methode initBookingLayout(): Anzeige der Dienstleistung<br />
Immer dann, wenn in der Anwendung die Methode initBookingLayout(...) aufgerufen<br />
wird, soll das BookingLayout, wie in Abb. 4.7 gezeigt, dargestellt werden. Um<br />
13 diese Klasse wurde neben IntentIntegrator ebenfalls ins CodeScanner Projekt importiert<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 49<br />
je nach Status der Dienstabfrage einen entsprechenden Inhalt darstellen zu können,<br />
greift die CodeScanner Activity auf die Feldvariable mStatus des Enumerationstyp<br />
Status aus der DataAccess-Klasse zu. Die mStatus-Variable kann die folgenden Werte<br />
annehmen: ” VALID“, ” INVALID“, VALID PROCESSING und ” VALID INET“. Die<br />
initBookingLayout()-Methode prüft mStatus auf die Werte von Status und reagiert<br />
anhand einer switch(da.mStatus)-Anweisung entsprechend:<br />
INVALID : Der gescannte QR Code ist ungültig. Die Buttons Dienst buchen“ und<br />
”<br />
” über Telefon buchen“ werden deaktiviert und es wird eine Meldung angezeigt,<br />
einen gültigen Code erneut zu scannen.<br />
VALID NO INET : Das Smartphone ist nicht mit dem Internet verbunden. Der Button<br />
” Dienst buchen“ wird deaktiviert. Basierend auf dem Inhalt der im QR Code<br />
codierten Informationen wird die Titel-TextView mit dem Kurztitel befüllt und<br />
der Button ” über Telefon buchen“ mit einem onClick Listener aktiviert.<br />
VALID PROCESSING : Solange wie Dienst angefordert wird (innerhalb einiger hundert<br />
Millisekunden) nimmt das mStatus-Feld diesen Wert an. Für einen kurzen<br />
Moment werden die UI-Elemente mit dem Kurztitel und der Telefonnummer aus<br />
dem QR Code, wie beim VALID NO INET -Wert, aktiviert.<br />
VALID INET Dies ist der Normalfall. Der QR Code ist gültig, es besteht eine Internetverbindung,<br />
alle Daten zur Dienstleistung wurden abgefragt und liegen im<br />
Feld mService vor. Die vier TextViews werden mit den Daten Titel, Beschreibung,<br />
Zeitangabe und Kosten des Dienstes befüllt. Die Buttons ” Dienst buchen“<br />
und ” über Telefon buchen“ wurden mit einem onClick Listener versehen.<br />
In allen Fällen ist die Möglichkeit gegeben, den Dienst erneut zu scannen. Der Button<br />
” Erneut scannen“ ist bei jedem Status aktiv und mit einem onClick Listener aktiviert,<br />
um die initiateScan(...) aufzurufen und einen neuen Scanvorgang zu initiieren.<br />
Den Wert VALID“ kann mStatus zur switch-Anweisung nicht besitzen, denn vor<br />
”<br />
Ausführung der switch-Anweisung wird in der initBookingLayout()-Methode der<br />
Status durch den Aufruf von setStatus() aus der DataAccess-Klasse neu gesetzt:<br />
Listing 4.18: Methode setStatus(): Steuerung des Ablaufs der Dienstabfrage<br />
1 p u b l i c void s e t S t a t u s ( ) {<br />
2 switch ( mStatus ) {<br />
3 c a s e INVALID :<br />
4 break ;<br />
5 c a s e VALID :<br />
6 i f ( c h e c k I n e t ( mContext ) ) mStatus=Status . VALID PROCESSING ;<br />
7 e l s e mStatus=Status . VALID NO INET ;<br />
8 s e t S t a t u s ( ) ;<br />
9 break ;<br />
10 c a s e VALID PROCESSING :<br />
11 r e q u e s t S e r v i c e T h r e a d ( ) ;<br />
12 break ;<br />
13 c a s e VALID INET :<br />
14 break ;<br />
15 c a s e VALID NO INET :<br />
16 s e t O f f l i n e S e r v i c e ( ) ;<br />
17 break ;<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 50<br />
18 }<br />
19 }<br />
Initiiert wird mStatus in der Methode parseScanresult() mit den Werten ” VALID“<br />
(<strong>für</strong> einen gültigen und geparsten QR Code) oder ” INVALID“ <strong>für</strong> einen ungültigen QR<br />
Code (siehe Codeabschnitt 4.10, Zeile 15 bzw. 16). Im Falle von ” VALID“ wird mStatus<br />
nach Prüfung einer vorhandenen Internetverbindung durch checkInet() entsprechend<br />
auf ” VALID NO INET“ oder ” VALID PROCESSING“ gesetzt. Anschließend ruft sich<br />
setStatus() rekursiv erneut auf. Ist mStatus nach fehlgeschlagenem Internetverbindungscheck<br />
” VALID NO INET“, werden die Dienstinformationen in mService bis auf<br />
Titel und Telefonnummer (aus dem QR Code) durch die Funktion setOfflineService()<br />
mit leeren Strings befüllt.<br />
Wurde mStatus nach einem positiven Internetverbindungscheck auf ” VALID PRO-<br />
CESSING“ gesetzt, werden die Dienstinformationen durch Aufruf von requestServiceThread()<br />
über einen separaten Worker-Thread angefragt. Durch Auslagerung in<br />
einen separaten Worker-Thread arbeitet die Laufzeitumgebung den Code weiter ab<br />
und befüllt währenddessen durch die initBookingLayout()-Methode das Layout mit<br />
den im QR Code befindlichen Daten. Ist die Dienstabfrage beendet, so setzt die Runnable<br />
mUpdateBookingLayout aus der DataAccess-Klasse (siehe 4.3.3.2) den Wert von<br />
mStatus auf ” VALID INET“ und ruft initBookingLayout() erneut auf. Damit wird<br />
das Layout mit den nun in mService gespeicherten Dienstinformationen befüllt.<br />
Letztendlich setzt sich die initBookingLayout()-Methode wie folgt zusammen:<br />
Listing 4.19: Methode initBookingLayout()<br />
1 p u b l i c void initBookingLayout ( ) {<br />
2 l a y o u t s c a n n i n g . s e t V i s i b i l i t y ( View . INVISIBLE ) ;<br />
3 l a y o u t b o o k i n g . s e t V i s i b i l i t y ( View . VISIBLE ) ;<br />
4<br />
5 // to r e a c t whether scanned code i s v a l i d , i n e t i s a v a i l a b l e e t c . invoke<br />
s e t S t a t u s ( ) being a b l e to r e a c t to i t<br />
6 da . s e t S t a t u s ( ) ;<br />
7<br />
8 switch ( da . mStatus ) {<br />
9 c a s e VALID NO INET :<br />
10 c a s e VALID INET :<br />
11 t x t t i t l e . setText ( da . mService . get ( 0 ) ) ;<br />
12 t x t d e s c . setText ( da . mService . get ( 1 ) ) ;<br />
13 t x t d a t e . setText ( da . mService . get ( 2 ) ) ;<br />
14 t x t c o s t s . setText ( da . mService . get ( 3 )+" EUR " ) ;<br />
15 i f ( da . mStatus==Status . VALID NO INET) {<br />
16 t x t c o s t s . setText ( "" ) ;<br />
17 b t n b o o k s e r v i c e . setEnabled ( f a l s e ) ;<br />
18 }<br />
19 b t n b o o k s e r v i c e . setEnabled ( t r u e ) ;<br />
20 b t n b o o k s e r v i c e . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
21 @Override<br />
22 p u b l i c void onClick ( View v ) {<br />
23 da . loginAndSend ( ) ;<br />
24 }<br />
25 }) ;<br />
26 btn makecall . setEnabled ( t r u e ) ;<br />
27 btn makecall . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
28 @Override<br />
29 p u b l i c void onClick ( View v ) {<br />
30 makeCall ( ) ;<br />
31 }<br />
32 }) ;<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 51<br />
33 b t n r e s c a n . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
34 @Override<br />
35 p u b l i c void onClick ( View v ) {<br />
36 S t r i n g [ ] d l g s c a n n e r d l = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y<br />
(R. array . d l g s c a n n e r d l ) ;<br />
37 I n t e n t I n t e g r a t o r . i n i t i a t e S c a n ( CodeScanner . t h i s ,<br />
d l g s c a n n e r d l [ 0 ] , d l g s c a n n e r d l [ 1 ] , d l g s c a n n e r d l<br />
[ 2 ] , d l g s c a n n e r d l [ 3 ] , " QR_CODE " ) ;<br />
38 }<br />
39 }) ;<br />
40 break ;<br />
41 c a s e VALID PROCESSING :<br />
42<br />
43 [ . . . ]<br />
Um auf die in der codescanner.xml (unter Codeabschnitt 4.7) definierten UI-<br />
Elemente vom Programmcode aus zugreifen zu können, ist es nötig diese vorher im<br />
Code zu intialisieren und durch findViewById(id) einem UI-Element der angegebenen<br />
Resource ID zuzuweisen. Beispielhaft zeigt dies folgende Codezeile <strong>für</strong> das Scan-<br />
Button-Element:<br />
Button btn scan = (Button) findViewById(R.id.btn scan);<br />
Als Konventionen <strong>für</strong> die Benennung der UI-Objekte im Programmcode wurden die<br />
Präfixe layout “ <strong>für</strong> ein Layout, btn “ <strong>für</strong> einen Button, txt “ <strong>für</strong> eine TextView und<br />
” ” ”<br />
” img “ <strong>für</strong> ein Image festgelegt.<br />
Nach Ausblenden des ScanningLayouts und Einblenden des BookingLayouts erfolgt<br />
in Zeile 6 die Steuerung der Dienstabfrage und das Setzen des Status durch die setStatus()-Methode.<br />
Die switch-Anweisung wurde <strong>für</strong> den Fall eines korrekt eingescannten<br />
und bereits abgefragten Dienstes betrachtet. mStatus hat in diesem Fall den Wert<br />
” VALID INET“. In Zeile 11-14 werden die TextViews durch setText(...) mit den<br />
entsprechenden Inhalten aus der Variablen mService befüllt. Zeile 19-39 aktiviert die<br />
drei Buttons jeweils mit einem onClick Listener, der entsprechende Aktionen ausführt:<br />
Button ” Dienst buchen“ : Es wird die Methode loginAndSend() aus der DataAccess-<br />
Klasse aufgerufen. Diese prüft, ob <strong>für</strong> die Anwendung bereits ein Login gespeichert<br />
wurde. Falls nicht, öffnet sich ein Logindialog, zu dem der Nutzer einen<br />
vorher vom Dienstanbieter zugewiesenen Benutzernamen und ein Passwort (User-<br />
Login) eingeben muss. Ist dies geschehen, wird die vorher beschriebene sendMessage()-Methode<br />
aufgerufen und die über formatMessage() erstellte Nachricht<br />
an den openMQ Server gesendet.<br />
Button ” über Telefon buchen“ : Die onClick-Funktion ruft die Methode makeCall()<br />
auf, die einen Anruf an die in der optischen Marke bzw. im Datensatz des Dienstes<br />
gespeicherte Telefonnummer initiiert. Die Funktionsweise der makeCall()-<br />
Funktion wird im nächsten Abschnitt beschrieben.<br />
Button ” Erneut scannen“ : Dieser Button ist in jeder case-Anweisung aktiviert. Der<br />
Nutzer hat unabhängig vom mStatus-Wert die Möglichkeit erneut einen QR Code<br />
zu scannen.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 52<br />
4.3.4.4 Methode makeCall(): Verbindung mit einem Ansprechpartner<br />
Falls der Nutzer noch Fragen zum angezeigten Dienst hat oder lieber mit einem Ansprechpartner<br />
persönlich sprechen möchte anstatt den Dienst direkt zu buchen, hat er<br />
die Möglichkeit, sich mit einer auf den angezeigten Dienst angepassten Telefonnummer<br />
verbinden zu lassen. Da die Nummer in den QR Code direkt codiert ist, kann der<br />
Nutzer auch bei nicht vorhandener Internetverbindung die codierte Nummer anrufen.<br />
Der Anruf wird durch die Methode makeCall() initiiert:<br />
Listing 4.20: Methode makeCall()<br />
1 p r i v a t e void makeCall ( ) {<br />
2 Uri u r i = Uri . p a r s e ( da . mService . get ( 4 ) ) ;<br />
3 I n t e n t i n t e n t = new I n t e n t ( I n t e n t .ACTION CALL, u r i ) ;<br />
4 s t a r t A c t i v i t y ( i n t e n t ) ;<br />
5 }<br />
In Zeile 2 wird zunächst ein URI (Uniform Resource Identifier) mit der zuvor formatierten<br />
Telefonnummer (siehe 4.3.3.1) erstellt. Anschließend wird ein impliziter Intent<br />
mit den Parametern ” ACTION CALL“ (um einen Anruf zu initiieren) und dem URI<br />
erzeugt. Da durch den Intent kein Ergebnis erwartet wird, wird dieser zuletzt noch mit<br />
startActivity(intent) abgeschickt, um die Activity der Phone App zu starten und<br />
den Anruf zu initiieren. Ist der Anruf beendet, schließt sich die Phone Activity wieder<br />
und die zuletzt auf dem ” Back Stack“ des Activity Managers gespeicherte CodeScanner<br />
Activity wird reaktiviert.<br />
4.4 WEITBLICK QR Code-Generator<br />
Der Nutzer hat gemäß des Usecases aus der Aufgabenstellung aus Kapitel 2 die Möglichkeit<br />
den Dienst durch Scannen eines in einer Fernsehsendung eingeblendeten Barcodes<br />
mit seinem Smartphone zu buchen. Für das Produktionsstudio des Fernsehsenders<br />
sollte es möglichst einfach sein, einen solchen QR Code komfortabel in das Fernsehbild<br />
einblenden zu können. Demnach besteht Bedarf an einer einfachen Möglichkeit den<br />
QR Code mit einem entsprechenden Inhalt zu erzeugen. Die ZXing Bildverarbeitungsbibliothek<br />
stellt dazu unter [ZXi11c] einen QR Code Generator mit einem RESTful<br />
Interface (siehe 4.2.2) bereit, womit QR Codes dynamisch erzeugt werden können.<br />
Durch Senden einer HTTP GET Nachricht mit einem API Befehl wird ein QR Code<br />
generiert und eine jpg-Bilddatei zurückgeliefert.<br />
Zur einfachen Erzeugung eines QR Codes mit dem Inhalt ” WEITBLICK“ muss das<br />
REST Interface wie folgt aufgerufen werden:<br />
http://chart.apis.google.com/chart?cht=qr&chs=545x545&chl=WEITBLICK<br />
Damit ist <strong>für</strong> ein System, das den QR Code in das Fernsehbild einblendet, eine leichte<br />
Implementierungsmöglichkeit geschaffen. Als Hilfsmittel wird dabei ein zusätzliches<br />
Programm namens wget verwendet. Dies ist ein plattformunabhängiger HTTP-Client,<br />
mit welchem HTTP Nachrichten verschickt werden können.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
4 Praktische Umsetzung 53<br />
Eine vereinfachte Generierung des QR Codes wird durch Aufruf einer Batchdatei<br />
gencode.bat in der Kommandozeile erreicht:<br />
gencode WEITBLICK qrcode.jpg<br />
Dem Batchskript werden zwei Parameter übergeben. Der erste Parameter steht <strong>für</strong><br />
den Inhalt des Codes, welcher innerhalb der Batchdatei in die oben genannte URL<br />
als Variable eingesetzt wird. Für das WEITBLICK-Projekt müsste hier der unter Abschnitt<br />
4.2.1.1 diskutierte Inhalt eingegeben werden. Der zweite Parameter bezeichnet<br />
die Zieldatei, in der das JPG-Bild (die Antwort des ZXing REST Interface) gespeichert<br />
wird. Die damit erzeugte Bilddatei kann das Compositingsystem in der Fernseh-<br />
Postproduktion weiter verarbeiten und in den Videostream einbetten.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
5 Zusammenfassung und Ausblick 54<br />
5 Zusammenfassung und Ausblick<br />
Die Aufgabe der Arbeit bestand darin, mittels eines Smartphones einen Rückkanal <strong>für</strong><br />
den herkömmlichen Fernsehrundfunk zu bilden. Ausgehend vom WEITBLICK-Projekt<br />
sollen dabei, im Hinblick auf ein Assistenzsystem <strong>für</strong> Senioren, Dienstleistungen (Pflege,<br />
soziale Kontakte, Hobby, Wellness) vermittelt werden. Gemäß der Aufgabenstellung<br />
ergaben sich folgende Teilaufgaben:<br />
1. Recherche möglicher Darstellungsformen <strong>für</strong> die optische Marke<br />
2. Codierung von Informationen mittels der optischen Marke<br />
3. Realisierung einer Anwendung auf dem Smartphone zur Erkennung der optischen<br />
Marke<br />
4. Übermittlung der Buchungsinformation an einen Server<br />
5. Anruf einer mitcodierten Telefonnummer<br />
In Kapitel 3 wurden die allgemeinen Merkmale einer optischen Marke erläutert und<br />
darauf basierend eine Anforderungsanalyse an den zu wählenden Code gestellt. Nach<br />
einer Erläuterung der nach den Anforderungen in Frage kommenden Typen an Codes,<br />
wurden diese am Ende des Kapitels praktisch miteinander verglichen. Dabei wurde ein<br />
Usecase-nahes Szenario erstellt und der bestgeeignetste Code in einer Testreihe unter<br />
realen Bedingungen ermittelt. Die Wahl fiel letztendlich auf den QR Code.<br />
Im zweiten Teil wurde die praktische Umsetzung der Aufgabenstellung behandelt.<br />
Dazu war es nötig die an das Dienstbuchungssystem gestellten Anforderungen zu formulieren,<br />
um anschließend dessen Struktur sowohl auf der Seite des Clients als auch<br />
auf der des Servers, zu erläutern. Der Android Client fotografiert den auf dem Fernsehgerät<br />
abgebildeten QR Code ab und fordert die vollständigen Dienstinformationen<br />
anhand einer in den Code codierten ID von einem SQL Server über das Internet an.<br />
Ist keine Internetverbindung vorhanden, so verwendet das Smartphone nur die direkt<br />
in den QR Code codierten Informationen. Dies betrifft die Anzeige des Diensttitels sowie<br />
die Möglichkeit sich über die codierte Telefonnummer mit einem Ansprechpartner<br />
verbinden zu lassen.<br />
Des Weiteren wurde im zweiten Teil auf die Entwicklung der Android CodeScanner<br />
App eingegangen. Diese beschreibt zunächst die zum Verständnis der Programmstruktur<br />
notwendigen Grundlagen des Android Betriebssystems im Allgemeinen und geht<br />
darauf folgend auf die CodeScanner App ein. Beschrieben wird sowohl das User Interface<br />
sowie die zur Erfüllung der Aufgaben nötigen Methoden. Zur vollständigen<br />
Einsicht des Quellcodes sei hierbei auf den Anhang verwiesen. Zuletzt wird noch die<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
5 Zusammenfassung und Ausblick 55<br />
Möglichkeit erläutert, einen QR Code möglichst einfach und plattformunabhängig erstellen<br />
und in eine Anwendung implementieren zu können.<br />
Zum Ausblick dieser Technologie lässt sich Folgendes sagen: Vor ein paar Jahren waren<br />
Smartphones noch kaum verbreitet. Das Marktforschungsunternehmens IDC prognostiziert<br />
<strong>für</strong> die nächsten Jahre einen anhaltenden Smartphone-Boom. Der Smartphone-Marktwachstum<br />
soll demnach im Jahre 2011 50% betragen [hei11]. Laut einer<br />
Studie des Martkforschungsunternehmens comScore besitzen Smartphones in Deutschland<br />
bereits einen Marktanteil von über 23% [com11].<br />
Bezüglich des WEITBLICK-Projekts ist allerdings zu gestehen, dass die Zielgruppe<br />
der Senioren noch weniger vom Smartphone-Boom betroffen ist. Eine repräsentative<br />
Umfrage des Forsa-Instituts im Auftrag des Bundesverband Informationswirtschaft,<br />
Telekommunikation und neue Medien e.V. (BITKOM) im Oktober 2010 zeigt, dass der<br />
Anteil der Smartphone-Besitzer mit zunehmenden Alter rapide abnimmt. Die Quote<br />
bei den über 60-Jährigen (entsprechend der Zielgruppe des WEITBLICK-Projekts) beträgt<br />
nur 7% [Bun11]. Es ist aber gleichzeitig davon auszugehen, dass dieser Rückstand<br />
an den verwendeten Smartphones in dieser Zielgruppe generationsbedingt schwinden<br />
wird. Bei den 30- bis 44-Jährigen hat immerhin schon jeder vierte ein Smartphone<br />
[Bun11]. Diese Generation wird im Laufe der Zeit in die Zielgruppe des WEITBLICK-<br />
Projekts hineinwachsen. Zudem wäre es vorstellbar den Einsatzzweck und die Möglichkeiten<br />
des Assistenzsystems in der Zielgruppe zu bewerben, um so die Senioren zum<br />
Kauf eines Smartphones zu bewegen. Abgesehen vom WEITBLICK-Projekt könnte<br />
das Dienstbuchungssystem auch problemlos auf andere Zielgruppen erweitert werden.<br />
Eine Umsetzung des Dienstbuchungssystem wäre bei einer Markteinführung technisch<br />
sehr schnell implementierbar. Nachdem die Serverstruktur geschaffen wurde,<br />
könnte die CodeScanner App in den Android Market Store gestellt werden. Technisch<br />
gesehen wäre das Dienstbuchungssystem damit einsatzbereit. Der SQL Dienstserver<br />
würde durch die Dienstanbieter verwaltet werden und die auf der SQL Dienstdatenbank<br />
basierenden QR Codes könnten in Fernsehsendungen ausgestrahlt werden.<br />
Letztlich gilt es noch zu erwähnen, dass dieses Dienstbuchungssystem, das auf einer<br />
CodeScanner App beruht, in Konkurrenz mit einem Dienstbuchungssystem, das<br />
eine Technologie wie bspw. das Hybrid Broadcast Broadband TV (HbbTV) verwendet,<br />
steht. HbbTV ist eine moderne Basistechnologie <strong>für</strong> Unterhaltungselektronik, welche<br />
Fernsehangebote mit Mehrwertdiensten aus dem Internet verbindet. Über eine Internetverbindung<br />
kann der Nutzer während einer Fernsehsendung Informationen abrufen,<br />
die er in einem speziell angepassten HTML, dem sogenannten CE-HTML (Consumer-<br />
Electronics-HTML), auf dem Fernsehgerät angezeigt bekommt. Voraussetzung hier<strong>für</strong><br />
ist allerdings, dass der Nutzer auch einen Fernseher besitzt, der <strong>für</strong> die HbbTV-<br />
Technologie ausgelegt ist. Fraglich ist zudem, wie groß der technische Aufwand beim<br />
HbbTV wäre, um ein solches Dienstbuchungssystem zu entwickeln. Ein weiterer Vorteil<br />
der WEITBLICK Lösung ist die Nutzungsmöglichkeit bei analogem Fernsehen, die bei<br />
hybriden Fernsehtechnologien wie dem HbbTV nicht gegeben wäre.<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Anhang<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach<br />
56
A Quellcodes 57<br />
A Quellcodes<br />
A.1 mySQL-Server und PHP-Server als Dienstserver<br />
Listing A.1: weitblick services.php<br />
1 <br />
A.2 Android Manifest<br />
Listing A.2: /AndroidManifest.xml<br />
1 <br />
2 <br />
6 <br />
7 <br />
8 <br />
9 <br />
10 <br />
11 <br />
13 <br />
14 <br />
15 <br />
16 <br />
17 <br />
18 <br />
19 <br />
A.3 Layout<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 58<br />
Listing A.3: /res/layout/codescanner.xml<br />
1 <br />
2 <br />
7 <br />
8 <br />
14 <br />
19 <br />
23 <br />
24<br />
25 <br />
31 <br />
32 <br />
33<br />
34 <br />
35 <br />
41 <br />
46 <br />
51 <br />
55 <br />
56 <br />
63 <br />
71 <br />
77 <br />
83 <br />
89 <br />
90 <br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 59<br />
91 <br />
Listing A.4: /res/layout/userpw dialog.xml<br />
1 <br />
7 <br />
11 <br />
17 <br />
22 <br />
23 <br />
27 <br />
33 <br />
39 <br />
40 <br />
45 <br />
Listing A.5: /res/menu/optionsmenu.xml<br />
1 <br />
2 <br />
3 <br />
6 <br />
9 <br />
A.4 Strings<br />
Listing A.6: /res/values/strings.xml<br />
1 <br />
2 <br />
3 t r u e<br />
4 h t t p : //www. k r e a t i v f l o w . de / w e i t b l i c k s e r v i c e s . php<br />
5 h t t p s : // g a g a r i n . e−t e c h n i k . tu−ilmenau . d e : 8 4 4 3<br />
6 l o g i n s t o r e . pw<br />
7 WEITBLICK − CodeScanner !<br />
8 Keine I n t e r n e t v e r b i n d u n g vorhanden ! \ n D i e n s t kann nur mit b e s t e h e n d e r<br />
I n t e r n e t v e r b i n d u n g d i r e k t gebucht werden . Es b e s t e h t d i e M ö g l i c h k e i t s i c h über den Button \<br />
" ü b e r T e l e f o n b u c h e n \ " d i r e k t mit einem A n s p r e c h p a r t n e r v e r b i n d e n zu l a s s e n . \ nZur d i r e k t e n<br />
Buchung b i t t e I n t e r n e t v e r b i n d u n g ü b e r p r ü f e n !<br />
9 Die g e s p e i c h e r t e n Login−Daten wurden g e l ö s c h t !<br />
10<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 60<br />
11 <br />
12 Kein g ü l t i g e r Code<br />
13 Es wurde e i n u n g ü l t i g e r Code g e s c a n n t . F a l l s e s s i c h um e i n e n g ü l t i g e n Code g e h a n d e l t<br />
hat , scannen S i e d i e s e n b i t t e e r n e u t .<br />
14 <br />
15 <br />
16 WEITBLICK − CodeScanner APP<br />
17 e i n e B a c h e l o r a r b e i t von F l o r i a n Schlembach am F a c h g e b i e t Kommunikationsnetze an der<br />
<strong>TU</strong> <strong>Ilmenau</strong> f ü r das P r o j e k t WEITBLICK .<br />
18 OK<br />
19 <br />
20 I n f o zur APP<br />
21 Login l ö s c h e n<br />
22 <br />
23 Barcode Scanner APP<br />
24 Um d i e Scan−Funktion der WEITBLICK APP zu nutzen i s t d i e e x t e r n e Barcode<br />
Scanner APP notwendig . Möchten S i e d i e s e j e t z t a u t o m a t i s c h i n s t a l l i e r e n ?<br />
25 I n s t a l l i e r e n<br />
26 Abbrechen<br />
27 <br />
28 <br />
29 D i e n s t buchen<br />
30 B i t t e Logindaten e i n g e b e n :<br />
31 Buchen<br />
32 Abbrechen<br />
33 <br />
34 <br />
35 D i e n s t gebucht<br />
36 Termin e i n t r a g e n<br />
37 Nicht e i n t r a g e n<br />
38 FEHLER b e i Buchung des D i e n s t e s ! B i t t e e r n e u t v e r s u c h e n !<br />
39 <br />
40 <br />
41 Lade D i e n s t<br />
42 B i t t e warten . . . <br />
43 <br />
44 <br />
45 Buche D i e n s t<br />
46 B i t t e warten . . . <br />
47 <br />
48 <br />
A.5 Datenzugriffsklasse DataAccess()<br />
Listing A.7: /src/com.weitblick.codescanner/DataAccess.java<br />
1 package com . w e i t b l i c k . c o d e s c a n n e r ;<br />
2<br />
3 import j a v a . i o . B u f f e r e d R e a d e r ;<br />
4 import j a v a . i o . DataInputStream ;<br />
5 import j a v a . i o . F i l e I n p u t S t r e a m ;<br />
6 import j a v a . i o . FileNotFoundException ;<br />
7 import j a v a . i o . FileOutputStream ;<br />
8 import j a v a . i o . IOException ;<br />
9 import j a v a . i o . InputStream ;<br />
10 import j a v a . i o . InputStreamReader ;<br />
11 import j a v a . s e c u r i t y . KeyStore ;<br />
12 import j a v a . u t i l . A r r a y L i s t ;<br />
13 import j a v a . u t i l . L i s t ;<br />
14 import j a v a . u t i l . S t r i n g T o k e n i z e r ;<br />
15<br />
16 import org . apache . http . Header ;<br />
17 import org . apache . http . HttpEntity ;<br />
18 import org . apache . http . HttpResponse ;<br />
19 import org . apache . http . NameValuePair ;<br />
20 import org . apache . http . S t a t u s L i n e ;<br />
21 import org . apache . http . c l i e n t . H t t p C l i e n t ;<br />
22 import org . apache . http . c l i e n t . e n t i t y . UrlEncodedFormEntity ;<br />
23 import org . apache . http . c l i e n t . methods . HttpPost ;<br />
24 import org . apache . http . conn . scheme . Scheme ;<br />
25 import org . apache . http . conn . s s l . SSLSocketFactory ;<br />
26 import org . apache . http . e n t i t y . S t r i n g E n t i t y ;<br />
27 import org . apache . http . impl . c l i e n t . D e f a u l t H t t p C l i e n t ;<br />
28 import org . apache . http . message . BasicNameValuePair ;<br />
29 import org . j s o n . JSONArray ;<br />
30 import org . j s o n . JSONException ;<br />
31 import org . j s o n . JSONObject ;<br />
32<br />
33 import a n d r o i d . c o n t e n t . Context ;<br />
34 import a n d r o i d . net . ConnectivityManager ;<br />
35 import a n d r o i d . net . NetworkInfo ;<br />
36 import a n d r o i d . os . Handler ;<br />
37 import a n d r o i d . u t i l . Log ;<br />
38 import a n d r o i d . widget . Toast ;<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 61<br />
39<br />
40 p u b l i c c l a s s DataAccess {<br />
41 //member v a r i a b l e s<br />
42 I n t e g e r mId ;<br />
43 S t r i n g mTitle ;<br />
44 S t r i n g mPhonenr ;<br />
45<br />
46 p r i v a t e Context mContext ;<br />
47 S t a t u s mStatus ;<br />
48<br />
49 A r r a y L i s t mService = new A r r a y L i s t (6) ;<br />
50 A r r a y L i s t mLogin = new A r r a y L i s t (2) ;<br />
51<br />
52 // Handler manages the i n v o c a t i o n o f the r u n n a b l e s a f t e r f i n i s h i n g worker−t h r e a d s<br />
53 f i n a l Handler mHandler = new Handler ( ) ;<br />
54<br />
55 //STA<strong>TU</strong>S VARIABLES<br />
56 b o o l e a n s e n t ;<br />
57<br />
58 // S t a t u s o f r e q u e s t e d s e r v i c e<br />
59 p u b l i c enum S t a t u s {<br />
60 INVALID ,<br />
61 VALID,<br />
62 VALID PROCESSING ,<br />
63 VALID INET ,<br />
64 VALID NO INET ,<br />
65 }<br />
66 // Message type f o r showBookedDialog method<br />
67 p u b l i c s t a t i c enum showProgressDlgMsg {<br />
68 OFF,<br />
69 LOADSERVICE,<br />
70 BOOKSERVICE<br />
71 }<br />
72<br />
73 /∗∗<br />
74 ∗ S e t s c o n t e x t o f CodeScanner A c t i v i t y t o the c l a s s ’ c o n t e x t v a r i a b l e and p a r s e s<br />
s c a n r e s u l t s<br />
75 ∗<br />
76 ∗ @param c o n t e x t a Context which i s p a s s e d by the CodeScanner A c t i v i t y<br />
77 ∗ @param s c a n r e s u l t a S t r i n g o f the p a r s e d s c a n r e s u l t s<br />
78 ∗/<br />
79 DataAccess ( Context c o n t e x t , S t r i n g s c a n r e s u l t ) {<br />
80 mContext = c o n t e x t ;<br />
81 p a r s e S c a n r e s u l t ( s c a n r e s u l t ) ;<br />
82 }<br />
83<br />
84 //PUBLIC METHODS<br />
85 /∗∗<br />
86 ∗ S e t s and c o n t r o l s the s t a t u s o f the r e q u e s t e d s e r v i c e<br />
87 ∗ This Method i s invoked by the i n i t B o o k i n g L a y o u t ( )−method o f the CodeScanner A c t i v i t y −<br />
c l a s s<br />
88 ∗ 1 . A f t e r having s c a n r e s u l t s parsed , s t a t u s o f mStatus i s e i t h e r VALID or INVALID<br />
89 ∗ 2 . I f VALID i n t e r n e t c o n n e c t i o n s i s checked , an a p p r o p r i a t e S t a t u s i s s e t<br />
90 ∗ 3 . I f i n t e r n e t c o n n e c t i o n i s a v a i l a b l e , s t a r t r e q u e s t i n g s e r v i c e i n a s e p a r a t e worker−<br />
t h r e a d<br />
91 ∗ 4 . I f no i n t e r n e t c o n n e c t i o n i s a v a i l a b l e , f i l l mService with empty data<br />
92 ∗/<br />
93 p u b l i c v o i d s e t S t a t u s ( ) {<br />
94 s w i t c h ( mStatus ) {<br />
95 c a s e INVALID :<br />
96 break ;<br />
97 c a s e VALID :<br />
98 i f ( c h e c k I n e t ( mContext ) ) mStatus=S t a t u s . VALID PROCESSING ;<br />
99 e l s e mStatus=S t a t u s . VALID NO INET ;<br />
100 s e t S t a t u s ( ) ;<br />
101 break ;<br />
102 c a s e VALID PROCESSING :<br />
103 r e q u e s t S e r v i c e T h r e a d ( ) ;<br />
104 break ;<br />
105 c a s e VALID INET :<br />
106 break ;<br />
107 c a s e VALID NO INET :<br />
108 s e t O f f l i n e S e r v i c e ( ) ;<br />
109 break ;<br />
110 }<br />
111 }<br />
112<br />
113 /∗∗<br />
114 ∗ F e t c h e s UserPw D i a l o g<br />
115 ∗ 1 . Reads l o g i n d a t a from f i l e t o mLogin<br />
116 ∗ 2 . I f t h e r e i s no l o g i n −f i l e , mLogin i s empty and LoginDlg pops up<br />
117 ∗ 3 . I f l o g i n d a t a i s saved , s t a r t s s e n d i n g the f o r m a t t e d message ( which c o n s i s t s o f data<br />
o f shown s e r v i c e )<br />
118 ∗/<br />
119 p u b l i c v o i d loginAndSend ( ) {<br />
120 mLogin = readLoginFromFile ( ) ;<br />
121 // i f t h e r e i s no l o g i n saved y e t<br />
122 i f ( mLogin . isEmpty ( ) ) ( ( CodeScanner ) mContext ) . showLoginDlg ( ) ;<br />
123 e l s e sendMessageThread ( formatMessage ( ) ) ;<br />
124 }<br />
125<br />
126 /∗∗<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 62<br />
127 ∗ Sends HTTPPost−Message to UMS S e r v e r<br />
128 ∗ 1 . Obtains UMSServer URL from s t r i n g r e s o u r c e<br />
129 ∗ 2 . C r e a t e s K e y s t o r e out o f raw r e s o u r c e f i l e w e i t b l i c k . bks ( Bouncy C a s t l e k e y s t o r e f i l e )<br />
130 ∗ 3 . C r e a t e s Apache H t t p C l i e n t and HttpPost<br />
131 ∗ 4 . Sends and r e c e i v e s p o s t<br />
132 ∗ 5 . Reads h e a d e r s and c h e c k s whether message was s e n t s u c c e s s f u l l y<br />
133 ∗<br />
134 ∗ @param message a S t r i n g o f the message to send to the UMS S e r v e r<br />
135 ∗/<br />
136 p u b l i c v o i d sendMessage ( S t r i n g message ) {<br />
137 s e n t = f a l s e ;<br />
138 f i n a l S t r i n g UMSSERVER = mContext . g e t R e s o u r c e s ( ) . g e t S t r i n g (R. s t r i n g .UMSSERVER) ;<br />
139<br />
140 t r y {<br />
141 // C r e a t e s k e y s t o r e<br />
142 InputStream i s = mContext . g e t R e s o u r c e s ( ) . openRawResource (R. raw . w e i t b l i c k ) ;<br />
143 KeyStore k e y s t o r e = KeyStore . g e t I n s t a n c e ( " B K S " ) ;<br />
144 k e y s t o r e . l o a d ( i s , " w 3 1 t b l 1 c k " . toCharArray ( ) ) ;<br />
145<br />
146 // C r e a t e s SSL c o n n e c t i o n<br />
147 SSLSocketFactory s o c k e t F a c t o r y = new org . apache . http . conn . s s l .<br />
SSLSocketFactory ( k e y s t o r e ) ;<br />
148 s o c k e t F a c t o r y . s e t H o s t n a m e V e r i f i e r ( org . apache . http . conn . s s l . SSLSocketFactory<br />
. STRICT HOSTNAME VERIFIER) ;<br />
149<br />
150 f i n a l Scheme h t t p s = new Scheme ( " h t t p s " , s o c k e t F a c t o r y , 8443) ;<br />
151<br />
152 H t t p C l i e n t c l i e n t = new D e f a u l t H t t p C l i e n t ( ) ;<br />
153 c l i e n t . getConnectionManager ( ) . g e t S c h e m e R e g i s t r y ( ) . r e g i s t e r ( h t t p s ) ;<br />
154 HttpPost p o s t = new HttpPost (UMSSERVER+" / i m q u m s / s i m p l e ? s e r v i c e = s e n d & d e s t i n a t i o n =<br />
D V B _ R u e c k k a n a l & u s e r = "+mLogin . g e t ( 0 )+" & p a s s w o r d = "+mLogin . g e t ( 1 ) ) ;<br />
155 p o s t . addHeader ( " C o n t e n t - T y p e " , " t e x t / h t m l ; c h a r s e t = utf - 8 " ) ;<br />
156 HttpEntity e n t i t y = new S t r i n g E n t i t y ( message , " UTF - 8 " ) ;<br />
157 p o s t . s e t E n t i t y ( e n t i t y ) ;<br />
158 HttpResponse r e s p o n s e = c l i e n t . e x e c u t e ( p o s t ) ;<br />
159<br />
160 S t a t u s L i n e s t a t u s = r e s p o n s e . g e t S t a t u s L i n e ( ) ;<br />
161 Header u m s s e r v i c e = r e s p o n s e . g e t F i r s t H e a d e r ( " u m s . s e r v i c e " ) ;<br />
162 Header umsstatus = r e s p o n s e . g e t F i r s t H e a d e r ( " u m s . s t a t u s " ) ;<br />
163 b o o l e a n i s s t a t u s o k = s t a t u s . t o S t r i n g ( ) . c o n t a i n s ( " 2 0 0 " ) ;<br />
164 b o o l e a n i s r e p l y o k = u m s s e r v i c e . g e t V a l u e ( ) . t o S t r i n g ( ) . e q u a l s ( " s e n d _ r e p l y " ) ;<br />
165 b o o l e a n i s u m s s t a t u s o k = umsstatus . g e t V a l u e ( ) . t o S t r i n g ( ) . e q u a l s ( " 2 0 0 " ) ;<br />
166<br />
167<br />
168 i f ( i s s t a t u s o k && i s r e p l y o k && i s u m s s t a t u s o k ) s e n t = t r u e ;<br />
169 } c a t c h ( Exception e ) {<br />
170 Log . e ( " h t t p p o s t " , " E r r o r i n h t t p s c o n n e c t i o n : "+e . t o S t r i n g ( ) ) ;<br />
171 }<br />
172 }<br />
173<br />
174 /∗∗<br />
175 ∗ S t a r t s s e p a r a t e worker t h r e a d to p r e s e r v e hanging UI<br />
176 ∗ 1 . Shows P r o g r e s s D i a l o g<br />
177 ∗ 2 . S t a r t s worker−t h r e a d<br />
178 ∗ 3 . Sends the f o r m a t t e d message<br />
179 ∗ 4 . Shows booking−c o n f i r m a t i o n −d i a l o g<br />
180 ∗<br />
181 ∗ @param message a S t r i n g o f the message to send to the UMS S e r v e r<br />
182 ∗/<br />
183 p u b l i c v o i d sendMessageThread ( S t r i n g message ) {<br />
184 ( ( CodeScanner ) mContext ) . s h o w P r o g r e s s D i a l o g ( showProgressDlgMsg .BOOKSERVICE) ;<br />
185 // s t a r t a−worker−t h r e a d w<br />
186 Thread t = new Thread ( ) {<br />
187 p u b l i c v o i d run ( ) {<br />
188 sendMessage ( formatMessage ( ) ) ;<br />
189 mHandler . p o s t ( mShowBookedDialog ) ;<br />
190 }<br />
191 } ;<br />
192 t . s t a r t ( ) ;<br />
193 }<br />
194<br />
195 /∗∗<br />
196 ∗ Executing r u n n a b l e f o r c a l l b a c k method which i n v o k e s the updating−method o f Booking−<br />
Layout<br />
197 ∗ 1 . S w i t c h e s o f f P r o g r e s s D i a l o g<br />
198 ∗ 2 . Shows s u c c e s s f u l booking−c o n f i r m a t i o n −d i a l o g<br />
199 ∗/<br />
200 p u b l i c f i n a l Runnable mShowBookedDialog = new Runnable ( ) {<br />
201 p u b l i c v o i d run ( ) {<br />
202 ( ( CodeScanner ) mContext ) . s h o w P r o g r e s s D i a l o g ( showProgressDlgMsg .OFF) ;<br />
203 ( ( CodeScanner ) mContext ) . showBookedDlg ( s e n t ) ;<br />
204 }<br />
205 } ;<br />
206<br />
207 /∗∗<br />
208 ∗ Formats the message based on the shown s e r v i c e .<br />
209 ∗ Contains data : Username , S e r v i c e I D , S e r v i c e T i t l e , S e r v i c e D a t e , SendConfMail ( b o o l e a n s e t<br />
i n s t r i n g r e s o u r c e )<br />
210 ∗<br />
211 ∗ @return the f o r m a t t e d message<br />
212 ∗/<br />
213 p u b l i c S t r i n g formatMessage ( ) {<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 63<br />
214 // i f c o n f i r m m a i l i s s e t to true , a booking c o n f i r m a t i o n i s s e n t by mail through<br />
email−gateway<br />
215 S t r i n g c o n f i r m m a i l = mContext . g e t R e s o u r c e s ( ) . g e t S t r i n g (R. s t r i n g . c o n f i r m M a i l ) .<br />
t o S t r i n g ( ) ;<br />
216 S t r i n g B u f f e r m = new S t r i n g B u f f e r ( ) ;<br />
217 m. append ( " U s e r : "+mLogin . g e t ( 0 )+" ; " ) ;<br />
218 m. append ( " S e r v i c e I D : "+mId+" ; " ) ;<br />
219 m. append ( " S e r v i c e T i t l e : "+mService . g e t ( 0 )+" ; " ) ;<br />
220 m. append ( " S e r v i c e D a t e : "+mService . g e t ( 2 )+" ; " ) ;<br />
221 m. append ( " S e n d C o n f M a i l : "+c o n f i r m m a i l ) ;<br />
222 r e t u r n m. t o S t r i n g ( ) ;<br />
223 }<br />
224<br />
225 /∗∗<br />
226 ∗ Checks whether t h e r e i s l o g i n d a t a saved<br />
227 ∗<br />
228 ∗ @return the b o o l e a n v a l u e i f t h e r e i s l o g i n d a t a saved<br />
229 ∗/<br />
230 p u b l i c b o o l e a n i s L o g i n S a v e d ( ) {<br />
231 i f ( ! readLoginFromFile ( ) . isEmpty ( ) ) r e t u r n t r u e ;<br />
232 e l s e r e t u r n f a l s e ;<br />
233 }<br />
234<br />
235 /∗∗<br />
236 ∗ Writes l o g i n d a t a to f i l e on I n t e r n a l S t o r a g e<br />
237 ∗<br />
238 ∗ @return the r e s u l t o f the f i l e w r i t i n g o p e r a t i o n<br />
239 ∗/<br />
240 p u b l i c b o o l e a n w r i t e L o g i n T o F i l e ( ) {<br />
241 b o o l e a n w r i t t e n = t r u e ;<br />
242 t r y {<br />
243 S t r i n g userpw=mLogin . g e t ( 0 )+" : "+mLogin . g e t ( 1 ) ;<br />
244 S t r i n g LOGINSTORE=mContext . g e t R e s o u r c e s ( ) . g e t S t r i n g (R. s t r i n g .LOGINSTORE) ;<br />
245 FileOutputStream f o s = mContext . openFileOutput (LOGINSTORE, 0 ) ;<br />
246 f o s . w r i t e ( userpw . g e t B y t e s ( ) ) ;<br />
247 f o s . c l o s e ( ) ;<br />
248 }<br />
249 c a t c h ( FileNotFoundException e ) {<br />
250 Log . e ( " l o g i n s t o r e " , " e r r o r w r i t i n g l o g i n s t o r e f i l e : "+e . t o S t r i n g ( ) ) ;<br />
251 w r i t t e n = f a l s e ;<br />
252 }<br />
253 c a t c h ( IOException e ) {<br />
254 Log . e ( " l o g i n s t o r e " , " e r r o r w r i t i n g l o g i n s t o r e f i l e : "+e . t o S t r i n g ( ) ) ;<br />
255 w r i t t e n = f a l s e ;<br />
256 }<br />
257 r e t u r n w r i t t e n ;<br />
258 }<br />
259<br />
260 /∗∗<br />
261 ∗ D e l e t e s the l o g i n d a t a f i l e on I n t e r n a l S t o r a g e<br />
262 ∗/<br />
263 p u b l i c v o i d d e l e t e L o g i n F i l e ( ) {<br />
264 f i n a l S t r i n g LOGINSTORE = mContext . g e t R e s o u r c e s ( ) . g e t S t r i n g (R. s t r i n g .LOGINSTORE) ;<br />
265 S t r i n g m s g l o g i n d e l e t e d = mContext . g e t R e s o u r c e s ( ) . g e t S t r i n g (R. s t r i n g . l o g i n d e l e t e d ) ;<br />
266<br />
267 mLogin . c l e a r ( ) ;<br />
268 mContext . d e l e t e F i l e (LOGINSTORE) ;<br />
269 // Shows d e l e t e message t o a s t even i f t h e r e i s no l o g i n saved<br />
270 Toast . makeText ( mContext , m s g l o g i n d e l e t e d , 3000) . show ( ) ;<br />
271 }<br />
272<br />
273 //PRIVATE METHODS<br />
274 /∗∗<br />
275 ∗ P a r s e s s c a n r e s u l t<br />
276 ∗ 1 . S p l i t s s c a n r e s u l t S t r i n g i n t h r e e p a r t s<br />
277 ∗ 2 . Third Part i s s p l i t a g a i n i n t o t h r e e p a r t s<br />
278 ∗ 3 . I f f i r s t two p o i n t s succeeded , the QR Code i s v a l i d<br />
279 ∗ 4 . S e t s mStatus i n dependence o f p o i n t 3 to VALID o r INVALID<br />
280 ∗<br />
281 ∗ @param s c a n r e s u l t a S t r i n g o f the s c a n r e s u l t o f the e x t e r n a l Barcode Scanner App<br />
g i v e n by the CodeScanner A c t i v i t y<br />
282 ∗/<br />
283 p r i v a t e v o i d p a r s e S c a n r e s u l t ( S t r i n g s c a n r e s u l t ) {<br />
284 b o o l e a n r e s u l t = t r u e ;<br />
285 S t r i n g [ ] s p l i t p h o n e n r = n u l l ;<br />
286<br />
287 S t r i n g [ ] s p l i t r e s u l t = s c a n r e s u l t . s p l i t ( " # # " ) ;<br />
288 i f ( s p l i t r e s u l t . l e n g t h ==3) s p l i t p h o n e n r = s p l i t r e s u l t [ 2 ] . s p l i t ( " - " ) ;<br />
289<br />
290 i f ( s p l i t r e s u l t . l e n g t h==3 && s p l i t p h o n e n r . l e n g t h ==3) {<br />
291 mId=new I n t e g e r ( s p l i t r e s u l t [ 0 ] ) ;<br />
292 mTitle=s p l i t r e s u l t [ 1 ] ;<br />
293 mPhonenr=" t e l : ( "+s p l i t p h o n e n r [ 0 ] + " ) "+s p l i t p h o n e n r [ 1 ] + " "+s p l i t p h o n e n r [ 2 ] ;<br />
294 }<br />
295 e l s e r e s u l t = f a l s e ;<br />
296<br />
297 i f ( r e s u l t ) mStatus=S t a t u s . VALID ;<br />
298 e l s e mStatus=S t a t u s . INVALID ;<br />
299 }<br />
300<br />
301 /∗∗<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 64<br />
302 ∗ Formats the g i v e n phonenumber i n t o the format s p e c i f i e d i n RFC 3966 ( IETF ) : t e l : ( xx ) xxxx<br />
xxxx<br />
303 ∗<br />
304 ∗ @param nr a S t r i n g with the phonenumber<br />
305 ∗ @return the f o r m a t t e d phonenumber<br />
306 ∗/<br />
307 p r i v a t e S t r i n g formatNumber ( S t r i n g nr ) {<br />
308 S t r i n g T o k e n i z e r s t = new S t r i n g T o k e n i z e r ( nr , " - " ) ;<br />
309 nr = " t e l : ( "+s t . nextToken ( )+" ) "+s t . nextToken ( )+" "+s t . nextToken ( ) ;<br />
310 r e t u r n nr ;<br />
311 }<br />
312<br />
313 /∗∗<br />
314 ∗ Checks whether i n t e r n e t c o n n e c t i o n i s a v a i l a b l e<br />
315 ∗<br />
316 ∗ @param c o n t e x t a Context from the CodeScanner A c t i v i t y to check the i n t e r n e t c o n n e c t i o n<br />
from t h e r e<br />
317 ∗ @return the s t a t e o f the i n t e r n e t c o n n e c t i o n<br />
318 ∗/<br />
319 p r i v a t e b o o l e a n c h e c k I n e t ( Context c o n t e x t ) {<br />
320 ConnectivityManager connectmgr = ( ConnectivityManager ) c o n t e x t . g e t S y s t e m S e r v i c e ( Context .<br />
CONNECTIVITY SERVICE) ;<br />
321 NetworkInfo a c t i v e N e t w o r k I n f o = connectmgr . g e t A c t i v e N e t w o r k I n f o ( ) ;<br />
322 r e t u r n a c t i v e N e t w o r k I n f o != n u l l ;<br />
323 }<br />
324<br />
325 /∗∗<br />
326 ∗ Executing Runnable f o r c a l l b a c k method which i n v o k e s the updating−method o f<br />
BookingLayout<br />
327 ∗ 1 . S w i t c h e s o f f P r o g r e s s D i a l o g<br />
328 ∗ 2 . I n i t i a l i z e s updating−method o f BookingLayout<br />
329 ∗/<br />
330 f i n a l Runnable mUpdateBookingLayout = new Runnable ( ) {<br />
331 p u b l i c v o i d run ( ) {<br />
332 mStatus=S t a t u s . VALID INET ;<br />
333 ( ( CodeScanner ) mContext ) . s h o w P r o g r e s s D i a l o g ( showProgressDlgMsg .OFF) ;<br />
334 ( ( CodeScanner ) mContext ) . i n i t B o o k i n g L a y o u t ( ) ;<br />
335 }<br />
336 } ;<br />
337<br />
338 /∗∗<br />
339 ∗ S t a r t s s e p a r a t e worker t h r e a d to p r e s e r v e hanging UI<br />
340 ∗ 1 . Shows P r o g r e s s D i a l o g<br />
341 ∗ 2 . S t a r t s worker−t h r e a d<br />
342 ∗ 3 . Requests s e r v i c e<br />
343 ∗ 4 . Updates BookingLayout with r e q u e s t e d i n f o r m a t i o n<br />
344 ∗<br />
345 ∗ @param message a S t r i n g o f the message to send to the UMS S e r v e r<br />
346 ∗/<br />
347 p r i v a t e v o i d r e q u e s t S e r v i c e T h r e a d ( ) {<br />
348 ( ( CodeScanner ) mContext ) . s h o w P r o g r e s s D i a l o g ( showProgressDlgMsg .LOADSERVICE) ;<br />
349 // s t a r t a−worker−t h r e a d<br />
350 Thread t = new Thread ( ) {<br />
351 p u b l i c v o i d run ( ) {<br />
352 r e q u e s t S e r v i c e ( ) ;<br />
353 mHandler . p o s t ( mUpdateBookingLayout ) ;<br />
354 }<br />
355 } ;<br />
356 t . s t a r t ( ) ;<br />
357 }<br />
358<br />
359 /∗∗<br />
360 ∗ Requests SQL DB o f e x t e r n a l s e r v e r f o r s e r v i c e i n f o r m a t i o n<br />
361 ∗ 1 . Obtains SQL S e r v e r URI<br />
362 ∗ 2 . C r e a t e s Apache H t t p C l i e n t and HttpPost<br />
363 ∗ 3 . Puts NameValuePair i n t o POST<br />
364 ∗ 4 . P r o c e s s e s HTTP r e s p o n s e<br />
365 ∗ 5 . P a r s e s the r e c e i v e d JSON−data<br />
366 ∗/<br />
367 p r i v a t e v o i d r e q u e s t S e r v i c e ( ) {<br />
368 S t r i n g r e s u l t = n u l l ;<br />
369 InputStream i s = n u l l ;<br />
370 f i n a l S t r i n g SQLHOST = mContext . g e t R e s o u r c e s ( ) . g e t S t r i n g (R. s t r i n g .SQLHOST) ;<br />
371<br />
372 t r y {<br />
373 H t t p C l i e n t c l i e n t = new D e f a u l t H t t p C l i e n t ( ) ;<br />
374 HttpPost p o s t = new HttpPost (SQLHOST) ;<br />
375 L i s t nameValuePair = new A r r a y L i s t () ;<br />
376 nameValuePair . add ( new BasicNameValuePair ( " i d " , mId . t o S t r i n g ( ) ) ) ;<br />
377 p o s t . s e t E n t i t y ( new UrlEncodedFormEntity ( nameValuePair ) ) ;<br />
378 HttpResponse r e s p o n s e = c l i e n t . e x e c u t e ( p o s t ) ;<br />
379<br />
380 HttpEntity e n t i t y = r e s p o n s e . g e t E n t i t y ( ) ;<br />
381 i s = e n t i t y . getContent ( ) ;<br />
382<br />
383 B u f f e r e d R e a d e r s e r v i c e r e a d e r = new B u f f e r e d R e a d e r ( new InputStreamReader ( i s ,<br />
" UTF - 8 " ) , 8 ) ;<br />
384 r e s u l t=s e r v i c e r e a d e r . r e a d L i n e ( ) ;<br />
385 i s . c l o s e ( ) ;<br />
386 } c a t c h ( Exception e ) {<br />
387 Log . e ( " l o g _ t a g " , " E r r o r i n h t t p c o n n e c t i o n : "+e . t o S t r i n g ( ) ) ;<br />
388 }<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 65<br />
389 // P a r s e s JSON−data<br />
390 t r y {<br />
391 JSONArray j A r r a y = new JSONArray ( r e s u l t ) ;<br />
392 JSONObject s e r v i c e j s o n = j A r r a y . getJSONObject ( 0 ) ;<br />
393 mService . c l e a r ( ) ;<br />
394 mService . add ( s e r v i c e j s o n . g e t S t r i n g ( " t i t l e " ) ) ;<br />
395 mService . add ( s e r v i c e j s o n . g e t S t r i n g ( " d e s c r " ) ) ;<br />
396 mService . add ( s e r v i c e j s o n . g e t S t r i n g ( " f d a t e " ) ) ;<br />
397 mService . add ( s e r v i c e j s o n . g e t S t r i n g ( " c o s t s " ) ) ;<br />
398 mService . add ( formatNumber ( s e r v i c e j s o n . g e t S t r i n g ( " p h o n e n r " ) ) ) ;<br />
399 mService . add ( s e r v i c e j s o n . g e t S t r i n g ( " d u r a t i o n " ) ) ;<br />
400 }<br />
401 c a t c h ( JSONException e ) {<br />
402 Log . e ( " l o g _ t a g " , " E r r o r p a r s i n g d a t a "+e . t o S t r i n g ( ) ) ;<br />
403 }<br />
404 }<br />
405<br />
406 /∗∗<br />
407 ∗ S e t s o f f l i n e s e r v i c e i n f o r m a t i o n which i s c o n t a i n e d i n scanned QR Code , o t h e r f i e l d s a r e<br />
s e t to empty v a l u e s<br />
408 ∗/<br />
409 p r i v a t e v o i d s e t O f f l i n e S e r v i c e ( ) {<br />
410 mService . c l e a r ( ) ;<br />
411 mService . add ( mTitle ) ;<br />
412 mService . add ( mContext . g e t R e s o u r c e s ( ) . g e t S t r i n g (R. s t r i n g . n o i n e t ) ) ;<br />
413 mService . add ( " " ) ; // date<br />
414 mService . add ( " " ) ; // c o s t s<br />
415 mService . add ( mPhonenr ) ;<br />
416 mService . add ( " " ) ; // d u r a t i o n<br />
417 }<br />
418<br />
419 /∗∗<br />
420 ∗ Reads l o g i n d a t a from l o g i n f i l e on I n t e r n a l S t o r a g e<br />
421 ∗ 1 . Obtains l o g i n − f i l e name from s t r i n g r e s o u r c e<br />
422 ∗ 2 . Reads c o n t e n t o f f i l e<br />
423 ∗ 3 . S p l i t s c o n t e n t ( u s e r : pw) i n t o two p a r t s and s t o r e s them to mLogin<br />
424 ∗ 4 . I f l o g i n − f i l e e x i s t s mLogin i s empty<br />
425 ∗<br />
426 ∗ @return the read l o g i n d a t a<br />
427 ∗/<br />
428 p r i v a t e A r r a y L i s t readLoginFromFile ( ) {<br />
429 f i n a l S t r i n g LOGINSTORE = mContext . g e t R e s o u r c e s ( ) . g e t S t r i n g (R. s t r i n g .LOGINSTORE) ;<br />
430 S t r i n g userpw = n u l l ;<br />
431 mLogin . c l e a r ( ) ;<br />
432<br />
433 t r y {<br />
434 S t r i n g f i l e =LOGINSTORE;<br />
435 F i l e I n p u t S t r e a m f i s = mContext . o p e n F i l e I n p u t ( f i l e ) ;<br />
436 DataInputStream d i s = new DataInputStream ( f i s ) ;<br />
437 userpw = d i s . r e a d L i n e ( ) ;<br />
438 f i s . c l o s e ( ) ;<br />
439<br />
440 // S p l i t s u s e r : pw<br />
441 S t r i n g T o k e n i z e r s t = new S t r i n g T o k e n i z e r ( userpw , " : " ) ;<br />
442 w h i l e ( s t . hasMoreTokens ( ) ) {<br />
443 mLogin . add ( s t . nextToken ( ) ) ;<br />
444 }<br />
445 }<br />
446 c a t c h ( FileNotFoundException e ) {<br />
447 Log . e ( " l o g i n s t o r e " , " e r r o r r e a d i n g l o g i n s t o r e f i l e : "+e . t o S t r i n g ( ) ) ;<br />
448 }<br />
449 c a t c h ( IOException e ) {<br />
450 Log . e ( " l o g i n s t o r e " , " e r r o r r e a d i n g l o g i n s t o r e f i l e : "+e . t o S t r i n g ( ) ) ;<br />
451 }<br />
452<br />
453 r e t u r n mLogin ;<br />
454 }<br />
455<br />
456 }<br />
A.6 CodeScanner Activity-Klasse<br />
Listing A.8: /src/com.weitblick.codescanner/CodeScanner.java<br />
1 package com . w e i t b l i c k . c o d e s c a n n e r ;<br />
2<br />
3 import j a v a . t e x t . SimpleDateFormat ;<br />
4 import j a v a . u t i l . Date ;<br />
5<br />
6 import a n d r o i d . app . A c t i v i t y ;<br />
7 import a n d r o i d . app . A l e r t D i a l o g ;<br />
8 import a n d r o i d . app . P r o g r e s s D i a l o g ;<br />
9 import a n d r o i d . c o n t e n t . Context ;<br />
10 import a n d r o i d . c o n t e n t . D i a l o g I n t e r f a c e ;<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 66<br />
11 import a n d r o i d . c o n t e n t . I n t e n t ;<br />
12 import a n d r o i d . net . Uri ;<br />
13 import a n d r o i d . os . Bundle ;<br />
14 import a n d r o i d . u t i l . Log ;<br />
15 import a n d r o i d . view . L a y o u t I n f l a t e r ;<br />
16 import a n d r o i d . view . Menu ;<br />
17 import a n d r o i d . view . M e n u I n f l a t e r ;<br />
18 import a n d r o i d . view . MenuItem ;<br />
19 import a n d r o i d . view . View ;<br />
20 import a n d r o i d . view . ViewGroup ;<br />
21 import a n d r o i d . widget . Button ;<br />
22 import a n d r o i d . widget . CheckBox ;<br />
23 import a n d r o i d . widget . EditText ;<br />
24 import a n d r o i d . widget . ImageView ;<br />
25 import a n d r o i d . widget . R e l a t i v e L a y o u t ;<br />
26 import a n d r o i d . widget . TextView ;<br />
27 import a n d r o i d . widget . Toast ;<br />
28<br />
29 import com . w e i t b l i c k . c o d e s c a n n e r . DataAccess . S t a t u s ;<br />
30<br />
31 p u b l i c c l a s s CodeScanner e x t e n d s A c t i v i t y {<br />
32 // DataAccess−Object , used to handle r e q u e s t e d s e r v i c e data<br />
33 DataAccess da ;<br />
34<br />
35 // I n i t i a l i z e s UI Elements<br />
36 R e l a t i v e L a y o u t l a y o u t s c a n n i n g ;<br />
37 R e l a t i v e L a y o u t l a y o u t b o o k i n g ;<br />
38 ImageView i m g q r ;<br />
39 Button b t n s c a n ;<br />
40 Button b t n r e s c a n ;<br />
41 Button b t n b o o k s e r v i c e ;<br />
42 Button b t n m a k e c a l l ;<br />
43 TextView t x t t i t l e ;<br />
44 TextView t x t d e s c ;<br />
45 TextView t x t d a t e ;<br />
46 TextView t x t c o s t s ;<br />
47<br />
48 P r o g r e s s D i a l o g d i a l o g ;<br />
49<br />
50 //OVERRIDEN ACTIVITY−METHODS<br />
51 /∗∗<br />
52 ∗ I n i t i a l i z e s A c t i v i t y method :<br />
53 ∗ 1 . S e t s view to xml−l a y o u t d e f i n e d i n / r e s / l a y o u t / c o d e s c a n n e r . xml<br />
54 ∗ 2 . I n v o k e s UI−I n i t i a l i z i n g method i n i t U I ( )<br />
55 ∗ 3 . I f t h e r e i s no DataAccess o b j e c t , i n i t i a l i z e ScanningLayout<br />
56 ∗ 4 . e l s e ( e . g . a f t e r a s c r e e n o r i e n t a t i o n change ) i n i t i a l i z e BookingLayout<br />
57 ∗<br />
58 ∗ @param s a v e d I n s t a n c e S t a t e a Bundle o b j e c t which r e c o v e r s saved i n f o r m a t i o n<br />
59 ∗<br />
60 ∗ @see a n d r o i d . app . A c t i v i t y#onCreate ( a n d r o i d . os . Bundle )<br />
61 ∗/<br />
62 @Override<br />
63 p u b l i c v o i d onCreate ( Bundle s a v e d I n s t a n c e S t a t e ) {<br />
64 s u p e r . onCreate ( s a v e d I n s t a n c e S t a t e ) ;<br />
65 setContentView (R. l a y o u t . c o d e s c a n n e r ) ;<br />
66<br />
67 i n i t U I ( ) ;<br />
68<br />
69 // c h e c k s whether t h e r e i s a l r e a d y a DataAccess−Object , i f y e s i n i t i a l i z e Booking−Layout<br />
70 da = ( DataAccess ) g e t L a s t N o n C o n f i g u r a t i o n I n s t a n c e ( ) ;<br />
71 i f ( da==n u l l ) {<br />
72 i n i t S c a n n i n g L a y o u t ( ) ;<br />
73 }<br />
74 e l s e i n i t B o o k i n g L a y o u t ( ) ;<br />
75 }<br />
76<br />
77 /∗∗<br />
78 ∗ R e t a i n s DataAccess o b j e c t b e f o r e s c r e e n o r i e n t a t i o n change<br />
79 ∗<br />
80 ∗ @see a n d r o i d . app . A c t i v i t y#o n R e t a i n N o n C o n f i g u r a t i o n I n s t a n c e ( )<br />
81 ∗/<br />
82 @Override<br />
83 p u b l i c Object o n R e t a i n N o n C o n f i g u r a t i o n I n s t a n c e ( ) {<br />
84 f i n a l DataAccess data = da ;<br />
85 r e t u r n data ;<br />
86 }<br />
87<br />
88 /∗∗<br />
89 ∗ Obtain scanned r e s u l t s from Barcode Scanner App<br />
90 ∗ 1 . I n v o k e s s t a t i c p a r s e A c t i v i t y R e s u l t −method o f I n t e n t I n t e g r a t o r c l a s s to p a r s e s c a n r e s u l t<br />
91 ∗ 2 . C r e a t e s DataAccess−o b j e c t<br />
92 ∗ 3 . I n i t i a t e s BookingLayout<br />
93 ∗ params d e s c r i p t i o n o f the Android API R e f e r e n c e :<br />
94 ∗<br />
95 ∗ @param requestCode The i n t e g e r r e q u e s t code o r i g i n a l l y s u p p l i e d to<br />
s t a r t A c t i v i t y F o r R e s u l t ( ) , a l l o w i n g you t o i d e n t i f y who t h i s r e s u l t came from<br />
96 ∗ @param r e s u l t C o d e The i n t e g e r r e s u l t code r e t u r n e d by the c h i l d a c t i v i t y through i t s<br />
s e t R e s u l t ( )<br />
97 ∗ @param i n t e n t An I n t e n t , which can r e t u r n r e s u l t data t o the c a l l e r ( v a r i o u s data can be<br />
a t t a c h e d to I n t e n t ” e x t r a s ”)<br />
98 ∗<br />
99 ∗ @see a n d r o i d . app . A c t i v i t y#o n A c t i v i t y R e s u l t ( i n t , i n t , a n d r o i d . c o n t e n t . I n t e n t )<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 67<br />
100 ∗/<br />
101 @Override<br />
102 p u b l i c v o i d o n A c t i v i t y R e s u l t ( i n t requestCode , i n t r e s u l t C o d e , I n t e n t i n t e n t ) {<br />
103 I n t e n t R e s u l t s c a n R e s u l t = I n t e n t I n t e g r a t o r . p a r s e A c t i v i t y R e s u l t ( requestCode , r e s u l t C o d e ,<br />
i n t e n t ) ;<br />
104 i f ( s c a n R e s u l t != n u l l ) {<br />
105 S t r i n g m S c a n r e s u l t=s c a n R e s u l t . g e t C o n t e n t s ( ) ;<br />
106 da = new DataAccess ( t h i s , m S c a n r e s u l t ) ;<br />
107 i n i t B o o k i n g L a y o u t ( ) ;<br />
108 }<br />
109 e l s e Log . e ( " s c a n _ e r r o r " , " s c a n n i n g e r r o r " ) ;<br />
110 }<br />
111<br />
112 /∗∗<br />
113 ∗ C r e a t e s o p t i o n s menu which pops up a f t e r menu button o f smartphone i s p r e s s e d . I n f l a t e s menu<br />
g i v e n i n / r e s /menu/ optionsmenu . xml<br />
114 ∗ params d e s c r i p t i o n out o f Android API R e f e r e n c e :<br />
115 ∗<br />
116 ∗ @param menu The o p t i o n s menu i n which you p l a c e your i t e m s<br />
117 ∗<br />
118 ∗ @see a n d r o i d . app . A c t i v i t y#onCreateOptionsMenu ( a n d r o i d . view . Menu)<br />
119 ∗/<br />
120 @Override<br />
121 p u b l i c b o o l e a n onCreateOptionsMenu (Menu menu ) {<br />
122 M e n u I n f l a t e r i n f l a t e r = g e t M e n u I n f l a t e r ( ) ;<br />
123 i n f l a t e r . i n f l a t e (R. menu . optionsmenu , menu ) ;<br />
124 r e t u r n t r u e ;<br />
125 }<br />
126<br />
127 /∗∗<br />
128 ∗ Enables or d i s a b l e s d e l e t e l o g i n item whether DataAccess o b j e c t e x i s t s o r not<br />
129 ∗ params d e s c r i p t i o n out o f Android API R e f e r e n c e :<br />
130 ∗<br />
131 ∗ @param menu The o p t i o n s menu as l a s t shown o r f i r s t i n i t i a l i z e d by onCreateOptionsMenu ( )<br />
132 ∗<br />
133 ∗ @see a n d r o i d . app . A c t i v i t y#onPrepareOptionsMenu ( a n d r o i d . view . Menu)<br />
134 ∗/<br />
135 @Override<br />
136 p u b l i c b o o l e a n onPrepareOptionsMenu (Menu menu ) {<br />
137 i f ( da==n u l l | | ! da . i s L o g i n S a v e d ( ) ) menu . g e t I t e m ( 0 ) . s e t E n a b l e d ( f a l s e ) ;<br />
138 e l s e menu . g e t I t e m ( 0 ) . s e t E n a b l e d ( t r u e ) ;<br />
139 r e t u r n t r u e ;<br />
140 }<br />
141<br />
142 /∗∗<br />
143 ∗ Handles optionsmenu<br />
144 ∗ 1 . i t m d e l l o g i n : d e l e t e s on ” I n t e r n a l S t o r a g e ” saved l o g i n d a t a<br />
145 ∗ 2 . i t m c r e d i t s : pops up c r e d i t s d i a l o g<br />
146 ∗<br />
147 ∗ @param item The menu item t h a t was s e l e c t e d<br />
148 ∗<br />
149 ∗ @see a n d r o i d . app . A c t i v i t y#o n O p t i o n s I t e m S e l e c t e d ( a n d r o i d . view . MenuItem )<br />
150 ∗/<br />
151 @Override<br />
152 p u b l i c b o o l e a n o n O p t i o n s I t e m S e l e c t e d ( MenuItem item ) {<br />
153 // Handle item s e l e c t i o n<br />
154 s w i t c h ( item . g e t I t e m I d ( ) ) {<br />
155 c a s e R. i d . i t m d e l l o g i n :<br />
156 da . d e l e t e L o g i n F i l e ( ) ;<br />
157 r e t u r n t r u e ;<br />
158 c a s e R. i d . i t m c r e d i t s :<br />
159 s h o w C r e d i t s ( ) ;<br />
160 r e t u r n t r u e ;<br />
161 d e f a u l t :<br />
162 r e t u r n s u p e r . o n O p t i o n s I t e m S e l e c t e d ( item ) ;<br />
163 }<br />
164 }<br />
165<br />
166 //PUBLIC METHODS<br />
167 /∗∗<br />
168 ∗ I n i t i a l i z e s Booking−Layout<br />
169 ∗ 1 . Shows and h i d e s l a y o u t s<br />
170 ∗ 2 . S e t s S t a t u s<br />
171 ∗ 3 . F i l l s l a y o u t e l e m e n t s dependent on s e r v i c e r e q u e s t s t a t e<br />
172 ∗/<br />
173 p u b l i c v o i d i n i t B o o k i n g L a y o u t ( ) {<br />
174 l a y o u t s c a n n i n g . s e t V i s i b i l i t y ( View . INVISIBLE ) ;<br />
175 l a y o u t b o o k i n g . s e t V i s i b i l i t y ( View . VISIBLE ) ;<br />
176<br />
177 // to r e a c t whether scanned code i s v a l i d , i n e t i s a v a i l a b l e e t c . i n v o k e s e t S t a t u s ( ) b e i n g<br />
a b l e to r e a c t to i t<br />
178 da . s e t S t a t u s ( ) ;<br />
179<br />
180 s w i t c h ( da . mStatus ) {<br />
181 c a s e VALID NO INET :<br />
182 c a s e VALID INET :<br />
183 t x t t i t l e . s e t T e x t ( da . mService . g e t ( 0 ) ) ;<br />
184 t x t d e s c . s e t T e x t ( da . mService . g e t ( 1 ) ) ;<br />
185 t x t d a t e . s e t T e x t ( da . mService . g e t ( 2 ) ) ;<br />
186 t x t c o s t s . s e t T e x t ( da . mService . g e t ( 3 )+" E U R " ) ;<br />
187 i f ( da . mStatus==S t a t u s . VALID NO INET) {<br />
188 t x t c o s t s . s e t T e x t ( " " ) ;<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 68<br />
189 b t n b o o k s e r v i c e . s e t E n a b l e d ( f a l s e ) ;<br />
190 }<br />
191 b t n b o o k s e r v i c e . s e t E n a b l e d ( t r u e ) ;<br />
192 b t n b o o k s e r v i c e . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
193 @Override<br />
194 p u b l i c v o i d o n C l i c k ( View v ) {<br />
195 da . loginAndSend ( ) ;<br />
196 }<br />
197 }) ;<br />
198 b t n m a k e c a l l . s e t E n a b l e d ( t r u e ) ;<br />
199 b t n m a k e c a l l . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
200 @Override<br />
201 p u b l i c v o i d o n C l i c k ( View v ) {<br />
202 makeCall ( ) ;<br />
203 }<br />
204 }) ;<br />
205 b t n r e s c a n . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
206 @Override<br />
207 p u b l i c v o i d o n C l i c k ( View v ) {<br />
208 S t r i n g [ ] d l g s c a n n e r d l = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R.<br />
a r r a y . d l g s c a n n e r d l ) ;<br />
209 I n t e n t I n t e g r a t o r . i n i t i a t e S c a n ( CodeScanner . t h i s ,<br />
d l g s c a n n e r d l [ 0 ] , d l g s c a n n e r d l [ 1 ] , d l g s c a n n e r d l [ 2 ] ,<br />
d l g s c a n n e r d l [ 3 ] , " Q R _ C O D E " ) ;<br />
210 }<br />
211 }) ;<br />
212 break ;<br />
213 c a s e VALID PROCESSING :<br />
214 t x t t i t l e . s e t T e x t ( da . mTitle ) ;<br />
215 t x t d e s c . s e t T e x t ( " " ) ;<br />
216 t x t d a t e . s e t T e x t ( " " ) ;<br />
217 t x t c o s t s . s e t T e x t ( " " ) ;<br />
218 b t n b o o k s e r v i c e . s e t E n a b l e d ( f a l s e ) ;<br />
219 b t n m a k e c a l l . s e t E n a b l e d ( t r u e ) ;<br />
220 b t n m a k e c a l l . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
221 @Override<br />
222 p u b l i c v o i d o n C l i c k ( View v ) {<br />
223 makeCall ( ) ;<br />
224 }<br />
225 }) ;<br />
226 b t n r e s c a n . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
227 @Override<br />
228 p u b l i c v o i d o n C l i c k ( View v ) {<br />
229 S t r i n g [ ] d l g s c a n n e r d l = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R.<br />
a r r a y . d l g s c a n n e r d l ) ;<br />
230 I n t e n t I n t e g r a t o r . i n i t i a t e S c a n ( CodeScanner . t h i s ,<br />
d l g s c a n n e r d l [ 0 ] , d l g s c a n n e r d l [ 1 ] , d l g s c a n n e r d l [ 2 ] ,<br />
d l g s c a n n e r d l [ 3 ] , " Q R _ C O D E " ) ;<br />
231 }<br />
232 }) ;<br />
233 break ;<br />
234 c a s e INVALID :<br />
235 S t r i n g [ ] i n v a l i d c o d e = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R. a r r a y . i n v a l i d c o d e ) ;<br />
236 t x t t i t l e . s e t T e x t ( i n v a l i d c o d e [ 0 ] ) ;<br />
237 t x t d e s c . s e t T e x t ( i n v a l i d c o d e [ 1 ] ) ;<br />
238 t x t d a t e . s e t T e x t ( " " ) ;<br />
239 t x t c o s t s . s e t T e x t ( " " ) ;<br />
240 b t n b o o k s e r v i c e . s e t E n a b l e d ( f a l s e ) ;<br />
241 b t n m a k e c a l l . s e t E n a b l e d ( f a l s e ) ;<br />
242 b t n r e s c a n . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
243 @Override<br />
244 p u b l i c v o i d o n C l i c k ( View v ) {<br />
245 S t r i n g [ ] d l g s c a n n e r d l = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R.<br />
a r r a y . d l g s c a n n e r d l ) ;<br />
246 I n t e n t I n t e g r a t o r . i n i t i a t e S c a n ( CodeScanner . t h i s ,<br />
d l g s c a n n e r d l [ 0 ] , d l g s c a n n e r d l [ 1 ] , d l g s c a n n e r d l [ 2 ] ,<br />
d l g s c a n n e r d l [ 3 ] , " Q R _ C O D E " ) ;<br />
247 }<br />
248 }) ;<br />
249 break ;<br />
250 }<br />
251 }<br />
252<br />
253 /∗∗<br />
254 ∗ Shows l o g i n ( a l e r t ) d i a l o g and s e t s l o g i n d a t a to mLogin i n DataAccess−Object<br />
255 ∗/<br />
256 p u b l i c v o i d showLoginDlg ( ) {<br />
257 f i n a l L a y o u t I n f l a t e r i n f l a t e r = ( L a y o u t I n f l a t e r ) g e t S y s t e m S e r v i c e (<br />
LAYOUT INFLATER SERVICE) ;<br />
258 f i n a l View inputView = i n f l a t e r . i n f l a t e (R. l a y o u t . u s e r p w d i a l o g , ( ViewGroup )<br />
findViewById (R. i d . u s e r p w l a y o u t ) ) ;<br />
259 f i n a l EditText t x t u s e r = ( EditText ) inputView . findViewById (R. i d . t x t u s e r ) ;<br />
260 f i n a l EditText txt pw = ( EditText ) inputView . findViewById (R. i d . txt pw ) ;<br />
261 f i n a l CheckBox c b s a v e l o g i n = ( CheckBox ) inputView . findViewById (R. i d . c b s a v e l o g i n ) ;<br />
262 S t r i n g [ ] d l g l o g i n = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R. a r r a y . d l g l o g i n ) ;<br />
263<br />
264 A l e r t D i a l o g . B u i l d e r b u i l d e r = new A l e r t D i a l o g . B u i l d e r ( CodeScanner . t h i s ) ;<br />
265 b u i l d e r . s e t T i t l e ( d l g l o g i n [ 0 ] ) ;<br />
266 b u i l d e r . s e t M e s s a g e ( d l g l o g i n [ 1 ] ) ;<br />
267 b u i l d e r . setView ( inputView ) ;<br />
268 b u i l d e r . s e t P o s i t i v e B u t t o n ( d l g l o g i n [ 2 ] , new D i a l o g I n t e r f a c e . O n C l i c k L i s t e n e r ( ) {<br />
269 p u b l i c v o i d o n C l i c k ( D i a l o g I n t e r f a c e d i a l o g , i n t whichButton ) {<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 69<br />
270 S t r i n g u s e r = t x t u s e r . getText ( ) . t o S t r i n g ( ) ;<br />
271 S t r i n g pw = txt pw . getText ( ) . t o S t r i n g ( ) ;<br />
272 da . mLogin . add ( u s e r ) ;<br />
273 da . mLogin . add (pw) ;<br />
274<br />
275 // i f checkbox i s checked , s a v e l o g i n<br />
276 i f ( c b s a v e l o g i n . isChecked ( ) ) da . w r i t e L o g i n T o F i l e ( ) ;<br />
277<br />
278 // format and send message based on r e q u e s t e d s e r v i c e<br />
279 da . sendMessageThread ( da . formatMessage ( ) ) ;<br />
280 r e t u r n ;<br />
281 }<br />
282 }) ;<br />
283 b u i l d e r . s e t N e g a t i v e B u t t o n ( d l g l o g i n [ 3 ] , new D i a l o g I n t e r f a c e . O n C l i c k L i s t e n e r ( ) {<br />
284 p u b l i c v o i d o n C l i c k ( D i a l o g I n t e r f a c e d i a l o g , i n t whichButton ) {<br />
285 r e t u r n ;<br />
286 }<br />
287 }) ;<br />
288 A l e r t D i a l o g a l e r t = b u i l d e r . c r e a t e ( ) ;<br />
289 a l e r t . show ( ) ;<br />
290 }<br />
291<br />
292 /∗∗<br />
293 ∗ Pops up P r o g r e s s D i a l o g which i s d i s p l a y e d w h i l e l o n g e r o p e r a t i o n s a r e pending<br />
294 ∗<br />
295 ∗ @param type the type o f P r o g r e s s D i a l o g message which s h o u l d be shown<br />
296 ∗/<br />
297 p u b l i c v o i d s h o w P r o g r e s s D i a l o g ( DataAccess . showProgressDlgMsg type ) {<br />
298 s w i t c h ( type ) {<br />
299 c a s e OFF:<br />
300 d i a l o g . d i s m i s s ( ) ;<br />
301 break ;<br />
302 c a s e LOADSERVICE:<br />
303 S t r i n g [ ] d l g l o a d s e r v i c e = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R. a r r a y .<br />
d l g l o a d s e r v i c e ) ;<br />
304 d i a l o g = P r o g r e s s D i a l o g . show ( CodeScanner . t h i s , d l g l o a d s e r v i c e [ 0 ] ,<br />
d l g l o a d s e r v i c e [ 1 ] ) ;<br />
305 break ;<br />
306 c a s e BOOKSERVICE:<br />
307 S t r i n g [ ] d l g b o o k s e r v i c e = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R. a r r a y .<br />
d l g b o o k s e r v i c e ) ;<br />
308 d i a l o g = P r o g r e s s D i a l o g . show ( CodeScanner . t h i s , d l g b o o k s e r v i c e [ 0 ] ,<br />
d l g b o o k s e r v i c e [ 1 ] ) ;<br />
309 }<br />
310 }<br />
311<br />
312 /∗∗<br />
313 ∗ Shows d i a l o g with booking c o n f i r m a t i o n<br />
314 ∗ I f s e n d i n g o p e r a t i o n was s u c c e s s f u l :<br />
315 ∗ A l e r t D i a l o g . B u i l d e r −o b j e c t i s c r e a t e d what i s s e t with d i f f e r e n t p r o p e r t i e s ( t i t l e ,<br />
message , p o s i t i v e / n e g a t i v e button )<br />
316 ∗ I f not :<br />
317 ∗ A t o a s t ( a s h o r t d i a l o g message ) pops up with s e n d i n g r e q u e s t e r r o r<br />
318 ∗<br />
319 ∗ @param s e n t the b o o l e a n v a l u e which i n d i c a t e s s t a t e o f s e n d i n g r e q u e s t<br />
320 ∗/<br />
321 p u b l i c v o i d showBookedDlg ( b o o l e a n s e n t ) {<br />
322 S t r i n g [ ] d l g b o o k e d = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R. a r r a y . d l g b o o k e d ) ;<br />
323<br />
324 i f ( s e n t ) {<br />
325 A l e r t D i a l o g . B u i l d e r b u i l d e r = new A l e r t D i a l o g . B u i l d e r ( t h i s ) ;<br />
326 b u i l d e r . s e t T i t l e ( d l g b o o k e d [ 0 ] ) ;<br />
327 b u i l d e r . s e t M e s s a g e ( " D e r D i e n s t \ " "+da . mService . g e t ( 0 )+" \ " w u r d e e r f o l g r e i c h g e b u c h t<br />
. M ö c h t e n S i e d e n T e r m i n i n I h r e n K a l e n d e r e i n t r a g e n ? " ) ;<br />
328 b u i l d e r . s e t P o s i t i v e B u t t o n ( d l g b o o k e d [ 1 ] , new D i a l o g I n t e r f a c e . O n C l i c k L i s t e n e r ( ) {<br />
329 @Override<br />
330 p u b l i c v o i d o n C l i c k ( D i a l o g I n t e r f a c e d i a l o g , i n t which ) {<br />
331 addEvent ( ) ;<br />
332 r e t u r n ;<br />
333 }<br />
334 }) ;<br />
335 b u i l d e r . s e t N e g a t i v e B u t t o n ( d l g b o o k e d [ 2 ] , new D i a l o g I n t e r f a c e . O n C l i c k L i s t e n e r ( ) {<br />
336 @Override<br />
337 p u b l i c v o i d o n C l i c k ( D i a l o g I n t e r f a c e d i a l o g , i n t which ) {<br />
338 r e t u r n ;<br />
339 }<br />
340 }) ;<br />
341 A l e r t D i a l o g a l e r t = b u i l d e r . c r e a t e ( ) ;<br />
342 a l e r t . show ( ) ;<br />
343 }<br />
344 e l s e Toast . makeText ( t h i s , d l g b o o k e d [ 3 ] , Toast .LENGTH LONG) . show ( ) ;<br />
345 }<br />
346<br />
347 /∗∗<br />
348 ∗ Pops up c r e d i t s d i a l o g<br />
349 ∗ 1 . Obtains d i a l o g messages from s t r i n g r e s o u r c e s<br />
350 ∗ 2 . C r e a t e s A l e r t D i a l o g −B u i l d e r −o b j e c t<br />
351 ∗ 3 . S e t s d i a l o g p r o p e r t i e s t i t l e , message and an OK−button<br />
352 ∗ 4 . Shows d i a l o g<br />
353 ∗<br />
354 ∗/<br />
355 p u b l i c v o i d s h o w C r e d i t s ( ) {<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 70<br />
356 S t r i n g [ ] d l g c r e d i t s = t h i s . g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R. a r r a y . d l g c r e d i t s ) ;<br />
357<br />
358 A l e r t D i a l o g . B u i l d e r b u i l d e r = new A l e r t D i a l o g . B u i l d e r ( t h i s ) ;<br />
359 b u i l d e r . s e t T i t l e ( d l g c r e d i t s [ 0 ] ) ;<br />
360 b u i l d e r . s e t M e s s a g e ( d l g c r e d i t s [ 1 ] ) ;<br />
361 b u i l d e r . s e t N e u t r a l B u t t o n ( d l g c r e d i t s [ 2 ] , new D i a l o g I n t e r f a c e . O n C l i c k L i s t e n e r ( ) {<br />
362 @Override<br />
363 p u b l i c v o i d o n C l i c k ( D i a l o g I n t e r f a c e d i a l o g , i n t which ) {<br />
364 r e t u r n ;<br />
365 }<br />
366 }) ;<br />
367 A l e r t D i a l o g a l e r t = b u i l d e r . c r e a t e ( ) ;<br />
368 a l e r t . show ( ) ;<br />
369 }<br />
370<br />
371 //PRIVATE METHODS<br />
372 /∗∗<br />
373 ∗ I n i t i a l i z e s UI Elements by r e f e r r i n g to ID r e s o u r c e s p r o v i d e d by the xml−l a y o u t f i l e s<br />
374 ∗/<br />
375 p r i v a t e v o i d i n i t U I ( ) {<br />
376 l a y o u t s c a n n i n g = ( R e l a t i v e L a y o u t ) findViewById (R. i d . l a y o u t s c a n n i n g ) ;<br />
377 l a y o u t b o o k i n g = ( R e l a t i v e L a y o u t ) findViewById (R. i d . l a y o u t b o o k i n g ) ;<br />
378 i m g q r = ( ImageView ) findViewById (R. i d . i m g q r ) ;<br />
379 b t n s c a n = ( Button ) findViewById (R. i d . b t n s c a n ) ;<br />
380 b t n r e s c a n = ( Button ) findViewById (R. i d . b t n r e s c a n ) ;<br />
381 b t n b o o k s e r v i c e = ( Button ) findViewById (R. i d . b t n b o o k s e r v i c e ) ;<br />
382 b t n m a k e c a l l = ( Button ) findViewById (R. i d . b t n m a k e c a l l ) ;<br />
383 t x t t i t l e = ( TextView ) findViewById (R. i d . t x t t i t l e ) ;<br />
384 t x t d e s c = ( TextView ) findViewById (R. i d . t x t d e s c ) ;<br />
385 t x t d a t e = ( TextView ) findViewById (R. i d . t x t d a t e ) ;<br />
386 t x t c o s t s = ( TextView ) findViewById (R. i d . t x t c o s t s ) ;<br />
387 }<br />
388<br />
389 /∗∗<br />
390 ∗ I n i t i a l i z e s Scanning−Layout<br />
391 ∗ 1 . Shows Scanning−Layout<br />
392 ∗ 2 . S e t s two OnClick l i s t e n e r to shown image and button<br />
393 ∗/<br />
394 p r i v a t e v o i d i n i t S c a n n i n g L a y o u t ( ) {<br />
395 l a y o u t s c a n n i n g . s e t V i s i b i l i t y ( View . VISIBLE ) ;<br />
396 b t n s c a n . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
397 @Override<br />
398 p u b l i c v o i d o n C l i c k ( View v ) {<br />
399 S t r i n g [ ] d l g s c a n n e r d l = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R. a r r a y .<br />
d l g s c a n n e r d l ) ;<br />
400 I n t e n t I n t e g r a t o r . i n i t i a t e S c a n ( CodeScanner . t h i s , d l g s c a n n e r d l [ 0 ] ,<br />
d l g s c a n n e r d l [ 1 ] , d l g s c a n n e r d l [ 2 ] , d l g s c a n n e r d l [ 3 ] , " Q R _ C O D E " ) ;<br />
401 }<br />
402 }) ;<br />
403 i m g q r . s e t O n C l i c k L i s t e n e r ( new View . O n C l i c k L i s t e n e r ( ) {<br />
404 @Override<br />
405 p u b l i c v o i d o n C l i c k ( View v ) {<br />
406 S t r i n g [ ] d l g s c a n n e r d l = g e t R e s o u r c e s ( ) . g e t S t r i n g A r r a y (R. a r r a y .<br />
d l g s c a n n e r d l ) ;<br />
407 I n t e n t I n t e g r a t o r . i n i t i a t e S c a n ( CodeScanner . t h i s , d l g s c a n n e r d l [ 0 ] ,<br />
d l g s c a n n e r d l [ 1 ] , d l g s c a n n e r d l [ 2 ] , d l g s c a n n e r d l [ 3 ] , " Q R _ C O D E " ) ;<br />
408 }<br />
409 }) ;<br />
410 }<br />
411<br />
412 /∗∗<br />
413 ∗ I n i t i a t e s p h o n e c a l l to phonenr saved i n mService o f DataAccess−o b j e c t<br />
414 ∗ 1 . C r e a t e s URI from phonenr<br />
415 ∗ 2 . C r e a t e s an i m p l i c i t i n t e n t with ACTION CALL<br />
416 ∗ 3 . Sends i n t e n t<br />
417 ∗/<br />
418 p r i v a t e v o i d makeCall ( ) {<br />
419 Uri u r i = Uri . p a r s e ( da . mService . g e t ( 4 ) ) ;<br />
420 I n t e n t i n t e n t = new I n t e n t ( I n t e n t . ACTION CALL, u r i ) ;<br />
421 s t a r t A c t i v i t y ( i n t e n t ) ;<br />
422 }<br />
423<br />
424 /∗∗<br />
425 ∗ Adds an e v e n t to the c a l e n d a r<br />
426 ∗ 1 . C r e a t e s i n t e n t<br />
427 ∗ 2 . Puts e v e n t i n f o r m a t i o n t o i n t e n t<br />
428 ∗ 3 . Formats p r e v i o u s l y f o r m a t t e d date t o s t a n d a r d Date−format<br />
429 ∗ 4 . Sends i n t e n t<br />
430 ∗/<br />
431 p r i v a t e v o i d addEvent ( ) {<br />
432 I n t e n t i n t e n t = new I n t e n t ( I n t e n t . ACTION EDIT) ;<br />
433 i n t e n t . setType ( " v n d . a n d r o i d . c u r s o r . i t e m / e v e n t " ) ;<br />
434 i n t e n t . putExtra ( " t i t l e " , da . mService . g e t ( 0 ) ) ;<br />
435 i n t e n t . putExtra ( " d e s c r i p t i o n " , da . mService . g e t ( 1 ) ) ;<br />
436<br />
437 Date date = n u l l ;<br />
438 t r y {<br />
439 S t r i n g p a t t e r n = " d d . M M . y y ’ u m ’ H H : m m ’ U h r ’ " ;<br />
440 SimpleDateFormat s d f = new SimpleDateFormat ( p a t t e r n ) ;<br />
441 date = s d f . p a r s e ( da . mService . g e t ( 2 ) ) ;<br />
442 } c a t c h ( Exception e ) {<br />
443 Log . e ( " d a t e p a r s e _ e r r o r " , e . t o S t r i n g ( ) ) ;<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
A Quellcodes 71<br />
444 }<br />
445<br />
446 Double d u r a t i o n = new Double ( da . mService . g e t ( 5 ) ) ;<br />
447 l o n g durationms = ( l o n g ) ( d u r a t i o n ∗3600∗1000) ;<br />
448<br />
449 i n t e n t . putExtra ( " b e g i n T i m e " , date . getTime ( ) ) ;<br />
450 i n t e n t . putExtra ( " e n d T i m e " , date . getTime ( )+durationms ) ;<br />
451 i n t e n t . putExtra ( " a l l D a y " , f a l s e ) ;<br />
452 s t a r t A c t i v i t y ( i n t e n t ) ;<br />
453 }<br />
454 }<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Literaturverzeichnis 72<br />
Literaturverzeichnis<br />
[BP09] Becker, A. ; Pant, M.: Android: Grundlagen und Programmierung.<br />
dpunkt.verlag GmbH, 2009<br />
[Bun11] Bundesverband Informationswirtschaft, Telekommunikation<br />
und neue Medien e.V. (BITKOM): Jeder fünfte Handynutzer besitzt<br />
ein Smartphone. http://www.bitkom.org/65510_65506.aspx, zuletzt abgerufen<br />
am 31.03.2011<br />
[Can11] Canalys: Google’s Android becomes the world’s leading smart phone platform.<br />
http://www.canalys.com/pr/2011/r2011013.html, zuletzt abgerufen<br />
am 23.03.2011<br />
[com11] comScore, Inc.: Smartphones gewinnen an Fahrtwind in Deutschland.<br />
http://www.comscore.com/ger/Press_Events/Press_Releases/2011/1/<br />
Google_Android_Shows_Fastest_Growth_Among_Smartphone_Platforms_<br />
in_Germany, zuletzt abgerufen am 31.03.2011<br />
[Goo11] Google: Android Developers. http://developer.android.com, zuletzt<br />
abgerufen am 23.03.2011<br />
[HBF07] Hompel, M. ; Büchter, H. ; Franzke, U.: Identifikationssysteme und<br />
Automatisierung. Springer, 2007<br />
[Heg10] Hegen, M.: Mobile Tagging: Potenziale von QR-Codes im Mobile Business.<br />
Diplomica Verlag, 2010<br />
[hei11] heise online: IDC-Prognose: Smartphones boomen weiter, Microsoft überholt<br />
Apple. http://heise.de/-1217792, zuletzt abgerufen am 31.03.2011<br />
[Int11a] Internet Engineering Task Force (IETF): RFC 2818 - HTTP<br />
over TLS. http://tools.ietf.org/html/rfc2818, zuletzt abgerufen am<br />
25.03.2011<br />
[Int11b] Internet Engineering Task Force (IETF): RFC3966 - The tel URI<br />
for Telephone Numbers. http://tools.ietf.org/html/rfc3966, zuletzt<br />
abgerufen am 29.03.2011<br />
[Len00] Lenk, B.I.: Handbuch der automatischen Identifikation: ID-Techniken, 1D-<br />
Codes, 2D-Codes, 3D-Codes. Monika Lenk Fachbuchverlag, 2000<br />
[Len02] Lenk, B.: 2D-Codes, Matrixcodes, Stapelcodes, Composite Codes, Dotcodes.<br />
Lenk Monika Fachbuchverlag, 2002<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Literaturverzeichnis 73<br />
[Len04] Lenk, B.: Handbuch der Automatischen Identifikation 3. Strichcode-Praxis:<br />
Projektierung, Codeauswahl, Drucktechnik, Codeprüfung, Etikettierung, Lesegeräte.<br />
Monika Lenk Fachbuchverlag, 2004<br />
[Len05] Lenk, B.: Optische Identifikation. Monika Lenk Fachbuchverlag, 2005<br />
[LT07] Langlotz Tobias, Bimber O.: Unsynchronized 4D Barcodes - Coding and<br />
Decoding Time-Multiplexed 2D Colorcodes / Bauhaus-University Weimar.<br />
2007. – Forschungsbericht<br />
[Ora11a] Oracle Corporation (Hrsg.): Open Message Queue 4.5 Technical Overview.<br />
Redwood City, CA 94065, U.S.A.: Oracle Corporation, 2011<br />
[Ora11b] Oracle Corporation: Universal Message Service (UMS). http:<br />
//mq.java.net/4.3-content/ums/umsIntro.html, zuletzt abgerufen am<br />
24.03.2011<br />
[PDK03] Pötzsch ; Decker ; Kühnen: Private Haushalte in der Informationsgesellschaft.<br />
http://www.destatis.de/jetspeed/<br />
portal/cms/Sites/destatis/Internet/DE/Content/Publikationen/<br />
Querschnittsveroeffentlichungen/WirtschaftStatistik/<br />
Informationsgesellschaft/Privhaushalte,property=file.pdf, 2/2003<br />
[Pro11] Projekt WEITBLICK: WEITBLICK - Wissenbasierte Technologien<br />
und bedarfsgerechte Leistungen <strong>für</strong> Senioren durch individualisierte<br />
Care-Konzepte. http://www.weitblick-aal.de/, zuletzt abgerufen am<br />
20.03.2011<br />
[Rod08] Rodriguez, Alex ; IBM (Hrsg.): RESTful Web services: The basics. :<br />
IBM, 2008<br />
[Sch06] Schwenkler, T.: Sicheres Netzwerkmanagement: Konzepte, Protokolle,<br />
Tools. Springer, 2006<br />
[Son10] Soni, H.: Proceedings of the 2009 International Conference on Signals, Systems<br />
and Automation (ICSSA 2009). Universal-Publishers, 2010<br />
[Soy11] Soyatec: eUML2. http://www.soyatec.com/euml2/, zuletzt abgerufen<br />
am 28.03.2011<br />
[TCK10] Tan, K.T. ; Chai, D. ; Kato, H.: Barcodes for Mobile Devices. Cambridge<br />
University Press, 2010<br />
[TEC11] TEC-IT Datenverarbeitung GmbH: Online Barcode Generator. http:<br />
//barcode.tec-it.com/barcode-generator.aspx, zuletzt abgerufen am<br />
20.03.2011<br />
[The11] The Apache Software Foundation: Apache Tomcat 7 Documentation.<br />
http://tomcat.apache.org/tomcat-7.0-doc/index.html, zuletzt abgerufen<br />
am 24.03.2011<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Literaturverzeichnis 74<br />
[Wan11] Wanninger, B.: Mobile Tagging- Grundlagen, Einsatzmöglichkeiten und<br />
Akzeptanz. GRIN Verlag GmbH, 2011<br />
[Wik11] Wikipedia: Smartphone (Wikipedia). http://de.wikipedia.org/wiki/<br />
Smartphone, zuletzt abgerufen am 20.04.2011<br />
[ZXi11a] ZXing Project (Google): zxing - Multi-format 1D/2D barcode image<br />
processing library with clients for Android, Java. http://code.google.com/<br />
p/zxing/, zuletzt abgerufen am 20.03.2011<br />
[ZXi11b] ZXing Project (Google): Barcode Contents. http://code.google.<br />
com/p/zxing/wiki/BarcodeContents, zuletzt abgerufen am 20.04.2011<br />
[ZXi11c] ZXing Project (Google): QR Code Generator. http://zxing.<br />
appspot.com/generator/, zuletzt abgerufen am 23.03.2011<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Abbildungsverzeichnis 75<br />
Abbildungsverzeichnis<br />
2.1 Veranschaulichter Ablauf des gebildeten Rückkanals . . . . . . . . . . . 2<br />
3.1 Modulbreite/Zellgröße einer optischen Marke (entnommen aus [Len02]) 6<br />
3.2 Codeaufbau Code-128 . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />
3.3<br />
” Projekt WEITBLICK“ codiert mit dem Stapelcode PDF417 (erstellt<br />
mit [TEC11]) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />
3.4 Data Matrix und QR Code: Suchmuster mit Taktzellen (entnommen aus<br />
[Len05, S. 140 und 150]) . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />
3.5<br />
” Projekt WEITBLICK“ codiert in Data Matrix und QR Code, Vergleich<br />
der Platzeffizienz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />
3.6 Anschaulich dargestellte Testreihe (aus Tab. 3.2) des praktischen Vergleichs<br />
von Code-128, Data Matrix und QR Code . . . . . . . . . . . . 19<br />
4.1 Struktur des Dienstbuchungssystems . . . . . . . . . . . . . . . . . . . 22<br />
4.2 Erweiterte Struktur des Dienstbuchungssystems . . . . . . . . . . . . . 25<br />
4.3 Architektur eines Universal Message Service (UMS) (entnommen aus<br />
[Ora11b]) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />
4.4 JMS Nachrichten Domänen (entnommen aus [Ora11a, S. 27]) . . . . . . 27<br />
4.5 Android Systemarchitektur (entnommen aus [Goo11]) . . . . . . . . . . 31<br />
4.6 Verschachtelung von UI-Elementen (entnommen aus [Goo11]) . . . . . 36<br />
4.7 Scanning- und BookingLayout des User Interface . . . . . . . . . . . . 36<br />
4.8 Klassendiagramm der CodeScanner App . . . . . . . . . . . . . . . . . 40<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Tabellenverzeichnis 76<br />
Tabellenverzeichnis<br />
3.1 Anzahl der zu codierenden Zeichen . . . . . . . . . . . . . . . . . . . . 9<br />
3.2 Vergleich des maximalen Leseabstands (in cm) der Codes Code-128, Data<br />
Matrix, QR Code in Abhängigkeit vom horizontalen Betrachtungswinkel<br />
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />
4.1 SQL-Tabelle des mySQL-Servers als Dienstserver . . . . . . . . . . . . 30<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Abkürzungsverzeichnis 77<br />
Abkürzungsverzeichnis<br />
aapt . . . . . . . . . . . . . . . . Android Asset Packaging Tool<br />
AI . . . . . . . . . . . . . . . . . Application Identifier<br />
API . . . . . . . . . . . . . . . . Application Program Interface<br />
ASCII . . . . . . . . . . . . . . American Standard Code for Information Interchange<br />
CA . . . . . . . . . . . . . . . . . Certification Authority<br />
CCD . . . . . . . . . . . . . . . Charge-coupled Device<br />
CE-HTML . . . . . . . . . Consumer-Electronics HyperText Markup Language<br />
CRC . . . . . . . . . . . . . . . Cyclic Redundancy Check<br />
DEX . . . . . . . . . . . . . . . dalvik executables<br />
dip . . . . . . . . . . . . . . . . . density independent pixels<br />
DVB-RCS . . . . . . . . . . Digital Video Broadcast - Return Channel Satellite<br />
DVM . . . . . . . . . . . . . . . Dalvik Virtual Machine<br />
EAN . . . . . . . . . . . . . . . European Article Number<br />
GTIN . . . . . . . . . . . . . . Global Trade Item Number<br />
GUI . . . . . . . . . . . . . . . . Graphical User Interface<br />
HbbTV . . . . . . . . . . . . Hybrid Broadcast Broadband TV<br />
HCCB . . . . . . . . . . . . . High Capacity Color Barcode<br />
HTTP . . . . . . . . . . . . . HyperText Transfer Protocol<br />
HTTPS . . . . . . . . . . . . HyperText Transfer Protocol Secure<br />
ID . . . . . . . . . . . . . . . . . Identifikationsnummer<br />
IETF . . . . . . . . . . . . . . . Internet Engineering Taskforce<br />
IP . . . . . . . . . . . . . . . . . . Internet Protocol<br />
JDK . . . . . . . . . . . . . . . Java Development Kit<br />
JMS . . . . . . . . . . . . . . . Java Message Service<br />
JVM . . . . . . . . . . . . . . . Java Virtual Machine<br />
MOM . . . . . . . . . . . . . . Message Oriented Middleware<br />
MP . . . . . . . . . . . . . . . . Mega Pixel<br />
OCR . . . . . . . . . . . . . . . Optical Character Recognition<br />
openMQ . . . . . . . . . . . open Message Queue<br />
OS . . . . . . . . . . . . . . . . . Operating System<br />
QR Code . . . . . . . . . . . Quick Response Code<br />
REST . . . . . . . . . . . . . . REpresentational State Transfer<br />
SDK . . . . . . . . . . . . . . . Standard Development Kit<br />
SQL . . . . . . . . . . . . . . . . Structured Query Language<br />
SSL . . . . . . . . . . . . . . . . Secure Sockets Layer<br />
TLS . . . . . . . . . . . . . . . . Transport Layer Security<br />
UMS . . . . . . . . . . . . . . . Universal Message Service<br />
UMTS . . . . . . . . . . . . . Universal Mobile Telecommunications System<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Abkürzungsverzeichnis 78<br />
UPC . . . . . . . . . . . . . . . Universal Product Code<br />
URI . . . . . . . . . . . . . . . . Uniform Resource Identifier<br />
WLAN . . . . . . . . . . . . . Wireless Local Area Network<br />
XML . . . . . . . . . . . . . . . eXtensible Markup Language<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Abkürzungsverzeichnis 79<br />
Quellcodeverzeichnis<br />
4.1 Buchung des Dienstes als HTTP Request . . . . . . . . . . . . . . . . . 27<br />
4.2 HTTP Bestätigungsantwort vom UMS an den Android Client . . . . . 28<br />
4.3 SQL Anfrage im PHP-Skript . . . . . . . . . . . . . . . . . . . . . . . . 30<br />
4.4 Das Android Manifest der CodeScanner App . . . . . . . . . . . . . . . 32<br />
4.5 Übergabe eines Objekts bei Stoppen einer Activity . . . . . . . . . . . 34<br />
4.6 Einstiegspunkt einer Anwendung: die onCreate(...)-Methode . . . . . . 34<br />
4.7 Auszug aus codescanner.xml . . . . . . . . . . . . . . . . . . . . . . . . 37<br />
4.8 Zugriff auf UI-Elemente aus einer Layout-XML-Datei . . . . . . . . . . 38<br />
4.9 Konstruktor der DataAccess-Klasse . . . . . . . . . . . . . . . . . . . . 40<br />
4.10 Methode parseScanresult(...) . . . . . . . . . . . . . . . . . . . . . . . . 41<br />
4.11 HTTP POST zur Anfrage der Dienstinformation über das PHP-Skript 42<br />
4.12 Auszug aus Methode requestService() . . . . . . . . . . . . . . . . . . . 42<br />
4.13 Methode requestServiceThread() . . . . . . . . . . . . . . . . . . . . . 43<br />
4.14 Methode formatMessage() . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />
4.15 Methode sendMessage(String message) . . . . . . . . . . . . . . . . . . 45<br />
4.16 onClick Listener und Initiierung des Scanvorgangs . . . . . . . . . . . . 47<br />
4.17 Überschriebene Methode onActivityResult(...): Abfangen der Scan-Ergebnisse<br />
und Erstellen eines DataAccess-Objekts . . . . . . . . . . . . . . . . . . 48<br />
4.18 Methode setStatus(): Steuerung des Ablaufs der Dienstabfrage . . . . . 49<br />
4.19 Methode initBookingLayout() . . . . . . . . . . . . . . . . . . . . . . . 50<br />
4.20 Methode makeCall() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />
A.1 weitblick services.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57<br />
A.2 /AndroidManifest.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . 57<br />
A.3 /res/layout/codescanner.xml . . . . . . . . . . . . . . . . . . . . . . . . 58<br />
A.4 /res/layout/userpw dialog.xml . . . . . . . . . . . . . . . . . . . . . . . 59<br />
A.5 /res/menu/optionsmenu.xml . . . . . . . . . . . . . . . . . . . . . . . . 59<br />
A.6 /res/values/strings.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />
A.7 /src/com.weitblick.codescanner/DataAccess.java . . . . . . . . . . . . . 60<br />
A.8 /src/com.weitblick.codescanner/CodeScanner.java . . . . . . . . . . . . 65<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Thesen zur Bachelorarbeit 80<br />
Thesen zur Bachelorarbeit<br />
1. Der QR Code ist <strong>für</strong> den Usecase der Aufgabenstellung die bestgeeignetste optische<br />
Marke.<br />
2. Bei der Anzeige der Dienstleistung muss auf Authentizität und Integrität geachtet<br />
werden.<br />
3. Das Dienstbuchungssystem verlangt Anpassungen sowohl auf der Client- als auch<br />
auf der Serverseite.<br />
4. Die Erzeugung eines QR Codes lässt sich sehr einfach implementieren.<br />
<strong>Ilmenau</strong>, den 02. 05. 2011 Florian Schlembach<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach
Erklärung 81<br />
Erklärung<br />
Die vorliegende Arbeit habe ich selbstständig ohne Benutzung anderer als der angegebenen<br />
Quellen angefertigt. Alle Stellen, die wörtlich oder sinngemäß aus veröffentlichten<br />
Quellen entnommen wurden, sind als solche kenntlich gemacht. Die Arbeit ist<br />
in gleicher oder ähnlicher Form oder auszugsweise im Rahmen einer oder anderer Prüfungen<br />
noch nicht vorgelegt worden.<br />
<strong>Ilmenau</strong>, den 02. 05. 2011 Florian Schlembach<br />
Nutzung eines Smartphones als Rückkanal <strong>für</strong> digitalen Rundfunk Bachelorarbeit Florian Schlembach