Post on 25-Dec-2014
description
Mobile Anwendungen (38610)
Gruppe 4Karol Bronke, Daniel Frank,
Duygu Kücük, Tobias Weidinger
2
Agenda – Teil 1 (Business)• Marktanalyse
– Marktstatus und Entwicklung– Konkurrenzanalyse
• Kundenbedarf und -nutzen– Zielgruppe– Nutzen– Use Case– User Stories
• Finanzierung– Kosten– Erlösmodell
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
3
Agenda – Teil 1 (Business)• Vorgehen
– Aufgabenverteilung– Entwicklung– Projektstrukturplan
• Abschluss– Was muss noch gemacht werden?
• Lessons Learned– Was lief gut?– Was lief schlecht?
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
4
Agenda – Teil 2 (Entwicklung)• Graphical User Interface (GUI)
– Konzept– Aktivities– Elemente
• Applikation/Alerts
• Datenbank– Modell– Entwurfsmuster
• Global Positioning System (GPS)
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
5
Was ist todolo?
Applikation für die orts- und zeitabhängige Aufgabenverwaltung für Android-
Betriebssysteme
Namensfindung:to do list = todolocation = lo
6
Marktanalyse
Marktanteile mobiler Betriebssysteme weltweit Q3 2010 (Quelle: Gartner 2010, http://www.gartner.com/it/page.jsp?id=1466313)
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
7
Marktanalyse
Marktanteile mobiler Betriebssysteme weltweit Q3 2009(Quelle: Gartner 2010, http://www.gartner.com/it/page.jsp?id=1466313)
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
8
Marktanalyse
Marktanteile mobiler Betriebssysteme teamintern(Eigene Erhebung 2010)
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
9
Marktanalyse
Konkurrenzanalyse
• 3 Konkurrenzprodukte:– GeoNote von Jim McLaughlin -> Hauptkonkurrent– GeoNotes Lite von Hispamedia– GeoNotes: Location Based Notes von DroidSolutions
• Alle Versionen kostenlos verfügbar -> Werbung, Funktionseinschränkung
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
10
Marktanalyse
KonkurrenzanalyseGeoNote von Jim McLaughlin
Features:
• off / on function
• 2 default locations: Home and Work
• Edit Location: Name, Location, Notes
• Set Location: Location on Map, Current Location, Address
• Reminder: Display when leaving / arriving at location / one time only, Leaving distance (50 – 2000 meters), Arriving distance (100 meters)
• Sleep feature (preserve battery)
• Google Maps add-in
11
Marktanalyse
KonkurrenzanalyseGeoNotes Lite von Hispamedia
Features:
• New notes via phone menu
• Note: Name, Category, Description, Relevance
• Sort: sort by name, sort by category
• Geopositioning not allowed in trial version
• Google Maps add-in
12
Marktanalyse
KonkurrenzanalyseGeoNotes: Location Based Notes von DroidSolutions
Features:
• New notes via phone menu
• Note: Title, Address, Notify Close to Address, GeoNote
• Track movement start options: duration (now – 1 week), date/time
• Notification distance: 50 – 5000 feet
13
Marktanalyse
Konkurrenzanalyse (SWOT-Analyse)
• Stärken und Schwächen:
• Fokus liegt auf dem englischsprachigen Raum (Alle)
• Nicht alle Funktionen in den „Lite“-Versionen enthalten (2 Produkte)
• mangelnde Benutzerfreundlichkeit der Oberfläche (Alle)
• keine freie Adressbestimmung (2 Produkte)
• Google Maps-Anbindung (2 Produkte)
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
14
Marktanalyse
Konkurrenzanalyse (SWOT-Analyse)
• Chancen:
• Fokus auf dem deutschen Raum und Privatleuten
• keine eingeschränkte Version (nur Add-On!)
• benutzerfreundliche und seriöse Gestaltung der Oberfläche
• mehrere Möglichkeiten der Ortsbestimmung (GPS, textuelle Eingabe, Google Maps)
• Google Maps-Anbindung
• Ortszuweisung via Favoriten
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
15
Kundenbedarf und -nutzen
Zielgruppendefinition (soziodemographisch)
• Alter: Jugendliche und junge Erwachsenezwischen 18 und 40 Jahren
• Wohnort: Deutschsprachiger Raum(evtl. englisch)
• SozialeLage : Obere Mittelschicht
Oberes Bildungsniveau
Andere Nutzer werden nicht ausgeschlossen,sondern liegen nur nicht im Mittelpunkt unserer strategischen Ausrichtung.
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
16
Kundenbedarf und -nutzen
Zielgruppenbedürfnisse und Motivation
• Mobilitäthoch mobil und ständig unterwegs, sehr flexibelWunsch nach Sicherheit und einem geregelten Lebensverlauf
• Stressabbau durch Organisationstressiger und zeitlich straff geregelter Tagesablauf, handelt strukturiert nutzt Terminplaner und Notizfunktionen zur Alltagsbewältigung
• Trend- und Technikaffinität ist sehr stark technikaffin und besitzt hohe Medienkompetenz offen für neue Trends, probiert gern neues aus und ist experimentell
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
17
Kundenbedarf und -nutzen
Nutzenargumentation
• Ist-Zustand: Der Nutzer der definierten Zielgruppe vergisst häufiger Tätigkeiten zu erledigen wenn er an einem bestimmten Ort ist. Zudem könnte er zeit-unkritische Aufgaben an bestimmten Orten nebenbei erledigen, er denkt aber nicht daran.
• Soll-Zustand: Der Nutzer organisiert seinen Tagesablauf optimal. Er erledigt unwichtige Tätigkeiten nebenbei und spart sich doppelte Wege durch vergessene Aufgaben.
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
18
Kundenbedarf und -nutzen
Nutzenversprechen
Der zielgruppenentsprechende Nutzer kann Tätigkeiten nicht nur zeitabhängig, sondern zusätzlich auch ortsabhängig planen und verwalten. Er wird dann nicht nur durch Erreichen eines bestimmten Zeitpunktes, sondern auch bei der räumlichen Annäherung an einen bestimmten Ort daran erinnert. Dies spart dem Nutzer Zeit und Nerven.
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
19
Kundenbedarf und -nutzen
Nutzenversprechen
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
20
Kundenbedarf und -nutzenUse Case (Use Case-Diagramm)
21
Kundenbedarf und -nutzen
User Story (1)
Anja läuft durch die Königstraße und entdeckt im Schaufenster einer Boutique ein rotes Paar High Heels. Weil sie sich unsicher ist, möchte sie ihre Freundin Tanja, mit der sie geplant hat morgen Einkaufen zu gehen, um Rat fragen. Sie zückt ihr Smartphone, startet todolo und fügt eine neue Aufgabe hinzu. Dieser weist sie den aktuellen Standort zu und legt den Umkreis fest. Dann beendet sie todolo und geht nach Hause. Am nächsten Tag läuft sie mit Tanja durch die Stadt. Als sie sich in der Nähe der Boutique befinden, bekommt Anja eine Meldung auf dem Smartphone und wird an das Paar Schuhe in dem Schaufenster erinnert. Nun fragt sie Tanja um Rat.
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
22
Kundenbedarf und -nutzen
User Story (2)
Hannelore ist neu in der Stadt und kennt sich nicht gut aus. Sie kommt an einem Restaurant vorbei, von dem sie schon viel Gutes gehört hat. Da sie gerade gegessen hat, aber dort gerne Essen würde, erstellt sie sich mit todolo eine Erinnerung. Diese soll sie an das Restaurant erinnern, falls sie zufällig wieder in der Nähe ist.Einige Wochen später läuft sie zufällig in einer Parallelstraße des Restaurants und bekommt eine Meldung auf dem Display angezeigt. Zum Glück hat Hannelore diesmal Hunger und testet schließlich das Restaurant.
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
23
Finanzierung
Aufwand und Kosten
• Lohnkosten: 0€Alle vier Projektmitglieder verzichten auf Bezahlung
• Entwicklungskosten: 0€Ausschließlich Open-Source-Software und lizenzfreies Sekundärmaterial
• Equipment-Kosten: 0€Es wird das an der HdM zur Verfügung gestellte und eigene Equipment genutzt
• Vertriebskosten: ca. 25€Kosten für Einbindung in den Android Marketplace.
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
24
Finanzierung
PrivatKOSTENLOS
Werbefinanziert mit hoch effizientem Targeting:
• Ortsabhängig• Inhaltsabhängig
BusinessKOSTENPFLICHTIG
Zusätzliche Features:
• Ticket-System • Schnittstellen• Synchronisation
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
25
Finanzierung
Erlösmodell
• Kurzfristig (6 Monate – 1 Jahr):– Aufbau von Image durch (erfolgreiche) Verbreitung im Android Marketplace– Keine Maßnahmen zur Gewinnerzielung
• Langfristig (1 – 2 Jahre):– Werbeschaltung zur Gewinnerzielung– Business-Version zur Gewinnerzielung
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
26
Vorgehen1. Monat - Beginn
• Sammlung von Projektideen
• Aufteilung in Business (Markt-, Konkurrenzanalyse,…) – 2 Personen
• und Entwicklung (Klick-Prototyp,…) – 2 Personen
• Erstellung von Arbeitspaketen
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
27
Vorgehen2. Monat + 3. Monat - Entwicklung
• Aufteilung der Haupt-Arbeitspakete– Prototyp-Erstellung
• Einarbeitung / Entwicklung / Testing
• Fertigstellung der Entwicklungsschritte– Zusammenführen der Ergebnisse
• Weihnachtsferien!
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
28
Vorgehen4. Monat - Abschluss
• Zusammenführen der Ergebnisse– Bugfixing
• Vorbereitungen für die MediaNight– Präsentation / Poster– Funktionsfähige Applikation
• Abschluss der Entwicklung– Präsentation der Ergebnisse– Abgabe des Source-Code
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
29
Vorgehen
Entwicklung
• Aufteilung in Haupt-Arbeitspakete– GUI– Alert– Datenbank– GPS
• Eclipse als Entwicklungsumgebung + SVN + Redmine
• Detaillierte Informationen im zweiten Teil
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
30
Vorgehen (Projektstrukturplan)todolo
Projektziel:Ortsabhängige
Aufgabenverwaltung für Android-Betriebssysteme
GPS GUI Datenbank
GPS-Modul aktivieren /
deaktivieren
Ermittlung des aktuellen
Standorts per GPS
Google Maps-Anbindung
Optimierte GPS-Abfrage
Alert
Validierung von Nutzereingaben
Icons für Favoriten-Buttons
festlegen
Datenbank-Anbindung
implementieren (DAO)
Ortssuche via Google Maps
Entity-Relationship-
Modell
Alert bei Erreichen des Umkreises
Organisation
Quelltext kommentieren
Redmine-Tickets anlegen
Aufwand buchenSQL-Statements
Abschlusspräsentation vorbereiten
MediaNight-Präsentation vorbereiten
Business-Plan erstellen
Alert bei Erreichen des
Fälligkeitsdatums
GPS-Koordinaten speichern / Favoriten
hinterlegen
Optimierungen für Bildschrimgrößen
GUI-Design
Verantwortlichkeiten festlegen
Ideensammlung
31
Abschluss
Was muss noch getan werden?
• Entwicklung:– Beseitigung von kleineren Bugs– Testing– Sortierfunktion via Bewegungssensor implementieren
• Informationsrecherche zur Bereitstellung im Android Marketplace
• Langfristig: – Überlegungen hinsichtlich Werbeschaltung für kostenlose Version– Bedarfsanalyse hinsichtlich Business-Version– Neue Version mit erweitertem Funktionsumfang durch Feedbacks
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
32
Lessons Learned
Was lief schlecht?
• Kein strukturiertes Vorgehen, sondern direktes Programmieren -> Stichwort „Modellierung“
• Keine anfänglich detaillierte Zerlegung der Teilaufgaben
• Studium- und Zeitdruck -> geringer Fortschritt gegen Ende des Projektes
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
33
Lessons Learned
Was lief gut?
• Zusammenarbeit zwischen Teammitgliedern
• … durch regelmäßige Meetings / E-Mails / Redmine
• … trotz Erfahrungsdifferenzen
• Aufteilung der Aufgaben und Verantwortlichkeiten
• … selbständige Arbeitsweise ohne Zeitdruck
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
34
Agenda – Teil 2 (Entwicklung)• Graphical User Interface (GUI)
– Konzept– Aktivities– Elemente
• Applikation/Alerts
• Datenbank– Modell– Entwurfsmuster
• Global Positioning System (GPS)
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
35
GUIKonzept
• Tabs ähnlich einem Browser
• Listenansicht für Aufgaben
• Logischer Aufbau der Bearbeiten-Maske
• sprechende Icons
• Aussagekräftige Beschriftung, möglichst gering
• „as simple as possible“
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
36
GUIActivity
TabHost
TabWidget
ListView
ListItem
ImageView
TextView
CheckBox
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
37
GUIActivity
TabHost
TabWidget
ListView
ListItem
ImageView
TextView
CheckBox
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
38
GUIActivity
ScrollView
Textview
EditText
ImageButton
Spinner
Button
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
39
GUIActivity
MapView
EditTextButtonImagebutton
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
40
Applikation 1/2• Zwei-Schichten-Architektur
– Darstellung & Geschäftslogik– Datenzugriffschicht
• Plus Helferklassen• Aspekte einer
ereignisgetriebenen Architektur
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
Aplikation 2/2
ui• ActTab• TodoList• ActShowOpen• ActShowAll
• ActEdit• ActMap• LocationService
entity• Location• Task
util• Constants• ListAdapter• LocationNotFoundException• ProxAlert
dao• Dao
User Interface• 6 Activities• 1 Interface• 1 Service
Util• Constants
– Konstanten für den Application Context
• ListAdapter – Füllen und Anzeigen der
Aufgabenlisten– Aktionen auf
Listenelementen• LocationNotFoundException• ProxAlert
– Handhabung der Ereignisse
Ablauf bei Anlegen/Bearbeiten
ActTab ActShowAll ActEdit ActMap ActPos ActShowAll
Favorite Places@Overrideprotected Dialog onCreateDialog(int id) {
...switch (id) {…case CHOSE_EDIT_FAV_OPTIONS: {AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setMessage(getText(R.string.take_the_new_place_for_all_tasks_question)).setCancelable(false).setPositiveButton(
getText(R.string.yes),new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog,int id) { use_new_coordiinates_for_all_flag = true;location.setLatitude(lat);location.setLongitude(lng);Dao.getInstance(ActEdit.this).persist(location);}
}).setNegativeButton(getText(R.string.no), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {use_new_coordiinates_for_all_flag = false;Dao dao = Dao.getInstance(ActEdit.this); int favId = location.getFavoriteId();location.setFavoriteId(0);dao.persist(location);
location = new Location(lat, lng); location.setFavoriteId(favId); Log.v("FavId", "FavId " + favId); location = dao.persist(location); }});…
}
Für alle übernehmen
Neue Koordinaten bei bestehendem Ort
Nur für aktuellen Task
Ort wird Markierung „Favorit“ entzogen
Neuer Ort erhält Markierung
ActEdit
List Adapter 1/2public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;try {
if (view == null) {LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);view = vi.inflate(R.layout.list_item, null);
}final Task listItem = (Task) mList.get(position);if (listItem != null) {
((TextView) view.findViewById(R.id.tv_name)).setText(listItem.getText().length()>27?listItem.getText().substring(0, 28)+"...":listItem.getText());
((CheckBox) view.findViewById(R.id.checkbox)).setChecked(listItem.isDone()); switch (listItem.getLocation().getFavoriteId()) {
case 1: {((ImageView) view.findViewById(R.id.image))
.setImageResource(R.drawable.ic_fav_1home);break;
}case 2: {
((ImageView) view.findViewById(R.id.image)).setImageResource(R.drawable.ic_fav_2work);
break;}case 3: {
((ImageView) view.findViewById(R.id.image)).setImageResource(R.drawable.ic_fav_3shop);
break;}default: {
((ImageView) view.findViewById(R.id.image)).setImageResource(R.drawable.ic_compass);
break;}
}…
Definition eines Listeneintrags
Setzen des Icons
ActShowAll
List Adapter 2/2
((CheckBox) view.findViewById(R.id.checkbox)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
listItem.setDone(!listItem.isDone());
Dao dao = Dao.getInstance(mContext);
Task task = dao.getTaskById(listItem.getId());
task.setDone(listItem.isDone());
dao.updateTask(task);
String text = (listItem.isDone() ? mContext.getString(R.string.done_conf): mContext.getString(R.string.open_conf));
Toast.makeText(mContext, textToast.LENGTH_SHORT).show();
if(listItem.isDone()) {task.setConsumed(true);
Dao.getInstance(mContext).updateTask(task);}
TodoList showOpen = (TodoList) mContext;showOpen.fillListView();…
Update der gesamten Liste
Verhindern von Ereignissen
Aktualisieren des Status
Benachrichtigung des Nutzers
ActShowAll
Alert@Overridepublic void onReceive(Context context, Intent intent) {
long eventID = intent.getIntExtra(EVENTIDEXTRA, -1);
Dao dao = Dao.getInstance(context);Task task = dao.getTaskById((int)eventID);
if (task.isConsumed()) {return;}else {task.setConsumed(true);dao.updateTask(task);}
...
Ereignis kann ignoriert werden
Ereignis wird konsumiert
Setzen von ProximityAlerts
private void setProximityAlert(double lat, double lon, float radius, int eventID) {LocationManager locManager =
(LocationManager).getSystemService(Context.LOCATION_SERVICE);
Intent intent = new Intent("de.hdm.mobanwend.gruppe4.ui.PROXIMITYALERT");
intent.putExtra(ProxAlert.EVENTIDEXTRA, eventID);PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), eventID - 1, intent,PendingIntent.FLAG_CANCEL_CURRENT);
locManager.addProximityAlert(lat, lon, radius, -1, pendingIntent);}
Registrieren
Identifier
ActShowAll
Setzen von TimeAlertsprivate void setTimeAlert(int year, int month, int day, int hour, int minute, int eventID) {
Intent intent = new Intent("de.hdm.mobanwend.gruppe4.ui.PROXIMITYALERT");
intent.putExtra(ProxAlert.EVENTIDEXTRA, eventID);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,eventID + 10000, intent, PendingIntent.FLAG_CANCEL_CURRENT);AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);Calendar cur_cal = new GregorianCalendar();cur_cal.setTimeInMillis(System.currentTimeMillis());Calendar cal = new GregorianCalendar();cal.setTimeInMillis(System.currentTimeMillis());
cal.set(Calendar.YEAR, year);cal.set(Calendar.MONTH, month - 1);cal.set(Calendar.DAY_OF_MONTH, day);cal.set(Calendar.HOUR_OF_DAY, hour);cal.set(Calendar.MINUTE, minute);
long firstStart = cal.getTimeInMillis() - cur_cal.getTimeInMillis()+ SystemClock.elapsedRealtime();
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstStart,pendingIntent);
}
Zeit bis zum ersten Auslösen
Setzen des Alarms
Definition der Handlung
ActShowAll
51
Datenbank• SQLite Datenbank unter Android verwendet
• 2 Tabellen für Aufgaben und Orte
Task
ID INT PK
TEXT TEXT NN
LOCATIONID INT NN
DONE INT NN
RADIUS INT NN
DATETIME DATETIME
CONSUMED INT
Location
ID INT PK
LONGITUDE REAL NN
LATITUDE REAL NN
FAVORITID INT
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
52
Datenbank
Entwurfsmuster
• Singleton-Muster sichert zu, dass es nur eine Instanz einer Klasse gibt und bietet einen globalen Zugriffspunkt für die Instanz
• Data Access Object kapselt Zugriff auf Datenquelle, so dass Datenquelle ausgetauscht werden kann, ohne dass der Code verändert wird
• Entitäten verwendet um eindeutige Objekte zu bestimmen
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
53
DatenbankSingleton- Gehört zu den Creational Patterns- Verhindert, dass von einer Klasse mehr als ein Objekt
erzeugt werden kann- Üblicherweise global verfügbar- Wird verwendet wenn nur ein Objekt einer Klasse
existieren darf oder von dem einizgen Objekt Unterklassen gebildet werden
- Z.B. Protokollobjekt für die Ausgabe in einer Datei oder eben Datenbankzugriff
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
54
DatenbankSingleton
Vorteile (gegenüber globalen Variablen)
• Zugriffskontrolle lässt sich realisieren
• Spezialisierung durch Unterklassenbildunh möglich
• Welche Unterklassen verwendet werden, kann man zur Laufzeit entscheiden
• Die Einzelinstanz wird erzeugt wenn sie benötigt wird LAZY CREATION (spart Rechenzeit und Speicherbedarf)
• Falls man später doch mehrere Objekte benötigt, lässt sich dies einfach ändern
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
55
DatenbankSingleton
Nachteile
- Gefahr der Prozeduralisierung (statt Object-Orientiert zu arbeiten)
- Kopplung wird erhöht
- Abhängigkeiten zur Singleton Klasse werden verschleiert
- Thread-Safety muss zusätzlich implementiert werden (speziell bei Nebenläufigkeit und verteilten System)
- Testen teilweise schwieriger
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
56
DatenbankSingleton: Aufbau
1. Eine statische Variable des gleichen Typs
2. Einen privaten Konstruktor (von außen kann kein weiteres Objekt der Klasse erzeugt werden)
3. Eine Statische Methode, welche die Instanz zurück gibt
Der ganze Trick: Die Klasse verwaltet selbst seine Instanzen.
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
58
Datenbank
public static Dao getInstance(Context ctx) {if (instance == null) {instance = new Dao(ctx, Constants.DATABASE_NAME,
Task.DATABASE_TABLE, Task.DATABASE_VERSION);try { db = instance.getWritableDatabase();} catch (SQLiteException se) {… }db.execSQL(Task.TABLE_CREATE);db.execSQL(Location.TABLE_CREATE);
}return instance;
}
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
59
Global Positioning System (GPS)
Map-View (Layout)
<com.google.android.maps.MapView android:id="@+id/mapview" android:clickable="true" android:apiKey=„Unser apiKey" android:layout_below="@string/maps_suchbereich" android:layout_height="wrap_content" android:layout_width="fill_parent„android:layout_above="@string/maps_auswahlbereich"/>
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
60
Global Positioning System (GPS)
GPS (LocationManager)
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){ progDialog = ProgressDialog.show(ActPos.this, "Bitte warten...", "Position wird ermittelt...",
true, false);progDialog.setCancelable(true); mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 300000, 50, mlocListener);mlocManager.requestLocationUpdates(locationManager.NETWORK_PROVIDER, 300000, 50, mlocListener);getGPS(); }
else {showGPSDisabledAlertToUser(); }
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
61
Global Positioning System (GPS)
GPS (LocationListener)public class MyLocationListener implements LocationListener {public void onLocationChanged(Location loc) {int lon = (int) loc.getLatitude();int lat = (int) loc.getLongitude();…ActPos.this.mlocManager.removeUpdates(this); }
public void onProviderDisabled(String provider) {// TODO Auto-generated method stub }
public void onProviderEnabled(String provider) {// TODO Auto-generated method stub }
public void onStatusChanged(String provider, int status, Bundle extras) {// TODO Auto-generated method stub }
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
62
Global Positioning System (GPS)
GPS (GPS-Disabled-Dialog)private void showGPSDisabledAlertToUser(){AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);alertDialogBuilder.setMessage("GPS ist deaktiviert. Möchten Sie es aktivieren?").setCancelable(false).setPositiveButton("GPS aktivieren", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){Intent callGPSSettingIntent = new
Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);startActivity(callGPSSettingIntent); }});
alertDialogBuilder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener(){public void onClick(DialogInterface dialog, int id){finish(); }});
AlertDialog alert = alertDialogBuilder.create();alert.show(); }
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
63
Global Positioning System (GPS)
Ortssuche (Aktion bei Klick auf Such-Button)
searchButton.setOnClickListener(new OnClickListener() {
public void onClick (View arg0) {EditText location = (EditText)findViewById(R.string.ortssuche);String locationName = location.getText().toString();
progDialog = ProgressDialog.show(ActMap.this, "Bitte warten...", "Ort wird gesucht...", true, false);
findLocation(locationName); }});
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
64
Global Positioning System (GPS)
Ortssuche (findLocation)
private void findLocation(final String locationName) {Thread thrd = new Thread() {public void run() {try {//HintergrundprozessaddressList = geocoder.getFromLocationName(locationName, 5);
//leere Nachrichtzustellung um die Ergebnisse anzuzeigenuiCallback.sendEmptyMessage(0); }
catch (IOException e) {e.printStackTrace(); }}};
thrd.start(); }
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
65
Global Positioning System (GPS)
Ortssuche (findLocation - Ergebnis)
private Handler uiCallback = new Handler() {
public void handleMessage(Message msg) {
…
if(addressList != null && addressList.size() > 0) {int lat = (int)(addressList.get(0).getLatitude()*1000000);int lng = (int)(addressList.get(0).getLongitude()*1000000);
…
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
66
Global Positioning System (GPS)
Map-Marker (Marker setzen)
private void placeMarker(int lat, int lng) {Drawable marker = getResources().getDrawable(R.drawable.pushpin);marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight());myMapView.getOverlays().add(new InterestingLocations(marker, lat, lng)); }
private void CenterLocation(GeoPoint centerGeoPoint) {placeMarker(centerGeoPoint.getLatitudeE6(), centerGeoPoint.getLongitudeE6()); };
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
67
Global Positioning System (GPS)
Map-Marker (OverlayItem)
class InterestingLocations extends ItemizedOverlay<OverlayItem> {
private List<OverlayItem> locations = new ArrayList<OverlayItem>();private Drawable marker;private OverlayItem myOverlayItem;boolean MoveMap;
public InterestingLocations(Drawable marker, int lat, int lng) {super(marker);this.marker = marker;
GeoPoint myPlace = new GeoPoint(lat, lng);myOverlayItem = new OverlayItem(myPlace, "My Place", "My Place");locations.add(myOverlayItem);populate(); }…public void draw(Canvas canvas, MapView mapView, boolean shadow) {super.draw(canvas, mapView, shadow);boundCenterBottom(marker); }
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
68
Global Positioning System (GPS)
Map-Marker (Marker bewegen)
public boolean onTouchEvent(MotionEvent arg0, MapView arg1) {
int Action = arg0.getAction();if (Action == MotionEvent.ACTION_UP){
if(!MoveMap) {Projection proj = myMapView.getProjection(); GeoPoint loc = proj.fromPixels((int)arg0.getX(), (int)arg0.getY());
if (arg0.getAction() == 1) { GeoPoint p = arg1.getProjection().fromPixels((int) arg0.getX(),(int) arg0.getY());
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
69
Global Positioning System (GPS)
Map-Marker (Marker bewegen)
//Letzten Marker entfernenmyMapView.getOverlays().remove(0); CenterLocation(loc); }}
else if (Action == MotionEvent.ACTION_DOWN){MoveMap = false; }
else if (Action == MotionEvent.ACTION_MOVE){MoveMap = true; }
…
Karol Bronke, Daniel Frank, Duygu Kücük, Tobias Weidinger
Vielen Dank!
Gruppe 4Karol Bronke, Daniel Frank,
Duygu Kücük, Tobias Weidinger