80
FSIV10 THORSTEN WEISKOPF APPLIKATIONSENTWICKLUNG FÜR ANDROID

Einführung in die Android Applikationsentwicklung

Embed Size (px)

DESCRIPTION

Einführung in die Android Applikationsentwicklung

Citation preview

Page 1: Einführung in die Android Applikationsentwicklung

FSIV10

THORSTEN

WEISKOPF APPLIKATIONSENTWICKLUNG FÜR ANDROID

Page 2: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

2

1 Einführung ................................................................................................... 3

2 Kapitel 1 – Android Grundlagen ................................................................... 4

2.1 Was ist Android? ........................................................................................................... 4

2.2 Die Entwicklungsumgebung .......................................................................................... 4

2.3 Google ADT.................................................................................................................... 5

2.4 Grober Aufbau einer Android App ................................................................................ 8

2.5 Grundlagen der Android Entwicklung ......................................................................... 10

2.5.1 View-Activity-Event-Intent .................................................................................. 10

2.5.2 Activity Lebenszyklus........................................................................................... 12

2.5.3 Die wichtigsten XML Dateien ausserhalb der Layouts ........................................ 14

2.5.4 Persistenz und Datenspeicherung in Adnroid ..................................................... 15

3 Kapitel 2 - App Dokumentation LittleProjectManager ................................ 16

3.1 Beschreibung der Applikation ..................................................................................... 16

3.2 Architektur und Funktionsweise der Applikation ....................................................... 18

3.2.1 Activity-View und Layout (VIEW) ........................................................................ 18

3.2.2 Activitys (Controller) ........................................................................................... 20

3.2.3 Dialogfragmente (Controller) .............................................................................. 23

3.2.4 Plain-Old-Java-Objects (Model) .......................................................................... 24

3.2.5 DataAccessObjects (Model) ................................................................................ 24

3.2.6 MySQLiteHelper und seine Tabellenklassen (Model) ......................................... 25

3.3 SQLite Datenbank ........................................................................................................ 26

3.3.1 Datenbankstruktur .............................................................................................. 27

3.4 Projekt und Paketstruktur ........................................................................................... 29

3.4.1 Pakete und Klassen ............................................................................................. 29

3.4.2 Projektdateien und Ressourcen .......................................................................... 31

4 Ausblick und Fazit ..................................................................................... 33

5 Abbildungsverzeichnis ............................................................................... 34

6 Abkürzungsverzeichnis .............................................................................. 35

7 Anlagen ..................................................................................................... 36

7.1 Eclipse Workbench ...................................................................................................... 37

7.2 Screenshots LittleProjectManager .............................................................................. 38

7.3 Architekturschaubild ................................................................................................... 40

7.4 Quellcode der Applikation .......................................................................................... 41

Page 3: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

3

1 Einführung Dieses Dokument entstand im Rahmen einer abschließenden

Leistungsfeststellung des Modules Softwareentwicklung. Vorgabe war es das

Gebiet der Android Applikationsentwicklung zu erschließen und eine für den

Bereich typische Applikation zu realisieren. Das Dokument gliedert sich daher

auch in zwei Bereiche. Kapitel eins beschreibt die Grundlagen der

Applikationsentwicklung, während Kapitel zwei die Architektur und

Funktionsweise der, im Rahmen der ALF erstellten, Applikation

„LittleProjektManager“ beschreibt. Im Anhang finden sich unter anderem

Screenshots der Applikation, Diagramme und der gesamte Quellcode der

Applikation.

Page 4: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

4

2 Kapitel 1 – Android Grundlagen

2.1 Was ist Android?

Android ist ein hauptsächlich von Google getriebenes „Open Source Projekt“

und wurde ursprünglich als Betriebssystem für mobile Geräte entwickelt. Es

findet jedoch mittlerweile auch auf anderen Geräten wie Fernsehern

Anwendung. Nach meiner persönlichen Einschätzung wird es nicht lange dabei

bleiben. Es gibt bereits Modelle für Uhren, Spielekonsolen und „intelligente

Haushaltsgeräte“ wie Kühlschränke und Spiegel auf denen Android läuft.

Im Kern besteht das Betriebssystem aus einem Linux Kernel welcher den

Hardwarezugriff und die Speicherverwaltung regelt. Gleich darauf aufgesetzt

läuft eine auf Java Technologie basierende virtuelle Maschine mit einer

entsprechenden Android Klassenbibliothek. Die virtuelle Maschine führt dann

den Bytecode bestimmter Module oder der programmierten Android Applikation

aus. Um jetzt Applikationen, also Anwendungen oder Apps, zu entwickeln stellt

Google ein „Java Programming Interface“ mit einer Reihe von Tools zur

Verfügung.

Zusätzlich können auch bereits vorhandene Softwarekomponenten mit

verwendet werden. Zum Beispiel die Tastatur, die Medienwiedergabe, der

Browser, die SQLite Datenbank oder OpenGL für 3D Grafik, um nur mal einen

Auszug zu nennen.

2.2 Die Entwicklungsumgebung

Im Prinzip könnten die Apps in einem einfachen Editor geschrieben werden und

per Android Service Development Kid zu Bytecode kompiliert, um anschließend

in der virtuellen Maschine des Android Gerätes ausgeführt zu werden.

Das wäre aber weder zeitgemäß, noch komfortabel oder besonders effizient.

Heute setzt man auf eine starke Entwicklungsumgebung. Google selbst

unterstützt hier mit zahlreichen Erweiterungen (PlugIns) die

Entwicklungsumgebung Eclipse, eine der meist verbreiteten IDEs (Integrated

Page 5: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

5

Development Enviroment) gerade in der Java Entwicklung. Eclipse ist ebenfalls

Opensource und damit kostenlos. Dies bietet sehr viel Flexibilität und

Erweiterungsmöglichkeiten. (Kurzer Einblick in Eclipse unter, 7.1 Eclipse

Workbench, im Anhang auf Seite 37 )

Um nun mit der Entwicklung beginnen zu können benötigt man lediglich:

• Eclipse http://www.eclipse.org/downloads/

• Android SDK (Service Development Kid)

http://developer.android.com/sdk/index.html

• ADT (Android Development Tools) Eclipse Plugin

http://developer.android.com/tools/sdk/eclipse-adt.html

Das ADT beinhaltet, neben vielen kleinen Hilfen wie einen grafischen Editor für

die Benutzeroberfläche, auch einen Emulator, welcher ein beliebiges Android

System emulieren kann und so ein schnelles Testen während der Entwicklung

auch ohne Endgerät ermöglicht. Man kann sich mehrere verschiedene virtuelle

Geräte konfigurieren und so verschiedene Displaygrößen und andere

Hardwareeigenschaften emulieren und testen.

2.3 Google ADT

Das Plugin bietet viele nützliche Dienste und Hilfen. Hier die wichtigsten:

• Assistent zum Erstellen eines neuen Android Projektes

• Assistent zum Erstellen von Attributen und Variablen

• Visueller Editor für die Benutzeroberfläche der App

• Einfaches Verwalten und Starten des Emulators

• Ausgabe vom Systemlog-Meldungen (Logcat) des Android Systems auf

dem Emulator

• Android SDK Manager (Verwaltet und hält SDK aktuell)

Page 6: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

6

Android API und Besonderheiten

Die Google API (Application Programming Interface) stellt die zentrale

Programmierschnittstelle dar. Ohne diese ist keine Entwicklung einer Android-

App möglich, da bereits bei der Darstellung bis hin zur Interaktion mit dem

Nutzer über das Touchscreen native Android-Funktionen benötigt werden. Es

reicht also nicht aus Java entwickeln zu können, sondern es ist zwingend

notwendig sich mit der Android API auseinander zu setzen und sich an deren

Regeln zu halten.

Die API existiert bisher in verschiedenen Versionen. Leider sind hier nicht alle

Funktionen abwärtskompatibel, was es zwingend erforderlich macht Android

mitzuteilen gegen welche API Version die App kompiliert ist.

Dies geschieht in der AndroidManifest.xml. Hier wird die minimale API

Anforderung und die zuletzt getestete API angegeben gegen die auch kompiliert

wurde. Ist die angegebene „Minimum Required SDK“ neuer als die auf dem

Installationsgerät so kann die Applikation dort nicht installiert werden. Fehlt

diese Angabe kann die Applikation zwar installiert werden es wird aber

womöglich zu Problemen bei der Ausführung kommen und damit zu schlechten

Bewertungen im Play Store.

Page 7: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

7

Abbildung 1- Eclipse New Android Application

Page 8: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

8

2.4 Grober Aufbau einer Android App

Grundsätzlich ist es jedem Entwickler frei gestellt wie er seine Anwendung

gestaltet und entwickelt. Android oder die API machen hier keine Vorgaben

sondern sind extrem flexibel in der Wahl der Softwarearchitektur. So können

bestimmte Probleme mittels XML oder direkt im Java Code gelöst werden.

Google treibt aber eine modulare Softwarearchitektur voran für ein modulares

Bestriebssystem. Und nur das macht auch Sinn. Die Vorteile von, im weitesten

Sinne losgelösten Einzelmodulen welche als Gesamtpaket eine Applikation

bilden, liegen auf der Hand. Hier wird nicht nur die einfachere Entwicklung im

Team oder Softwarepflege vereinfacht, sondern auch eine stabilere und

schnellere Ausführung der Applikation für das Android System ermöglicht. XML-

Dateien beispielsweise welche bestimmte Eigenschaften oder das Aussehen

der Applikation beschreiben, werden vor der eigentlichen Codeausführung

geladen und zwar schnell und stabil. Genauso gut könnte man die komplette

View, also das Aussehen, im Java-Code schreiben. Das wäre aber nicht nur

schlechter Stil, sondern würde auch zu Lasten der Performance gehen im

Vergleich zu dem XML-Layout.

In der Softwareentwicklung gibt es bestimmte Entwurfs- oder Architekturmuster

darunter auch das „Model View Controller“ Modell. Dieses Modell lässt sich

auch auf Android Applikationen anwenden und beschreibt eine klare Trennung

der angesprochenen drei Bereiche. Während das „Model“ den Businessbereich

und die Logik darstellt ist die „View“ für das Aussehen und die Interaktion mit

dem Anwender zuständig. Der „Controller“ kontrolliert nun die Nutzung des

„Models“ von der „View“ aus und weiß welche „View“ welches „Model“

verwendet.

Page 9: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

9

Vereinfachte Schematische Darstellung:

Activity.XML - VIEW

Activity.JAVA - Controller

PlainOldJavaObject – Model

Zusätzlich gibt es noch eine Persistenzschicht zur dauerhaften

Datenspeicherung in einer Datenbank. Im Fall von Android sind das SQLite

Datenbanken welche ganz einfach über die API angelegt und genutzt werden

können. Und das ist im Groben auch alles was eine Android App heute nutzt um

seine Aufgaben erfüllen zu können. Im nachfolgenden Kapitel werde ich hier

noch etwas mehr ins Detail gehen.

Abbildung 2- MVC Architektur

Quelle: wikipedia.de (MVC)

Page 10: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

10

2.5 Grundlagen der Android Entwicklung

2.5.1 View-Activity-Event-Intent

Activity

Die Activity stellt so zu sagen das Herzstück der Android Applikation dar mit

dem entscheidenden Programmcode welcher für die Ausführung der Aplikation

verantwortlich ist. Jede App muss mindestens eine Activity haben und eine

davon muss als Hauptactivity definiert sein. Also die, welche beim Starten der

App als erstes geladen und ausgeführt wird (Equivalent zur Main Methode

eines klassischen Java-Programmes). Die Activity definiert eine „View“ zur

Anzeige auf dem Bildschirm und behandelt dort auftretende Events wie

beispielsweise ein Klick auf einen Button. Die Activity benutzt „Intents“ um

andere Activitys zu starten.

View

Die View ist der sichtbare Teil der Activity und wird üblicherweise in einer XML-

Layout-Datei definiert.

Event

Ein Event wird ausgelöst, wenn etwas geschieht wie das Klicken auf einen

Button oder das Drücken des Suchen und Zurück Buttons. In der Activity muss

dann ein Listener definert sein welcher auf diese Events reagiert und

entsprechende Operationen durchführt.

Intent

Startet eine andere Activity also eine zweite Benutzeroberfläche auf dem

Bildschirm. Mittels „Bundels“ können dann einfache Parameter an die Activity

übergeben werden. Es können sogar Activities aus anderen Apps gestartet

werden so lange diese verfügbar und im Android System als öffentlich

gekennzeichnet sind. Beispielsweise könnte die Google Maps App gestartet

werden und Koordinaten übergeben werden.

Page 11: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

11

Abbildung 3- Zusammenarbeit Activity und View (Quelle http://www.androidpit.de/de/android/wiki/view/Android_Anf%C3%A4nger_Workshop)

Page 12: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

12

2.5.2 Activity Lebenszyklus

Da auf dem Handy die Ressourcen limitiert sind muss das Betriebssystem in

der Lage sein auf den Lebenszyklus der Apps Einfluß nehmen zu können. Jede

Activity hat ihren eigenen Lebenszyklus und so muss sich der Entwickler auch

um die entprechenden Phasen des Zyklusses kümmern um Datenverluste oder

unerwünschtes Verhalten zu vermeiden. Es gibt folgende Phasen:

• onCreate()

• onStart()

• onPause()

• onResume()

• onStop()

• onRestart()

• onDestroy()

Jede eigene Activity erbt diese Methoden von ihrer Vaterklasse Activity und

kann diese überschreiben. OnPause() beispielsweise tritt ein wenn die Activity

in den Hintegrund gerät weil ein Anruf herein kommt oder eine neue Activity

aufgerufen wird. Vielleicht wäre es hier sinnvoll die bereits eingegebenen Daten

in einer Datenbank zu speichern und bei onResume() wieder anzuzeigen.

Folgendes Schaubild soll die verschiedenen Stati verdeutlichen:

Page 13: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

13

Abbildung 4 - Activity Lebenszyklus (Quelle

http://www.androidpit.de/de/android/wiki/view/Android_Anf%C3%A4nger_Workshop)

Page 14: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

14

2.5.3 Die wichtigsten XML Dateien ausserhalb der Layouts

Strings.xml

Hier werden Variablen zur Darstellung definiert. Beispielsweise Beschriftungen

und Text für die Buttons in den Views, Hilfemeldungen oder sonstige Texte.

Android Manifest.xml

Ist die Grundlage jeder App und unabdingbar. Hier werden Metainformationen

wie das Icon, der Applikationsname und die Rechte, welche sich die Applikation

einräumt, bekannt gegeben. Diese werden dem Nutzer auch vor der Installation

bekannt gegeben und müssen bestätigt werden. Rechte sind beispielsweise

Zugriffe auf das Netzwerk, die Kamera oder die Kontaktdaten.

Ausserdem sollte noch die vorausgesetzte API Version angegeben werden, um

zu verhindern, dass die App auf nicht lauffähigen Geräten installiert werden

kann.

Exemplarisches Beispiel einer AdroidManifest.xml mit Erläuterung.

Abbildung 5- AndroidManifest.xml (Quelle

http://www.androidpit.de/de/android/wiki/view/Android_Anf%C3%A4nger_Workshop/)

Page 15: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

15

2.5.4 Persistenz und Datenspeicherung in Adnroid

Zur persistenten Datenspeicherung bietet Android eine einfache Art SQLite als

schlankes Datenbanksystem an. Durch das Erben und Überschreiben der

Klasse SQLiteOpenHelper wird es erleichtert eigene Datenbanken an zu legen,

welche dann per default als Datei auf der SD-Karte gespeichert werden.

SQLite ist eine Open-Source-Datenbank, die in Android eingebettet ist. SQLite

unterstützt Standardfunktionen von relationalen Datenbanken wie SQL-Syntax,

Transaktionen und Prepared Statements. Darüber hinaus bedarf es nur wenig

Speicher zur Laufzeit (ca. 250 KByte). SQLite unterstützt die Datentypen TEXT

(ähnlich String in Java), INTEGER (ähnlich wie long in Java) und REAL (ähnlich

wie double in Java). Alle anderen Formate müssen vor dem Speichern in einen

dieser Datentypen konvertiert werden.

Page 16: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

16

3 Kapitel 2 - App Dokumentation LittleProjectManager

3.1 Beschreibung der Applikation

Die App soll eine einfache Verwaltung von Projekten und seinen ToDo`s

möglich machen. Zusätzlich soll man die Zeit messen können wie lange man für

das jeweilige Projekt gearbeitet hat. Der Anwendungsfall kommt aus der Praxis.

Denn bei kleinen oder mittelgroßen Projekten wird häufig vergessen die eigene

Zeit zu messen um hinterher die geschätzte Zeit und die verbrauchte Zeit

gegenüber stellen zu können. Ausserdem soll es helfen dem Kunden die

korrekten Zeiten in Rechnung zu stellen. Die Möglichkeit ToDo`s anzulegen

dient lediglich der Übersichtlichkeit und stellt eine Art Notizzettel für das Projekt

dar. Ich habe mich bewusst dagegen entschieden die Zeiten für einzelne ToDos

zu tracken. Dies wäre zwar auf Grund der Datenbankstruktur möglich findet

aber in der Praxis wenig Relevanz da zumindest bei den Projekten kleinerer

Größenordnung diese Zeiten keine Rolle spielen und das Buchen für den

Nutzer zu aufwendig wäre.

Die Applikation bildet folgende funktionale und technische Leistungsmerkmale:

• Projekte anlegen und entfernen

• ToDo`s für Projekte anlegen und entfernen

• Einfaches „Einbuchen“ bei Arbeitsbeginn

• Einfaches „Ausbuchen“ bei Arbeitsende

• Zusätzlich soll auch ein manuelles Buchen von Zeiten möglich sein

• Die App soll direkt nach Buchung die aktuelle Zeit berechnen und

anzeigen

Technische Leistungsmerkmale:

• Daten in der SQLite Datenbank speichern

• Intuitive Bedienung über das Touch-Display

Page 17: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

17

• Optimiert für die Benutzung mit Smartphone, sollte aber auch auf einem

Tablet funktionsfähig sein

• Android spezifische Bedienelemente wie der Zurück Button und Menü

Button (vor Android 3.0) sollten unterstützt werden

Screenshots zur Verdeutlichung finden sich im Anhang unter 7.2 Screenshots

LittleProjectManager auf Seite 38.

Page 18: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

18

3.2 Architektur und Funktionsweise der Applikation

Hierzu empfiehlt es sich erst mal einen Blick auf das Schaubild aus Anlage 7.3

Architekturschaubild auf Seite 40 zu werfen. Dort ist ein Architekturdiagramm

der Applikation abgebildet unter Berücksichtigung des MVC Entwurfsmusters.

Es beinhaltet alle funktional wichtigen Klassen und XML Dateien der Applikation

und deren Abhängigkeiten, welche nun im Detail erläutert werden. Es empfiehlt

sich vorher im ersten Kapitel den Teil „Grober Aufbau einer Android Applikation“

gelesen zu haben.

3.2.1 Activity-View und Layout (VIEW)

In der VIEW befinden sich die XML Dateien. Drei Activity-Views und ein Layout.

Die activity_project_view und die activity_todo_view bestehen beide aus

ListViews um eine Liste der jeweiligen Objekte, eben Projekte und Todos,

darstellen zu können. Bei beiden kann über das Menü das Layout add_item.xml

aufgerufen werden. Dies ist eine Art Formular, um neue Todo's oder Projekte an

zu legen. Das Add-Item-Layout besteht aus einem Textfeld und einem Button

und wird hier einmal exemplarisch dargestellt:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

<EditText

android:id="@+id/editText1"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:ems="10"

android:inputType="textMultiLine" >

<requestFocus />

</EditText>

Page 19: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

19

<Button

android:id="@+id/button1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/Add"

android:onClick="AddClick"

/>

</LinearLayout>

Das ganze Layout besteht aus einem LinearLayout innerhalb dessen befinden

sich ein EditText Feld zum Eingeben des neuen Projektes oder des Todo und ein

Button zum Bestätigen. Zusätzlich werden Angaben zur Größe und Anordnung

des jeweiligen Elementes gemacht. Die android:id beschreibt den Namen über

den auf das Element später im JAVA Code zugegriffen werden kann und

android:text="@string/Add gibt an welcher Text auf dem Button stehen soll.

Unter android:id="@+id/editText1" kann das Textfeld in der JavaKlasse also der

jeweiligen Activity, welche das Layout gestartet hat, erreicht werden. Und

android:onClick="AddClick" gibt an, dass, wenn der Button Add gedrückt wird, in

der Activity die Methode AddClick() ausgeführt wird.

Die Dritte und letzte Activity-View ist die activity_time_manager.xml welche für

die Zeitbuchungen und die Anzeige der Zeiten zuständig ist. Dementsprechend

viele Elemente sind hier vorhanden:

ein Button zur Anzeig des aktuellen Datums

ein Button welcher die aktuelle Zeit anzeigt

ein Button zum Einbuchen

ein Button zum Ausbuchen

einen Button um nur die Zeit in Stunden und Minuten auf das Projekt

nachträglich als Arbeitszeit zu buchen.

Wird der Button für Datum gedrückt so öffnet sich ein spezielles Auswahlmenü

von Android zur Datumsauswahl und bei der Zeit ist es das gleiche. Diese

Auswahldialoge müssen als so genannte Dialogfragmente ausprogrammiert

Page 20: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

20

werden.

3.2.2 Activitys (Controller)

Jede Activity-View hat auch ihre eigene Klasse welche die verschiedenen Stati

des Lebenszyklus und die Interaktion mit dem Benutzer behandelt. Die

Hauptactivity ist in der AndroidManifest.xml beschrieben. Bei dieser Applikation

handelt es sich um die Activity Project_View.java. Jede Activity die als solche

fungieren soll hat als Vaterklasse die Klasse android.app.Activity und

überschreibt mindestens eine Methode: Die onCreate() Methode, welche in

unserem Fall nichts weiter macht als sich aktuelle Daten aus der Datenbank zu

holen und darzustellen. Zusätzlich wird noch das Optionsmenu deklariert und

auf das Drücken von Menüeinträgen, Listeinträgen und Buttons mit

entsprechendem Programmcode reagiert.

ProjectView.java

Füllt die ListView mit Projekten. Projekte können ausgewählt und anschließend

gelöscht werden. Genauso gut können nach Auswahl eines Projektes die

dazugehörigen Todos geladen werden. Dies geschieht durch das Aufrufen der

MyTodosOverview und die Übergabe der Projektid des ausgewählten Objektes.

Ausserdem kann das Layout add_item.xml aufgerufen werden und neue

Projekte angelegt werden.

Kurze Beschreibung der Methoden:

onCreate()

Legt die Activity-View fest welche angezeigt werden soll.

Ruft Hilsmethode showValuesFromDB() auf.

showValuesFromDB()

Holt sich die Projekte aus der Datenbank und setzt vorhandene Values in die

Liste.

Page 21: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

21

Aktiviert OnClickListner welcher das markierte Objekt der Liste festhält und

einfärbt.

onCreateOptionsMenu()

Legt das Menü Fest welches angezeigt wird wenn auf den Menü Button

gedrückt wird.

onOptionsItemSelected(MenuItem item)

Deklariert pro betätigtem Menüeintrag was passieren soll.

AddClick(View view)

Methode wird aufgerufen wenn im add_item.xml Layout der Button Add

gedrückt wird.

Der Inhalt des Textfeldes aus dem Layout wird als Projekt in die Datenbank

geschrieben

MyTodosOverview.java

Funktioniert genauso wie die ProjectView.java, ausser dass es sich hierbei um

die Todos handelt, die angezeigt, verwaltet und in die Datenbank geschrieben,

sowie dort gelöscht werden können.

TimeManager.java

Diese Activity ist die Aufwendigste in der Applikation. Sie übernimmt nicht nur

das Eintragen von Buchungen in die Datenbank sondern ist auch für die

aktuelle Anzeige von Datum und Uhrzeit zuständig. Außerdem errechnet sie bei

jeder Buchung die Arbeitszeit neu, sofern möglich und zeigt diese Information

direkt über die VIEW an. Die beiden Dialoge zur Datums- und Zeitauswahl

werden von ihr gestartet und beobachtet um Änderungen direkt zu erkennen.

Daher handelt es sich auch um eine FragmentActivity welche ihrerseits

erweiterte Funktionen anbietet als ihre Vaterklasse Activity.

Page 22: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

22

Die ganze Berechnung der Zeit erfolgt über ein java.util.Calendar Objekt

während die Anzeige über java.text.SimpleDateFormat formatiert wird.

Erläuterung der wichtigsten Methoden:

onCreate()

Legt die Activity-View fest welche angezeigt werden soll.

Ermittelt die aktuelle Zeit

Steuert die interne Hilfsmethode setTimeOnView(Calendar c) und

setDateOnView(Calendar c) an.

Steuert interne Hilfsmethode addTimeandDateButtonListners() an.

onResume()

Ermittelt das aktuelle Projekt und zeigt dessen Namen an sowie die bisher

gebuchte Arbeitszeit. Dies geschieht in der onResume() Methode so, dass die

Anzeige nicht nur nach dem Erstellen der Activity aktualisiert wird sondern auch

wenn die Activity im Hintergrund war.

setTimeOnView(Calendar c)

Zeigt die aktuelle Zeit im Button an

setDateOnView(Calendar c)

Zeigt aktuelles Datum im Datum Button an

addTimeandDateButtonListners()

Listner welcher auf das Drücken einer der Buttons reagiert

checkin(), checkout() und justbookthetime()

Bucht die entsprechende Zeit in die Datenbank.

Steuert CalcWorkingTime() an

CalcWorkingTime()

Errechnet die Arbeitszeit wenn möglich. Es wird überprüft ob genau so viele

Page 23: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

23

Ein- wie Ausbuchungen vorhanden sind, errechnet dann die neue Arbeitszeit

und schreibt diese Informationen in die Datenbank.

ShowDatePicker() und showTimePicker()

Zeigen die Dialoge zur Auswahl von Datum und Zeit an

OnTimeSetListener() und OnDateSetListener()

Reagieren auf die Zeitauswahl in dem sie die Zeit im Calendar Objekt ändern

und die ausgewählte Zeiten auf den Buttons der View visualisieren.

3.2.3 Dialogfragmente (Controller)

Zur Auswahl von Datum und Zeit werden TimePicker und DatePicker

verwendet. Dies sind Objekte um es dem Nutzer so komfortabel wie möglich zu

machen über den Touchscreen Datum und Zeiteingaben zu tätigen. Diese

werden von Android zur Verfügung gestellt. Um sie nutzen zu können, müssen

sie in so genannte Dialogfragmente verpackt werden. Also Dialoge welche

erscheinen während die eigentliche Activity im Hintergrund noch aktiv ist. Also

weder in den Status onPause() gesetzt, noch beendet wird. Wird also nun in der

Time_Manager.java Activity auf den Button mit dem Datum gedrückt so wird das

DatePickerFragment gestartet. Über einen Datencontainer, bei Android das

Bundle, werden die aktuellen Werte zur Anzeige übergeben und bei Auswahl

durch den Nutzer die ausgewählten Werte zurück an die Activity übergeben.

Page 24: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

24

3.2.4 Plain-Old-Java-Objects (Model)

Hier finden sich klassische Java Objekte welche in der Applikation durch alle

Instanzen hindurch genutzt werden wie Todo, TimeEntry oder Project. Klassisch

deshalb weil sie als Vaterklasse lediglich die Klasse Object besitzen. Diese

Objekte stellen immer jeweils ein Listeneintrag in der View oder eine Zeile in

der Datenbank dar. Dementsprechend sind auch die Attribute pro Klasse

gewählt:

3.2.5 DataAccessObjects (Model)

Hierunter fallen die drei Klassen ProjectDatasource.java,

TimeTableDatasource.java und TodosDatasource.java. Die Aufgabe des DAO

ist das Erlauben des Zugriffs auf die Datenbank und das Anbieten von

Methoden fürs Abholen und Schreiben von Daten. Dies beinhaltet den

Verbindungsauf- und Abbau genauso wie das Zusammenbauen bestimmter

SQL-Abfragen zum Herausholen aller oder nur eines bestimmten Datensatzes

mittels Fremdschlüssel. Das Ergebnis aus der Datenbank kommt als so

genannter Curser zurück und wird nicht einfach an die aufrufende Klasse

zurückgegeben. Es werden POJOs (Plain-Old-Java-Objects) vom jeweiligen

Typ erzeugt und einzeln oder in einer Liste zurück gegeben. Dazu wurden in

Abbildung 6 - Klassendiagramm Models

Page 25: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

25

der Klasse als privat gekennzeichnete Hilfsmethoden geschrieben.

3.2.6 MySQLiteHelper und seine Tabellenklassen (Model)

MySQLiteHelper hat als Vaterklasse SQLiteOpenHelper und überschreibt

onCreate() und onUpgrade(). OnCreate() wird vom Framework aufgerufen wenn

die Datenbank noch nicht existiert und onUpdate() wenn sich die

Versionsnummer ändert. Beide Methoden bekommen ein Datenbankobjekt

beim Aufruf übergeben, welches die Datenbank repräsentiert.

In der Applikation gibt es für jede Tabelle eine eigene Klasse:

• ProjectTable.java

• TodoTable.java

• TimeTabl.java

Jede dieser Tabellenklassen hat statische Variablen für den Tabellennamen und

die Spalten. Ausserdem besitzt jede Klasse ihre eigene statische onCreate()

und onUpdate() Methode in der der SQL-Befehl zum Erstellen und Updaten der

Tabellen ausformuliert ist. Hier wird auch angegeben welche Datentypen in die

Spalten gehören und ob es sich dabei um Schlüssel handelt.

Als Beispiel hier ein Auszug der Klasse ProjectTable, welche auch genau diese

Tabelle MYPROJECTS repräsentiert:

public class ProjectTable // Database table

public static final String TABLE_PJ = "myprojects";

public static final String COLUMN_ID = "_id";

public static final String COLUM_NAME = "name";

public static final String COLUM_WORKTIME = "worktime";

//SQL CREATE Statement

private static final String TABLE_CREATE_MYPROJECTS =""

+"create table " +TABLE_PJ +" ( "

+COLUMN_ID+ " integer primary key autoincrement, "

+COLUM_NAME +" text not null, "

+COLUM_WORKTIME +" integer"

+");";

/*

Page 26: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

26

* Tabelle erstellen

*/

public static void onCreate(SQLiteDatabase db) {

db.execSQL(TABLE_CREATE_MYPROJECTS);

}

Es wird von Android empfohlen als Primärschlüssel _id zu verwenden so wie

hier geschehen. Zusätzlich wird noch durch „autoincrement“ angegeben, dass

die Spalte automatisch hoch gezählt wird.

Die Klasse MySQLiteHelper führt jetzt in seiner eigenen onCreate() Methode

nur noch die statischen onCreate() Methoden der jeweiligen Tabellen aus:

Auszug aus public class MySQLiteHelper

@Override

public void onCreate(SQLiteDatabase db) {

ProjectTable.onCreate(db);

TodoTable.onCreate(db);

TimeTable.onCreate(db);

}

So ist sichergestellt, dass die Datenbanken alle angelegt sind und von Objekten

der Datasource Klasse darauf zu gegriffen werden kann.

3.3 SQLite Datenbank

Zur Datenspeicherung bietet Android eine sehr einfache Möglichkeit eine

SQLite Datenbank an zu legen. Der LittleProjektManager greift darauf zu. Die

Daten werden zwecks Normalisierung und einer einfachen Datenhaltung in drei

Tabellen gespeichert. Android empfiehlt für jede Tabelle eine Spalte _id als

Primärschlüssel zu verwenden. In unserem Falle deklarieren wir die Spalte _id

zusätzlich noch als „autoincrement“, so dass sie bei jedem Eintrag automatisch

hoch gezählt wird und uns die Verknüpfung somit vereinfacht. In SQLite gibt es

vier Datentypen:

Page 27: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

27

SQLite Datentyp Equivalent in JAVA

INTEGER Long

TEXT String

REAL Double

BLOB Data

Die Datenbank selbst wird von Android auf der SD-Karte unter dem Ordner

„data“ und dem jeweiligen Applikationsnamen als eine Datei gespeichert.

3.3.1 Datenbankstruktur

Abbildung 7 - Datenbankdiagramm

MYPROJECTS

Beinhaltet alle relevanten Informationen zum Projekt. Der eingegebene Name

als Text, eine _id als Primärschlüssel, der automatisch hoch gezählt wird und

die workingtime als Integer. Die Workingtime ist zu Beginn 0 und wird dann je

nach Buchungen hochgezählt und überschrieben. Einfache Zeitbuchen werden

direkt und nur hier gespeichert. Ein- und Ausbuchungen mit Datumsangaben

kommen in die Tabelle TIMETABLE.

TODO

Page 28: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

28

Ist eine unabhängige Tabelle mit eigener _id als Primärschlüssel und der

Aufgabe todo selbst als Text. Da alle Todos einem Projekt zugeordnet werden

müssen, sind sie über die pj_id als Fremdschlüssel mit der Tabelle

MYPROJECTS verbunden. Es besteht eine 1-zu-n Beziehung. Ein Projekt kann

viele Todos haben aber ein Todo kann nur zu einem Projekt gehören.

TIMETABLE

Hier werden alle Ein- und Ausbuchungen gespeichert, welche nicht nur als

Zeitbuchung, sondern mit einer kompletten Zeitangabe gebucht werden also

Datum und Uhrzeit. Beides zusammen wird im Java Code als Ganzzahl im

Datentyp long dargestellt und kann daher auch so in der Datenbank

eingetragen werden. Neben dem Primärschlüssel _id wird die Zeit als long, und

datetime als Integer gespeichert. Unter entrytype wird eine 0 fürs Einbuchen

und eine 1 fürs Ausbuchen geschrieben und die pj_id ist wieder die Verbindung

in Form eines Fremdschlüssels zur Tabelle MYPROJECTS. Auch hier besteht

vom Projekt der Tabelle MYPROJECTS ausgehend eine 1-zu-n Beziehung.

Page 29: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

29

3.4 Projekt und Paketstruktur

3.4.1 Pakete und Klassen

Da der Paketname eindeutig für die Applikation sein soll, um gezielt der eigenen

Applikation zugeordnet werden zu können, wurde hier de.thorstenweiskopf.lpm

gewählt. Das Kürzel de für die Länderdomäne, thorstenweiskopf als autor und

lpm als kürzel für den Applikationsname LittleProjectManager. Danach werden

noch Unterpakete verwendet um die unterschiedlichen Aufgabenbereiche

darzustellen:

Page 30: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

30

src: Hier liegen die eigenen Klassen. Unter dem Hauptpaket befinden sich die drei Activitys. .databse: alle datenbankrelevanten Klassen: Der SQLiteHelper welcher die Datenbank erstellt und updatet sowie die drei Datasources zum Zugriff auf die Datenbank. .tables: Tabellen selbst in Form von Java-Klassen die vom SQLiteHelper genutzt werden. .dialogframents ZeitAuswahlDialoge .model Daten Modelle für die verwendeten Datenobjekte: Projekt, Zeiteintrag und Todo. gen: Hier sind die von Android generierten Klassen abgelegt. Am wichtigsten ist die Klasse R welche über Referenzvariablen alle Ressourcen zur Verfügung stellt. Ressourcen sind: Layouts, Activity-Views, Strings, Menüs, Bilder usw.

Page 31: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

31

3.4.2 Projektdateien und Ressourcen

Das Android Projekt besteht allerdings aus mehr als nur den Java-Klassen

selbst. Es gibt noch ein Ressourcen Verzeichnis mit Inhalten und die

AndroidManifest.xml:

Page 32: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

32

/res:Ordner für Resource-Dateien /res/drawable-hdpi: Logos in hoher Auflösung /res/drawable-ldpi Logos in niedriger Auflösung /res/drawable-mdpi: Logos in mittlerer Auflösung /res/drawable-xhdpi:Logos in sehr hoher Auflösung /res/layout alle Layout-Definitionen Activity-Views und Layouts /res/menu: Menüs activity_project_view: Menü für die Projektübersicht activity_project_view: Menü für die ToDos /res/values: Variablen strings.xml: String-Definitionen für Buttons und Überschriften styles.xml: Erscheinungsbild der App AndroidManifest.xml:"Manifest"-Datei, definiert Infos wie Name, Logo und Haupt-Activity default.properties:Projekt-Eigenschaften

Page 33: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

33

4 Ausblick und Fazit Die Applikation „LittleProjektMananer“ hat noch Optimierungspotential

hinsichtlich des Designs. Ausserdem fehlt noch eine Implementierung der seit

Android 4.0 vorhandenen „ActionBar“ welche das Menü ersetzen soll. Eine

Möglichkeit für statistische Auswertungen über die bereits getätigten

Buchungen ist auch denkbar. Sind diese Leistungsmerkmale realisiert, was sich

bereits in Planung befindet, steht einer Veröffentlichung über den Google

„Playstore“ nichts mehr im Wege.

Als Fazit für Android selbst ist zu sagen, dass Android eine solide Basis bietet

native Applikationen zu entwickeln. Der modulare Aufbau bietet gute

Möglichkeiten für Erweiterungen und die Realisierung von größeren Projekten.

Diese Gründe und der Fakt, dass das Betriebssystem auf dem Vormarsch in

vielen Bereichen elektronischer Geräte ist, verspricht Android und den

Applikationsentwicklern eine aussichtsreiche Zukunft.

Page 34: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

34

5 Abbildungsverzeichnis

Abbildung 1 - Eclipse New Android Application .................................................. 7

Abbildung 2 - MVC Architektur ........................................................................... 9

Abbildung 3 - Zusammenarbeit Activity und View ........................................... 11

Abbildung 4 - Activity Lebenszyklus ............................................................... 13

Abbildung 5 - AndroidManifest.xml ................................................................. 14

Abbildung 6 - Klassendiagramm Models .......................................................... 24

Abbildung 7 - Datenbankdiagramm .................................................................. 27

Page 35: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

35

6 Abkürzungsverzeichnis

App Application (Anwendung)

IDE Integrated Development Enviroment

SDK Service Development Kit

ADT Android Development Tools

API Application Programming Interface

MVC Model View Controller (Softwarearchitektur)

POJO Plain Old Java Object (“simple” Javaklassen)

Page 36: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

36

7 Anlagen

Page 37: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

37

7.1 Eclipse Workbench (QUELLE: http://www.admin-wissen.de/tutorials/eclipse_workshop/ueberblick_workbench.html)

Zu Eclipse selbst und der Benutzung gibt es eine Reihe von Büchern und Seminare. Ich möchte hier nur einen Auszug aus www.admin-wissen.de einbinden welcher ganz gut die Benutzung erläutert:

1. Im Bereich 1 findest einen Überblick über die vorhandenen Projekte. Du kannst zwischen den Projekten navigieren und Dateien öffnen, erstellen oder Ordner in denProjekten anlegen etc.

2. In diesem Bereich ist der Editor zu finden. Im Editor kannst du den Sourcecode

schreiben, er wird farbig hervorgehoben und Fehler die Eclipse im Vorfeld erkennt werden markiert. In manchen Fällen signalisiert Eclipse mit einer Glühbirne, wie der Fehler möglicherweise behoben werden kann.

3. Hier befindet sich die Outline. Darin findest du wissenswertes über die im

Moment geöffnete Datei. Bei einer Klasses siehst du hier die Attribute und Methoden und kannst sie sortieren oder anders in der Outline organisieren. Durch einen Klick auf die Methode kommst du z.B. direkt an die Stelle im Quelltext wo sie implementiert ist. Dadurch bekommt man bei umfangreichen Klassen schnell einen Überblick welche Methoden die Klasse bietet.

4. In diesem Bereich findest du verschiedene Konsolenausgaben. Eine mögliche

Konsolenausgabe ist z.B. ein Kompilierungsfehler oder die Ausgabe des laufenden Programms.

Page 38: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

38

7.2 Screenshots LittleProjectManager

Projektübersicht

Projektübersicht mit Auswahl und Menü

Add Item Formular

Todoübersicht mit Auswahl und Menü

Page 39: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

39

Arbeitszeitverwaltung zum Buchen und Anzeigen von Zeiten

Dialog zur Zeitauswahl wenn

entsprechender Button gedrückt wurde

Page 40: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

40

7.3 Architekturschaubild

Page 41: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

41

7.4 Quellcode der Applikation

AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="de.thorstenweiskopf.lpm"

android:versionCode="1"

android:versionName="1.0" >

<!-- welches min und max sdk wird supported von dieser app -->

<uses-sdk

android:minSdkVersion="8"

android:targetSdkVersion="15" />

<!-- applicationbeschreibung-->

<application

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

<!-- alle Activitys also Views -->

<activity

android:name=".MyTodosOverview"

android:label="@string/title_activity_my_todos_overview" >

</activity>

<activity

android:name=".ProjectView"

android:label="@string/title_activity_project_view"

android:configChanges="orientation|keyboardHidden|keyboard|screenSize" >

<intent-filter>

<!-- Hauptactivity soll geöffnet werden beim start -->

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

<activity

android:name=".TimeManager"

android:label="@string/title_activity_time_manager" >

</activity>

</application>

</manifest>

Page 42: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

42

stringx.xml <resources>

<string name="app_name">LittleProjectManager</string>

<string name="title_activity_my_todos_overview">My Todos</string>

<string name="Add">Add</string>

<string name="Remove">Remove</string>

<string name="title_activity_my_todo_add">Add a Todo</string>

<string name="title_activity_project_view">My Projects</string>

<string name="title_activity_time_manager">My Project Times</string>

<string name="menu_settings">Settings</string>

<string name="menu_addpj">Add Project</string>

<string name="menu_showtodos">Show ToDo Items</string>

<string name="menu_remove_pj">Remove Project</string>

<string name="menu_timemanager">Project TimeManagement</string>

<string name="menu_timestats">Show Workingtime</string>

<string name="time_checkinbutton">Check In</string>

<string name="time_checkoutbutton">Check Out</string>

<string name="time_hourbutton">Timebooking (Hour and Minute)</string>

</resources>

Page 43: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

43

ACTIVITY-VIEWS activity_project_view.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent" >

<ListView

android:id="@+id/listView1"

android:layout_width="match_parent"

android:layout_height="wrap_content" >

</ListView>

</RelativeLayout>

activity_todos_view.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<LinearLayout

android:layout_height="wrap_content"

android:layout_width="wrap_content" >

<TextView

android:id="@+id/todo_lable"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="@string/title_activity_my_todos_overview"

android:textSize="30dp" />

</LinearLayout>

<LinearLayout

android:layout_height="match_parent"

android:layout_width="match_parent" >

<ListView

android:id="@+id/listView1"

android:layout_width="match_parent"

android:layout_height="wrap_content" >

</ListView>

</LinearLayout>

</LinearLayout>

Page 44: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

44

additem.xml <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

<EditText

android:id="@+id/editText1"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:ems="10"

android:inputType="textMultiLine" >

<requestFocus />

</EditText>

<Button

android:id="@+id/button1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/Add"

android:onClick="AddClick"

/>

</LinearLayout>

Page 45: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

45

activity_time_manager_view.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

<TextView

android:id="@+id/Text_ProjectLable"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginLeft="5dip"

android:text="Large Text"

android:textAppearance="?android:attr/textAppearanceLarge"

android:textSize="30dp" />

<TextView

android:id="@+id/Text_ProjectTime"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_margin="10dip"

android:text="Large Text"

android:textAppearance="?android:attr/textAppearanceLarge" />

<Button

android:id="@+id/button_date"

android:layout_width="199dp"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:layout_marginTop="5dip"

android:text="Button" />

<LinearLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:orientation="horizontal" >

<Button

android:id="@+id/button_time"

android:layout_width="198dp"

android:layout_height="wrap_content"

android:text="Button" />

</LinearLayout>

<LinearLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal" >

<Button

android:id="@+id/button_checkin"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_vertical"

android:layout_margin="10dip"

android:text="@string/time_checkinbutton" />

Page 46: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

46

<Button

android:id="@+id/button_checkout"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_margin="10dip"

android:text="@string/time_checkoutbutton" />

</LinearLayout>

<Button

android:id="@+id/button_hours"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:text="@string/time_hourbutton" />

</LinearLayout>

Page 47: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

47

MENUS acitivity_project_view <menu xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/addpj" android:title="@string/menu_addpj"></item>

<item android:id="@+id/showTodos" android:title="@string/menu_showtodos"></item>

<item android:id="@+id/removepj" android:title="@string/menu_remove_pj"></item>

<item android:id="@+id/timemanager" android:title="@string/menu_timemanager"></item>

</menu>

activity_todos_view <menu xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/addpj" android:title="@string/menu_addpj"></item>

<item android:id="@+id/showTodos" android:title="@string/menu_showtodos"></item>

<item android:id="@+id/removepj" android:title="@string/menu_remove_pj"></item>

<item android:id="@+id/timemanager" android:title="@string/menu_timemanager"></item>

</menu>

Page 48: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

48

JAVA KLASSEN MyTodosOverview.java

package de.thorstenweiskopf.lpm;

import java.util.ArrayList;

import java.util.List;

import de.thorstenweiskopf.lpm.database.TodosDatasource;

import de.thorstenweiskopf.lpm.model.ToDo;

import de.thorstenweiskopf.lpm.R;

import android.os.Bundle;

import android.app.Activity;

import android.graphics.Color;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.ArrayAdapter;

import android.widget.EditText;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.Toast;

public class MyTodosOverview extends Activity {

ArrayAdapter<ToDo> adapter;

//Variablen der Todo Liste

public static List<ToDo> values = new ArrayList<ToDo>();

int selectedItem = -999;

private String projectname;

private long projectid;

//For Database Use

private TodosDatasource datasource;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_todos_view);

//Datasource benutzen

datasource = new TodosDatasource(this);

Bundle extras = getIntent().getExtras();

if (extras == null) {

return;

}

// Get data via the key from Intent

projectname = extras.getString("ProjectName");

projectid = extras.getLong("ProjectId");

if (projectname != null) {

// Show projectname as lable

Page 49: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

49

TextView lable = (TextView) findViewById(R.id.todo_lable);

lable.setText(projectname);

}

showValuesFromDB(projectid);

}

/*

* Methode um mittels projectid die entsprechenden Todos anzuzeigen

*/

private void showValuesFromDB(long projectid) {

values.clear();

try {

datasource.open();

values = datasource.getAllTodosFromProject(Long.toString(projectid));

datasource.close();

} catch (Exception ex) {

Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG).show();

}

adapter = new ArrayAdapter<ToDo>(this,

android.R.layout.simple_list_item_1, android.R.id.text1, values);

// Assign adapter to ListView

ListView listView = (ListView) findViewById(R.id.listView1);

listView.setAdapter(adapter);

//Set a OnClickListner to the ListView to choose one todo

listView.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView<?> parent, View view,

int position, long id) {

selectedItem = position; //the choosen one

//change bgcolor of the selected item

for(int a = 0; a < parent.getChildCount(); a++)

{

parent.getChildAt(a).setBackgroundColor(Color.WHITE);

}

view.setBackgroundColor(Color.GRAY);

openOptionsMenu();

}

});

}

/*

* Methode setzt alle vorhandene Todos in die Liste

* DERZEIT nicht genutzt

*/

private void showValuesFromDB() {

values.clear();

try {

datasource.open();

values = datasource.getAllTodos();

datasource.close();

} catch (Exception ex) {

Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG).show();

}

adapter = new ArrayAdapter<ToDo>(this,

android.R.layout.simple_list_item_1, android.R.id.text1, values);

// Assign adapter to ListView

ListView listView = (ListView) findViewById(R.id.listView1);

Page 50: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

50

listView.setAdapter(adapter);

//Set a OnClickListner to the ListView to choose one todo

listView.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView<?> parent, View view,

int position, long id) {

selectedItem = position; //the choosen one

//change bgcolor of the selected item

for(int a = 0; a < parent.getChildCount(); a++)

{

parent.getChildAt(a).setBackgroundColor(Color.WHITE);

}

view.setBackgroundColor(Color.GRAY);

openOptionsMenu();

}

});

}

/*

* (non-Javadoc)

* @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)

* OptionsMenuStuff

*/

@Override

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.activity_todos_view, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

if (item.getItemId() == R.id.Add){

ListView listView = (ListView) findViewById(R.id.listView1);

listView.setAdapter(adapter);

// show the add view

setContentView(R.layout.additem);

} else if (item.getItemId() == R.id.Remove) {

if (selectedItem != -999){

ToDo todo = adapter.getItem(selectedItem);

selectedItem = -999;

try {

datasource.open();

datasource.removeTodo(todo);

datasource.close();

} catch (Exception ex) {

Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG)

.show();

}

// show the main view

setContentView(R.layout.activity_todos_view);

showValuesFromDB();

}

else{

Toast.makeText(this, "Please choose a Item from List",

Toast.LENGTH_LONG).show();

}

}

Page 51: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

51

return super.onOptionsItemSelected(item);

}

/*

* Method of the layout additem.xml

* Beschrieben im Layout als AddClick

*/

public void AddClick(View view){

if (view.getId() == R.id.button1){

EditText text = (EditText)findViewById(R.id.editText1);

//values.add(text.getText().toString());

//put the new value in the database

try {

datasource.open();

datasource.creatTodo(text.getText().toString(),

Long.toString(projectid));//Fehlt noch die Projektid vom DB Objekt Projekt

datasource.close();

} catch (Exception ex) {

Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG).show();

}

//show the main view

setContentView(R.layout.activity_todos_view);

// Show projectname as lable

TextView lable = (TextView) findViewById(R.id.todo_lable);

lable.setText(projectname);

showValuesFromDB(projectid);

}

}

}

Page 52: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

52

ProjectView.java package de.thorstenweiskopf.lpm;

import java.util.ArrayList;

import java.util.List;

import de.thorstenweiskopf.lpm.database.ProjectDatasource;

import de.thorstenweiskopf.lpm.database.TodosDatasource;

import de.thorstenweiskopf.lpm.model.Project;

import de.thorstenweiskopf.lpm.model.ToDo;

import de.thorstenweiskopf.lpm.R;

import android.os.Bundle;

import android.app.Activity;

import android.content.Intent;

import android.graphics.Color;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.EditText;

import android.widget.ListView;

import android.widget.Toast;

import android.widget.AdapterView.OnItemClickListener;

public class ProjectView extends Activity {

ArrayAdapter<Project> adapter; //Adapter to fill the P

//Variablen der Projekte Liste

public static List<Project> values = new ArrayList<Project>();

int selectedItem = -999;

private ProjectDatasource datasource; //Schnittstelle zur Datenbank

/*

* (non-Javadoc)

* @see android.app.Activity#onCreate(android.os.Bundle)

* wird aufgerufen wenn android Activity anzeigen soll

*/

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_project_view);

datasource = new ProjectDatasource(this);

showValuesFromDB();

}

/*

* Methode holt sich Projekte aus DB

* und setzt vorhandene Values in die Liste

*/

private void showValuesFromDB() {

values.clear();

try {

datasource.open();

values = datasource.getAllProjects();

datasource.close();

Page 53: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

53

} catch (Exception ex) {

Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG).show(); //Fehler

ausgabe ToDo: Überschreiben mit eigenem Fehlertext

}

adapter = new ArrayAdapter<Project>(this,

android.R.layout.simple_list_item_1, android.R.id.text1, values);

// Assign adapter zur ListView

ListView listView = (ListView) findViewById(R.id.listView1);

listView.setAdapter(adapter);

/*

* Setze Onclicklistner auf die ListView um projekte auswählen zu könnnen.

*/

listView.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView<?> parent, View view,

int position, long id) {

selectedItem = position; // the choosen one

// change bgcolor of the selected item

for (int a = 0; a < parent.getChildCount(); a++) {

parent.getChildAt(a).setBackgroundColor(Color.WHITE);

}

view.setBackgroundColor(Color.GRAY);

openOptionsMenu();

}

});

}

/*

* (non-Javadoc)

* @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)

* OptionsMenuStuff

*/

@Override

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.activity_project_view, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

if (item.getItemId() == R.id.addpj) {

ListView listView = (ListView) findViewById(R.id.listView1);

listView.setAdapter(adapter);

// show the add view -> No Activity just a "Formular" Layout to switch into

setContentView(R.layout.additem);

} else if (item.getItemId() == R.id.removepj) {

if (selectedItem != -999) {

Project project = adapter.getItem(selectedItem);

selectedItem = -999;

try {

datasource.open();

datasource.removeProject(project);

datasource.close();

} catch (Exception ex) {

Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG)

.show();

}

Page 54: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

54

// show the main view

setContentView(R.layout.activity_project_view);

showValuesFromDB();

} else {

Toast.makeText(this, "Please choose a Item from List",

Toast.LENGTH_LONG).show();

}

} else if (item.getItemId() == R.id.showTodos) {

//Intent nutzen um andere Activity zu starten und Werte zu übergen

Intent i = new Intent(this, MyTodosOverview.class);

Project project = adapter.getItem(selectedItem);

i.putExtra("ProjectId", project.getId());

i.putExtra("ProjectName", project.getName());

startActivity(i);

} else if (item.getItemId() == R.id.timemanager){

if (selectedItem != -999) {

Intent i = new Intent(this, TimeManager.class);

Project project = adapter.getItem(selectedItem);

i.putExtra("ProjectId", project.getId());

i.putExtra("ProjectName", project.getName());

i.putExtra("workingtime", project.getTime());

startActivity(i);

} else {

Toast.makeText(this, "Please choose a Item from List",

Toast.LENGTH_LONG).show();

}

}

return super.onOptionsItemSelected(item);

}

/*

* Method of the Formular Layout additem.xml

* Beschrieben im Layout als AddClick

*/

public void AddClick(View view) {

if (view.getId() == R.id.button1) {

EditText text = (EditText) findViewById(R.id.editText1);

// values.add(text.getText().toString());

// put the new value in the database

try {

datasource.open();

datasource.creatProject(text.getText().toString());

datasource.close();

} catch (Exception ex) {

Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG).show();

}

// show the main view

setContentView(R.layout.activity_project_view);

showValuesFromDB();

}

}

}

Page 55: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

55

TimeManager.java

package de.thorstenweiskopf.lpm;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Calendar;

import java.util.Date;

import java.util.List;

import android.app.Activity;

import android.app.DatePickerDialog;

import android.app.TimePickerDialog;

import android.app.DatePickerDialog.OnDateSetListener;

import android.app.TimePickerDialog.OnTimeSetListener;

import android.os.Bundle;

import android.view.Menu;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.DatePicker;

import android.widget.TextView;

import android.widget.TimePicker;

import android.widget.Toast;

import de.thorstenweiskopf.lpm.database.ProjectDatasource;

import de.thorstenweiskopf.lpm.database.TimeTableDatasource;

import de.thorstenweiskopf.lpm.dialogfragments.DatePickerFragment;

import de.thorstenweiskopf.lpm.dialogfragments.TimePickerFragment;

import de.thorstenweiskopf.lpm.model.TimeEntry;

import de.thorstenweiskopf.lpm.R;

import android.support.v4.app.FragmentActivity;

//Fragmentactivity weil neu mit FragmentDialogen gearbeitet werdeb muss

public class TimeManager extends FragmentActivity {

//Buttons für Datum und Zeit

private Button btnChangeTime, btnChangeDate;

//Datum und Zeit Objekte

//Kalender Objekt wird erzeugt und geändert vom Time und Datepicker bei Änderungen

Calendar calendar = Calendar.getInstance();

final SimpleDateFormat date_format = new SimpleDateFormat("dd.MM.yyyy");

final SimpleDateFormat time_format = new SimpleDateFormat("HH:mm");

final SimpleDateFormat datetime_format = new SimpleDateFormat("dd.MM.yyyy HH:mm");

//Projektdaten

private String projectname;

private long projectid;

private float workingtime_frompj;

//DB Schnittstelle

private TimeTableDatasource datasource;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_time_manager_view);

Page 56: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

56

//get the datasourceobject needed

datasource = new TimeTableDatasource(this);

setTimeOnView(calendar);

setDateOnView(calendar);

addTimeandDateButtonListners();

}

/*

* (non-Javadoc)

* @see android.support.v4.app.FragmentActivity#onStart()

* Wird die App hier in den Hintergrund gelegt bleibt aber aktiv

* und kommt wieder in den Vordergrund so wird diese Methode ausgeführt

* Sie holt sich das aktuelle Projekt und Zeigt die Zeit an da Diese Daten mitlerweile

* nicht mehr in der View gespeichert sind. //onStart() in onResume() geändert

*/

@Override

protected void onResume() {

super.onStart();

getProject();

showWorkingTime();

}

/*

* Hildmethode: Errechnet die Arbeitszeit des Projektes wenn möglich

* und Schreibt sie in die Datenbank. In die ProjekteTabelle.

* Wird nach jedem ein uns ausbuchen ausgeführt.

*/

private boolean CalcWorkingTime(){

//Get the bookings, show 0 if no bookings are available

List<TimeEntry> entrys = new ArrayList<TimeEntry>();

long worktime =0;

try {

datasource.open();

entrys = datasource.getAllTimeEntrysFromProject(String.valueOf(projectid));

} catch (Exception ex) {

Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG).show();

}

if (entrys ==null | entrys.isEmpty()){

//Do NOTHING

return false;

} else {

//Read the in and outs

List <TimeEntry> in_entrys = new ArrayList<TimeEntry>();

List <TimeEntry> out_entrys = new ArrayList<TimeEntry>();

for (int i=0; i< entrys.size();i++ ){

if (entrys.get(i).getEntrytype() == 0){

in_entrys.add(entrys.get(i));

} else if (entrys.get(i).getEntrytype() == 1){

out_entrys.add(entrys.get(i));

}

}

//check if as many ins as outs

if (in_entrys.size() == out_entrys.size()){

for (int i=0; i< in_entrys.size();i++ ){

Page 57: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

57

long checkout = out_entrys.get(i).getDatetime() ;

long checkin = in_entrys.get(i).getDatetime();

worktime += (checkout-checkin )/1000/60;

//Store in DB

ProjectDatasource pd = new ProjectDatasource(this);

pd.open();

pd.updateTime(projectid, worktime);

pd.close();

}

return true;

} else {

if (in_entrys.size() > out_entrys.size()){

TimeEntry lastTimeEntry = in_entrys.get(in_entrys.size()-1);

long time = lastTimeEntry.getDatetime();

Calendar c = Calendar.getInstance();

c.setTimeInMillis(time);

Toast.makeText(this, "Last checkin ("

+datetime_format.format(c.getTime())+") without checkout.", Toast.LENGTH_LONG).show();

return false;

} else {

TimeEntry lastTimeEntry = out_entrys.get(out_entrys.size()-

1);

long time = lastTimeEntry.getDatetime();

Calendar c = Calendar.getInstance();

c.setTimeInMillis(time);

Toast.makeText(this, "Last checkout ("

+datetime_format.format(c.getTime()) +") without checkin.", Toast.LENGTH_LONG).show();

return false;

}

}

}

}

/*

* Hilfmethode holt Arbeitszeit aus der ProjekteDB und zeigt sie an.

*/

private void showWorkingTime() {

String str_hours = "00";

String str_minutes = "00";

TextView tv = (TextView)findViewById(R.id.Text_ProjectTime);

ProjectDatasource pd = new ProjectDatasource(this);

pd.open();

workingtime_frompj = pd.getWorkingtime(projectid);

pd.close();

int h = (int) workingtime_frompj/60;

int minuten = (int)workingtime_frompj % 60;

if (h < 10){

str_hours = "0"+h;

}

if (minuten < 10){

str_minutes = "0"+minuten;

}

tv.setText("Workingtime in hours: " +str_hours+":"+str_minutes);

}

Page 58: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

58

/*

* Hilfsmethode: Setzt die Listner auf alle Buttons

* und führt jeweilige Hilfsfunktion aus

*/

private void addTimeandDateButtonListners() {

findViewById(R.id.button_date).setOnClickListener(new OnClickListener() {

public void onClick(View v) {

showDatePicker();

}

});

findViewById(R.id.button_time).setOnClickListener(new OnClickListener() {

public void onClick(View v) {

showTimePicker();

}

});

findViewById(R.id.button_checkin).setOnClickListener(new OnClickListener() {

public void onClick(View v) {

checkin();

}

});

findViewById(R.id.button_checkout).setOnClickListener(new OnClickListener() {

public void onClick(View v) {

checkout();

}

});

findViewById(R.id.button_hours).setOnClickListener(new OnClickListener() {

public void onClick(View v) {

justbookthetime();

}

});

}

/*

* Hilfsmethode bucht eingestelle Zeit als Stunde und Minute

* vom Calender Objetk

*/

public void justbookthetime(){

int hour = calendar.get(Calendar.HOUR);

int minutes = calendar.get(Calendar.MINUTE);

int time = hour*60+minutes;

//Store in DB

ProjectDatasource pd = new ProjectDatasource(this);

pd.open();

long wtime= pd.getWorkingtime(projectid);

wtime = time +wtime;

pd.updateTime(projectid, wtime);

pd.close();

Toast.makeText(this, "timebooking done", Toast.LENGTH_LONG).show();

showWorkingTime();

}

/*

* Hilfsmethode mach Einträge in die TimeTable

*/

public void checkin(){

long time = calendar.getTimeInMillis();

try {

Page 59: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

59

datasource.open();

datasource.creatTimeEntry(time, Long.toString(projectid),0);//0 for in

datasource.close();

Toast.makeText(this, "checkin done", Toast.LENGTH_LONG).show();

boolean newWorkingTime = CalcWorkingTime();

if (newWorkingTime){

showWorkingTime();

}

} catch (Exception ex){

Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG)

.show();

}

}

/*

* Hilfsmethode macht Einträge in die TimeTable

*/

public void checkout(){

long time = calendar.getTimeInMillis();

try {

datasource.open();

datasource.creatTimeEntry(time, Long.toString(projectid),1);//1 for out

datasource.close();

Toast.makeText(this, "checkout done", Toast.LENGTH_LONG).show();

boolean newWorkingTime = CalcWorkingTime();

if (newWorkingTime){

showWorkingTime();

}

} catch (Exception ex){

Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG)

.show();

}

}

/*

* Hilfmethode öffnet DatePicker mit aktuellem Datum

*/

private void showDatePicker() {

DatePickerFragment date = new DatePickerFragment();

/**

* Set Up Current Date Into dialog

*/

Calendar calender = Calendar.getInstance();

Bundle args = new Bundle();

args.putInt("year", calender.get(Calendar.YEAR));

args.putInt("month", calender.get(Calendar.MONTH));

args.putInt("day", calender.get(Calendar.DAY_OF_MONTH));

date.setArguments(args);

/**

* setze die RückkehrMethode wenn Datum ausgewählt wurde

*/

date.setCallBack(ondate);

date.show(getSupportFragmentManager(), "Date Picker");

}

/*

* Rückkehrmethode: Datum wurde ausgewählt vom Picker

Page 60: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

60

* setze Neue Daten im Calender und Zeige es an

*/

public OnDateSetListener ondate = new OnDateSetListener() {

public void onDateSet(DatePicker view, int year, int monthOfYear,

int dayOfMonth) {

calendar.set(year, monthOfYear, dayOfMonth);

setDateOnView(calendar);

}

};

/*

* Helpermethod opens Timepicker and set current time

*/

private void showTimePicker() {

TimePickerFragment timepicker = new TimePickerFragment();

/**

* Set Up Current Date Into dialog

*/

Calendar calender = Calendar.getInstance();

Bundle args = new Bundle();

args.putInt("minute", calender.get(Calendar.MINUTE));

args.putInt("hour", calender.get(Calendar.HOUR_OF_DAY));

timepicker.setArguments(args);

/**

* Set Call back to capture selected date

*/

timepicker.setOnCallBack(ontime);

timepicker.show(getSupportFragmentManager(), "Date Picker");

}

/*

* Helpermethod: Time was choosen from picker

*/

public OnTimeSetListener ontime = new OnTimeSetListener() {

public void onTimeSet(TimePicker view, int hour, int minute) {

calendar.set(Calendar.HOUR_OF_DAY, hour);

calendar.set(Calendar.MINUTE, minute);

setTimeOnView(calendar);

}

};

/*

* (non-Javadoc)

* @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)

* OptionsMenuStuff: Gibt es hier nicht!

*/

@Override

public boolean onCreateOptionsMenu(Menu menu) {

//getMenuInflater().inflate(R.menu.activity_time_manager, menu);

return true;

}

/*

* Hilfsmethode holt sich vom Intent die Werte

* und Erzeugt das Projekt und Zeigt den Namen in View an

*/

public void getProject(){

//Lable anzeigen

Bundle extras = getIntent().getExtras();

Page 61: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

61

if (extras == null) {

return;

}

// Get data via the key

projectname = extras.getString("ProjectName");

projectid = extras.getLong("ProjectId");

workingtime_frompj = extras.getLong("workingtime");

if (projectname != null) {

// Show projectname as lable

TextView lable = (TextView) findViewById(R.id.Text_ProjectLable);

lable.setText(projectname);

}

}

/*

* Hilfsfunktion zeigt Zeit im Button

*/

public void setTimeOnView(Calendar c){

Button time = (Button) findViewById(R.id.button_time);

time.setText("Uhrzeit: "+time_format.format(c.getTime()));

}

/*

* Hilfsfunktion zeigt Datum im Button

*/

public void setDateOnView(Calendar c){

Button date = (Button) findViewById(R.id.button_date);

date.setText("Datum: "+date_format.format(c.getTime()));

}

}

Page 62: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

62

MySQLiteHelper.java

package de.thorstenweiskopf.lpm.database;

import de.thorstenweiskopf.lpm.database.tables.ProjectTable;

import de.thorstenweiskopf.lpm.database.tables.TimeTable;

import de.thorstenweiskopf.lpm.database.tables.TodoTable;

import android.annotation.TargetApi;

import android.content.Context;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

@TargetApi(11)

public class MySQLiteHelper extends SQLiteOpenHelper {

private static final String DATABASE_NAME = "LittleProjectManager.db";

private static final int DATABASE_VERSION= 1;

/*

* Datenbank wird erstellt wenn

* sie noch nicht existiert mit diesem Namen

*/

@TargetApi(11)

public MySQLiteHelper(Context context) {

super(context, DATABASE_NAME, null, DATABASE_VERSION);

}

/*

* (non-Javadoc)

* @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)

* Wird automatisch aufgerufen wenn DB noch nicht existiert

* Es Werden alle benötigten Tabellen erstellt

*/

@Override

public void onCreate(SQLiteDatabase db) {

ProjectTable.onCreate(db);

TodoTable.onCreate(db);

TimeTable.onCreate(db);

}

/*

* (non-Javadoc)

* @see

android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)

* wird ausgeführt wen DB Version sich im Code ändert

*/

@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

TodoTable.onUpgrade(db, oldVersion, newVersion);

}

}

Page 63: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

63

ProjectDatasource.java

/*

* Klasse ist das DAO (Database Access Object)

* Erlaubt den Zugriff auf die Datenbank und bietet Methoden

* für das Abholen und Schreiben von Daten.

*/

package de.thorstenweiskopf.lpm.database;

import java.util.ArrayList;

import java.util.List;

import de.thorstenweiskopf.lpm.database.tables.ProjectTable;

import de.thorstenweiskopf.lpm.database.tables.TodoTable;

import de.thorstenweiskopf.lpm.model.Project;

import de.thorstenweiskopf.lpm.model.ToDo;

import android.content.ContentValues;

import android.content.Context;

import android.database.Cursor;

import android.database.SQLException;

import android.database.sqlite.SQLiteDatabase;

public class ProjectDatasource {

private SQLiteDatabase db;

private MySQLiteHelper dbhelper;

private String[] allCollums = {ProjectTable.COLUMN_ID, ProjectTable.COLUM_NAME,

ProjectTable.COLUM_WORKTIME};

public ProjectDatasource(Context context) {

dbhelper = new MySQLiteHelper(context);

}

/*

* Öffnet DB Verbindung

*/

public void open() throws SQLException {

db = dbhelper.getWritableDatabase();

}

/*

* Schließt DB Verbindung

*/

public void close() {

db.close();

}

/*

* Erstellt Projekt in der Datenbank

* @param name Projektname

* @return Project

*/

public Project creatProject(String name){

ContentValues values = new ContentValues();

Page 64: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

64

values.put(ProjectTable.COLUM_NAME, name);

values.put(ProjectTable.COLUM_WORKTIME, 0);

long insertId = db.insert(ProjectTable.TABLE_PJ, null, values);

Cursor cursor = db.query(ProjectTable.TABLE_PJ, allCollums,

TodoTable.COLUMN_ID+" = " +insertId, null, null, null, null);

cursor.moveToFirst();

return makeProjectFromCursor(cursor);

}

/*

* Entfernt Proket aus der Datenbank

* @param pj Projekt welches entfernt werden soll

*/

public void removeProject(Project pj){

long id = pj.getId();

System.out.println("Comment deleted with id: " + id);

db.delete(ProjectTable.TABLE_PJ, ProjectTable.COLUMN_ID

+ " = " + id, null);

}

/*

* Gibt Liste aller Projekte zurück

* @return ArrayList<Project>

*/

public List<Project> getAllProjects(){

List<Project> projectlist = new ArrayList<Project>();

Cursor cursor = db.query(ProjectTable.TABLE_PJ, allCollums, null, null, null, null,

null);

cursor.moveToFirst();

if (cursor.getCount() == 0){

return projectlist;

}

while (cursor.isAfterLast() == false){

Project pj = makeProjectFromCursor(cursor);

projectlist.add(pj);

cursor.moveToNext();

}

cursor.close();

return projectlist;

}

/*

* Hilfmethode: Macht aus dem cursor(dbeintrag) ein neues Projekt

* @param cursor: Db cursor

* @return Project

*/

private Project makeProjectFromCursor(Cursor cursor) {

Project pj = new Project();

pj.setId(cursor.getLong(0));

Page 65: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

65

pj.setName(cursor.getString(1));

pj.setTime(cursor.getLong(2));

return pj;

}

/*

* Trägt gesamte bisherige Arbeitszeit in die Tabelle ein

* @param projectid: Id des Projektes

* @param workingtime: arbeitszeit welche fürs Projekt in die DB soll

*/

public void updateTime(long projectid, long workingtime) {

ContentValues updateTime = new ContentValues();

updateTime.put(ProjectTable.COLUM_WORKTIME, Long.toString(workingtime));

db.update(ProjectTable.TABLE_PJ, updateTime, ProjectTable.COLUMN_ID+"=?", new

String[] {Long.toString(projectid)});

}

/*

* Gibt die Arbeitszeit zurück

* @param projectid: Id des Projektes

* @return Arbeitszeit

*/

public long getWorkingtime(long projectid) {

Cursor cursor = db.query(ProjectTable.TABLE_PJ, new String[]

{ProjectTable.COLUM_WORKTIME}, ProjectTable.COLUMN_ID+"=?", new

String[]{Long.toString(projectid)}, null, null, null);

cursor.moveToFirst();

return cursor.getLong(0);

}

}

Page 66: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

66

TimeTableDatasource.java

/*

* Klasse ist das DAO (Database Access Object)

* Erlaubt den Zugriff auf die Datenbank und bietet Methoden

* für das Abholen und Schreiben von Daten.

*/

package de.thorstenweiskopf.lpm.database;

import java.util.ArrayList;

import java.util.List;

import android.content.ContentValues;

import android.content.Context;

import android.database.Cursor;

import android.database.SQLException;

import android.database.sqlite.SQLiteDatabase;

import de.thorstenweiskopf.lpm.database.tables.TimeTable;

import de.thorstenweiskopf.lpm.model.TimeEntry;

public class TimeTableDatasource {

private SQLiteDatabase db;

private MySQLiteHelper dbhelper;

private String[] allCollums = {TimeTable.COLUMN_ID,TimeTable.COLUM_DATETIME,

TimeTable.COLUM_PJ_ID, TimeTable.COLUM_ENTRYTYPE};

public TimeTableDatasource(Context context) {

dbhelper = new MySQLiteHelper(context);

}

/*

* Öffnet DB Verbindung

*/

public void open() throws SQLException {

db = dbhelper.getWritableDatabase();

}

/*

* Schließt DB Verbindung

*/

public void close() {

db.close();

}

/*

* Erstellt TimeEntry in der Datenbank

* @param timeinms Zeit in Millisekunden

* @param pjid Projektid des betreffenden Projektes

* @param inOrOut 0 für einbuchen, 1 für ausbuchen

* @return TimeEntry Objekt

*/

public TimeEntry creatTimeEntry(long timeinms, String pjid, int inOrOut){

ContentValues values = new ContentValues();

values.put(TimeTable.COLUM_DATETIME, timeinms);

Page 67: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

67

values.put(TimeTable.COLUM_PJ_ID, pjid);

values.put(TimeTable.COLUM_ENTRYTYPE, inOrOut);

//in DB eintragen

long insertId = db.insert(TimeTable.TABLE_TIMETABLE, null, values);

//Eintrag holen

Cursor cursor = db.query(TimeTable.TABLE_TIMETABLE, allCollums,

TimeTable.COLUMN_ID+" = " +insertId, null, null, null, null);

cursor.moveToFirst();

return makeTimeEntryFromCursor(cursor);

}

/*

* Entfernt TimeEntry aus der Datenbank

* @param te TimeEntry welches entfernt werden soll

*/

public void removeTimeEntry(TimeEntry te){

long id = te.getId();

System.out.println("Comment deleted with id: " + id);

db.delete(TimeTable.TABLE_TIMETABLE, TimeTable.COLUMN_ID

+ " = " + id, null);

}

/*

* Gibt Liste aller TimeEntry aus DB zurück

* @return ArrayList<TimeEntry>

*/

public List<TimeEntry> getAllTimeEntrys(){

List<TimeEntry> timeentrys = new ArrayList<TimeEntry>();

Cursor cursor = db.query(TimeTable.TABLE_TIMETABLE, allCollums, null, null,

null, null, null);

cursor.moveToFirst();

if (cursor.getCount() == 0){

return timeentrys;

}

while (cursor.isAfterLast() == false){

TimeEntry entry = makeTimeEntryFromCursor(cursor);

timeentrys.add(entry);

cursor.moveToNext();

}

cursor.close();

return timeentrys;

}

/*

* Hilfmethode: Macht aus dem cursor(dbeintrag) ein neues TimeEntry

* @param cursor: Db cursor

* @return TimeEntry

*/

private TimeEntry makeTimeEntryFromCursor(Cursor cursor) {

TimeEntry timeentry = new TimeEntry();

timeentry.setId(cursor.getLong(0));

timeentry.setDatetime(cursor.getLong(1));

Page 68: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

68

timeentry.setPj_id(cursor.getLong(2));

timeentry.setEntrytype(cursor.getLong(3));

return timeentry;

}

/*

* Gibt Liste aller TimeEntry aus DB abhängig vom Projekt zurück

* @param projectid

* @return ArrayList<TimeEntry>

*/

public List<TimeEntry> getAllTimeEntrysFromProject(String projectid) {

List<TimeEntry> timeentrys = new ArrayList<TimeEntry>();

Cursor cursor = db.query(TimeTable.TABLE_TIMETABLE, allCollums,

TimeTable.COLUM_PJ_ID +" = "+projectid, null, null, null, null);

cursor.moveToFirst();

if (cursor.getCount() == 0){

return timeentrys;

}

while (cursor.isAfterLast() == false){

TimeEntry entry = makeTimeEntryFromCursor(cursor);

timeentrys.add(entry);

cursor.moveToNext();

}

cursor.close();

return timeentrys;

}

}

Page 69: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

69

TodosDatasource.java

package de.thorstenweiskopf.lpm.database;

import java.util.ArrayList;

import java.util.List;

import de.thorstenweiskopf.lpm.database.tables.TodoTable;

import de.thorstenweiskopf.lpm.model.ToDo;

import android.content.ContentValues;

import android.content.Context;

import android.database.Cursor;

import android.database.SQLException;

import android.database.sqlite.SQLiteDatabase;

public class TodosDatasource {

private SQLiteDatabase db;

private MySQLiteHelper dbhelper;

private String[] allCollums = {TodoTable.COLUMN_ID,TodoTable.COLUM_TODO,

TodoTable.COLUM_PJ_ID};

public TodosDatasource(Context context) {

dbhelper = new MySQLiteHelper(context);

}

/*

* Öffnet DB Verbindung

*/

public void open() throws SQLException {

db = dbhelper.getWritableDatabase();

}

/*

* Schließt DB Verbindung

*/

public void close() {

db.close();

}

/*

* Trägt ToDo in die Tabelle ein

* @param projectid: Id des Projektes als Fremdschlüssel

* @param todo: ToDo selbst als String

* @return ToDo Objekt welches eingetragen wurde

*/

public ToDo creatTodo(String todo, String pjid){

ContentValues values = new ContentValues();

values.put(TodoTable.COLUM_TODO, todo);

values.put(TodoTable.COLUM_PJ_ID, pjid);

//in DB eintragen

long insertId = db.insert(TodoTable.TABLE_TODO, null, values);

//Eintrag holen

Cursor cursor = db.query(TodoTable.TABLE_TODO, allCollums,

TodoTable.COLUMN_ID+" = " +insertId, null, null, null, null);

cursor.moveToFirst();

Page 70: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

70

return makeTodoFromCursor(cursor);

}

/*

* Entfernt ToDo aus der Datenbank

* @param todo ToDo welches entfernt werden soll

*/

public void removeTodo(ToDo todo){

long id = todo.getId();

System.out.println("Comment deleted with id: " + id);

db.delete(TodoTable.TABLE_TODO, TodoTable.COLUMN_ID

+ " = " + id, null);

}

/*

* Gibt Liste aller ToDos zurück

* @return ArrayList<ToDo>

*/

public List<ToDo> getAllTodos(){

List<ToDo> todolist = new ArrayList<ToDo>();

Cursor cursor = db.query(TodoTable.TABLE_TODO, allCollums, null, null, null, null,

null);

cursor.moveToFirst();

if (cursor.getCount() == 0){

return todolist;

}

while (cursor.isAfterLast() == false){

ToDo todo = makeTodoFromCursor(cursor);

todolist.add(todo);

cursor.moveToNext();

}

cursor.close();

return todolist;

}

/*

* Hilfmethode: Macht aus dem cursor(dbeintrag) ein neues ToDo

* @param cursor: Db cursor

* @return ToDo

*/

private ToDo makeTodoFromCursor(Cursor cursor) {

ToDo todo = new ToDo();

todo.setId(cursor.getLong(0));

todo.setTodo(cursor.getString(1));

todo.setPj_id(cursor.getLong(2));

return todo;

}

/*

* Gibt Liste aller ToDo aus DB abhängig vom Projekt zurück

Page 71: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

71

* @param projectid

* @return ArrayList<ToDo>

*/

public List<ToDo> getAllTodosFromProject(String projectid) {

List<ToDo> todolist = new ArrayList<ToDo>();

Cursor cursor = db.query(TodoTable.TABLE_TODO, allCollums,

TodoTable.COLUM_PJ_ID +" = "+projectid, null, null, null, null);

cursor.moveToFirst();

if (cursor.getCount() == 0){

return todolist;

}

while (cursor.isAfterLast() == false){

ToDo todo = makeTodoFromCursor(cursor);

todolist.add(todo);

cursor.moveToNext();

}

cursor.close();

return todolist;

}

}

Page 72: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

72

ProjectTable.java

/*

* Klasse stellt die Tabelle myprojects dar

* in der Datenbank gespeichert wird

*/

package de.thorstenweiskopf.lpm.database.tables;

import de.thorstenweiskopf.lpm.database.MySQLiteHelper;

import android.database.sqlite.SQLiteDatabase;

import android.util.Log;

public class ProjectTable {

// Database table

public static final String TABLE_PJ = "myprojects";

public static final String COLUMN_ID = "_id";

public static final String COLUM_NAME = "name";

public static final String COLUM_WORKTIME = "worktime";

//SQL CREATE Statement

private static final String TABLE_CREATE_MYPROJECTS =""

+"create table " +TABLE_PJ +" ( "

+COLUMN_ID+ " integer primary key autoincrement, "

+COLUM_NAME +" text not null, "

+COLUM_WORKTIME +" integer"

+");";

/*

* Tabelle erstellen

*/

public static void onCreate(SQLiteDatabase db) {

db.execSQL(TABLE_CREATE_MYPROJECTS);

}

/*

* Tabelle Upgraden

*/

public static void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

Log.w(MySQLiteHelper.class.getName(),

"Upgrading database from version " + oldVersion + " to "

+ newVersion + ", which will destroy all old data");

db.execSQL("DROP TABLE IF EXISTS " + TABLE_PJ);

onCreate(db);

}

}

Page 73: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

73

TimeTable.java

/*

* Klasse stellt die Tabelle timetable dar

* in der Datenbank gespeichert wird

*/

package de.thorstenweiskopf.lpm.database.tables;

import android.database.sqlite.SQLiteDatabase;

import android.util.Log;

import de.thorstenweiskopf.lpm.database.MySQLiteHelper;

public class TimeTable {

// Database table

public static final String TABLE_TIMETABLE = "timetable";

public static final String COLUMN_ID = "_id";

public static final String COLUM_DATETIME = "datetime";

public static final String COLUM_PJ_ID = "pj_id";

public static final String COLUM_ENTRYTYPE = "entrytype";

//SQL CREATE Statement

private static final String TABLE_CREATE_TIMETABLE =""

+"create table " +TABLE_TIMETABLE +" ( "

+COLUMN_ID+ " integer primary key autoincrement, "

+COLUM_DATETIME +" integer not null, "

+COLUM_PJ_ID + " integer, "

+COLUM_ENTRYTYPE + " integer not null,"

+ " FOREIGN KEY ("+COLUM_PJ_ID+") REFERENCES

"+ProjectTable.TABLE_PJ+" ("+ProjectTable.COLUMN_ID+")"

+");";

/*

* Tabelle erstellen

*/

public static void onCreate(SQLiteDatabase db) {

db.execSQL(TABLE_CREATE_TIMETABLE);

}

/*

* Tabelle Upgraden

*/

public static void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

Log.w(MySQLiteHelper.class.getName(),

"Upgrading database from version " + oldVersion + " to "

+ newVersion + ", which will destroy all old data");

db.execSQL("DROP TABLE IF EXISTS " + TABLE_TIMETABLE);

onCreate(db);

}

}

Page 74: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

74

TodoTable.java

/*

* Klasse stellt die Tabelle mytodos dar

* in der Datenbank gespeichert wird

*/

package de.thorstenweiskopf.lpm.database.tables;

import de.thorstenweiskopf.lpm.database.MySQLiteHelper;

import android.annotation.TargetApi;

import android.content.Context;

import android.database.sqlite.SQLiteDatabase;

import android.util.Log;

public class TodoTable {

// Database table

public static final String TABLE_TODO = "mytodos";

public static final String COLUMN_ID = "_id";

public static final String COLUM_TODO = "todo";

public static final String COLUM_PJ_ID = "pj_id";

//SQL CREATE Statement

private static final String TABLE_CREATE_MYTODOS =""

+"create table " +TABLE_TODO +" ( "

+COLUMN_ID+ " integer primary key autoincrement, "

+COLUM_TODO +" text not null, "

+COLUM_PJ_ID + " integer,"

+ " FOREIGN KEY ("+COLUM_PJ_ID+") REFERENCES

"+ProjectTable.TABLE_PJ+" ("+ProjectTable.COLUMN_ID+")"

+");";

/*

* Tabelle erstellen

*/

public static void onCreate(SQLiteDatabase db) {

db.execSQL(TABLE_CREATE_MYTODOS);

}

/*

* Tabelle Upgraden

*/

public static void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

Log.w(MySQLiteHelper.class.getName(),

"Upgrading database from version " + oldVersion + " to "

+ newVersion + ", which will destroy all old data");

db.execSQL("DROP TABLE IF EXISTS " + TABLE_TODO);

onCreate(db);

}

}

Page 75: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

75

DatePickerFragment.java

/*

* Klasse muss als sogenantes DatePickerFragment geschrieben werden

* welche Ihrerseits bei der Erzeugung einen DatePickerDialog öffnet

* Den Rest übernimmt dann Das Framework bzw. die Activity welches

* diese Klasse mit Argumenten füttert und Ausführen lässt

*/

package de.thorstenweiskopf.lpm.dialogfragments;

import android.app.DatePickerDialog;

import android.app.DatePickerDialog.OnDateSetListener;

import android.app.Dialog;

import android.os.Bundle;

import android.support.v4.app.DialogFragment;

public class DatePickerFragment extends DialogFragment {

//Klassenvariablen

private int year, month, day;

OnDateSetListener ondateSet;

public DatePickerFragment() {

}

public void setCallBack(OnDateSetListener ondate) {

ondateSet = ondate;

}

/*

* (non-Javadoc)

*

* @see android.support.v4.app.Fragment#setArguments(android.os.Bundle)

* Methode um Daten zu setzen

*/

@Override

public void setArguments(Bundle args) {

super.setArguments(args);

year = args.getInt("year");

month = args.getInt("month");

day = args.getInt("day");

}

@Override

public Dialog onCreateDialog(Bundle savedInstanceState) {

return new DatePickerDialog(getActivity(), ondateSet, year, month, day);

}

}

Page 76: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

76

TimePickerFragment.java

/*

* Klasse muss als sogenantes TimePickerFragement geschrieben werden

* welche Ihrerseits bei der Erzeugung einen TimePickerDialog öffnet

* Den Rest übernimmt dann Das Framework bzw. die Activity welches

* diese Klasse mit Argumenten füttert und Ausführen lässt

*/

package de.thorstenweiskopf.lpm.dialogfragments;

import android.app.Dialog;

import android.app.TimePickerDialog;

import android.app.TimePickerDialog.OnTimeSetListener;

import android.os.Bundle;

import android.support.v4.app.DialogFragment;

public class TimePickerFragment extends DialogFragment {

//Klassen variablen

private int hour, minute;

OnTimeSetListener ontimeset;

public TimePickerFragment() {

}

public void setOnCallBack (OnTimeSetListener ontime){

ontimeset = ontime;

}

/*

* (non-Javadoc)

* @see android.support.v4.app.Fragment#setArguments(android.os.Bundle)

* Methode um Daten zu setzen

*/

@Override

public void setArguments(Bundle args) {

super.setArguments(args);

hour = args.getInt("hour");

minute = args.getInt("minute");

}

@Override

public Dialog onCreateDialog(Bundle savedInstanceState) {

return new TimePickerDialog(getActivity(), ontimeset, hour, minute, true);

}

}

Page 77: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

77

TimeEntry.java

/*

* Klasse stellt ein TimeEntry dar wie es

* in der Datenbank gespeichert wird

*/

package de.thorstenweiskopf.lpm.model;

public class TimeEntry {

private long datetime;

private int entrytype; //0 in 1 out

private long id;

private long pj_id;

public long getDatetime() {

return datetime;

}

public void setDatetime(long datetime) {

this.datetime = datetime;

}

public int getEntrytype() {

return entrytype;

}

public void setEntrytype(long entrytype) {

this.entrytype = (int) entrytype;

}

public long getId() {

return id;

}

public void setId(long id) {

this.id = id;

}

public long getPj_id() {

return pj_id;

}

public void setPj_id(long pj_id) {

this.pj_id = pj_id;

}

}

Page 78: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

78

ToDo.java

/*

* Klasse stellt ein ToDo dar wie es

* in der Datenbank gespeichert wird

*/

package de.thorstenweiskopf.lpm.model;

public class ToDo {

private String todo;

private long id;

private long pj_id;

public String getTodo() {

return todo;

}

public void setTodo(String todo) {

this.todo = todo;

}

public long getId() {

return id;

}

public void setId(long id) {

this.id = id;

}

public long getPj_id() {

return pj_id;

}

public void setPj_id(long pj_id) {

this.pj_id = pj_id;

}

//Rückgabewert des Objektes für die Liste

public String toString(){

return todo;

}

}

Page 79: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

79

R.java

/* AUTO-GENERATED FILE. DO NOT MODIFY.

*

* This class was automatically generated by the

* aapt tool from the resource data it found. It

* should not be modified by hand.

*/

package de.thorstenweiskopf.lpm;

public final class R {

public static final class attr {

}

public static final class drawable {

public static final int ic_action_search=0x7f020000;

public static final int ic_launcher=0x7f020001;

}

public static final class id {

public static final int Add=0x7f07000f;

public static final int Remove=0x7f070010;

public static final int Text_ProjectLable=0x7f070001;

public static final int Text_ProjectTime=0x7f070002;

public static final int addpj=0x7f07000b;

public static final int button1=0x7f07000a;

public static final int button_checkin=0x7f070005;

public static final int button_checkout=0x7f070006;

public static final int button_date=0x7f070003;

public static final int button_hours=0x7f070007;

public static final int button_time=0x7f070004;

public static final int editText1=0x7f070009;

public static final int listView1=0x7f070000;

public static final int removepj=0x7f07000d;

public static final int showTodos=0x7f07000c;

public static final int timemanager=0x7f07000e;

public static final int todo_lable=0x7f070008;

}

public static final class layout {

public static final int activity_project_view=0x7f030000;

public static final int activity_time_manager_view=0x7f030001;

public static final int activity_todos_view=0x7f030002;

public static final int additem=0x7f030003;

}

public static final class menu {

public static final int activity_project_view=0x7f060000;

public static final int activity_todos_view=0x7f060001;

}

public static final class string {

public static final int Add=0x7f040002;

public static final int Remove=0x7f040003;

public static final int app_name=0x7f040000;

public static final int menu_addpj=0x7f040008;

public static final int menu_remove_pj=0x7f04000a;

public static final int menu_settings=0x7f040007;

public static final int menu_showtodos=0x7f040009;

public static final int menu_timemanager=0x7f04000b;

public static final int menu_timestats=0x7f04000c;

public static final int time_checkinbutton=0x7f04000d;

public static final int time_checkoutbutton=0x7f04000e;

Page 80: Einführung in die Android Applikationsentwicklung

10. Januar

2013 APPLIKATIONSENTWICKLUNG FÜR ANDROID

80

public static final int time_hourbutton=0x7f04000f;

public static final int title_activity_my_todo_add=0x7f040004;

public static final int title_activity_my_todos_overview=0x7f040001;

public static final int title_activity_project_view=0x7f040005;

public static final int title_activity_time_manager=0x7f040006;

}

public static final class style {

public static final int AppTheme=0x7f050000;

}

}