snailmail

Eine Email-Client-App entwickeln

eine Maturarbeit von Noah Vogt & Simon Hammer

aus der Klasse 4cg

Betreungslehrkraft: Victor Yakhontov Koreferent: Daniel Bühler

Geschrieben im Jahr 2021 Gymnasium Kirschgarten, Basel-Stadt CH

Noah Vogt & Simon Hammer  INHALTSVERZEICHNIS

Inhaltsverzeichnis

Inhaltsverzeichnis 1

1 Vorwort 3

2 Einleitung 4

2.1 Arbeitskonzept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.1.1 Quellcode Modell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.1.2 Lizensierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.1.3 Philosophie (suckless) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.1.3.1 Hintergründe, Technologisch, UNIX, KISS . . . . . . . . . . . . . . . . . . 5

2.2 Arbeitsziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3 Arbeitsprozess 7 3.1 Programmiermittel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.2 Programmstruktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3.2.1 Hauptziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.2.2 Aufbau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.2.3 Startup UI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.2.4 Account Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.2.5 Recyclerviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3.2.6 Input Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.2.7 Datenbank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.2.7.1 MessageDao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.2.8 Repository/ViewModel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.2.9 Draft Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.2.10 Server Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3.3 Umsetzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.3.1 Bugs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.3.2 Probleme / Hiccups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.3.3 Kommunikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.3.4 Namensfindung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3.4 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4 Resultate 20 4.1 Vergleich mit unseren ursprünglichen Zielen . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.2 Vergleich mit der Konkurrenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.3 Vor- und Nachteile unserer App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4.3.1 Pro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.3.2 Kontra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 5 Selbstreflexion 22

5.1 Was Gut Lief . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 5.2 Was Schlecht Lief . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 5.3 Was Wir Gleich Machen Würden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 5.4 Was Wir Anders Machen Würden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 5.5 Abschliessende Persönliche Schlussfolgerung . . . . . . . . . . . . . . . . . . . . . . . . . . 23

6 Danksagung 23

7 Glossar 24

8 Literaturverzeichnis 27

9 Abbildungsverzeichnis 29

Anhang 30

Noah Vogt & Simon Hammer  1 VORWORT

1 Vorwort

Die Informatik ist heutzutage allgegenwärtig. Sie umfasst schon einen sehr grossen Teil unseres Alltags und der Anteil wächst immer weiter. Da ist es sinnvoll, sich eine Zeit mit der Informatik beschäftigt zu haben. Zur Informatik gehört natürlich auch das Programmieren. Die Fähigkeit zu Programmieren wird uns sicher in der Zukunft behilflich sein. Auch wenn es nur darum geht, einfache Prozesse im eigenen Alltag zu automatisieren, wird es hilfreich sein. Noah hatte schon länger grosses Interesse am Programmieren. Simon hingegen begann Interesse an den Programmiersprachen zu entwickeln, als die beiden im Unterricht Python lernten. Als die Zeit kam, sich für ein Maturthema zu entscheiden, war für ihn klar, er würde eine App programmieren. Anfangs ging es ihm darum, eine nützliche App zu kreieren, welche er selbst verbessern kann und seine Bedürfnisse perfekt abdeckt. Zu diesem Zeitpunkt störte es ihn, dass es keine effiziente Edubs-Mail-App fürs Smartphone gab und er wollte sie selbst kreieren. Da er aber wusste, dass er sich nicht so gut auskenne, fragte er bei Noah nach, wie er die Idee findet und ob er vielleicht mit ihm diese Arbeit angehen möchte. Da Noah schon länger keinen Email Client auf seinem Smartphone installiert hatte, weil ihm keine der gerade verfügbaren Apps gefiel, und er den Gedanken schon länger hatte, sich seinen eigenen Email Client zu programmieren, traf sich das sehr gut und die beiden konnten sich einigen. Also habe sie sich zusammen getan, um einen Email Client zu programmieren, der auch auf älteren Geräten ohne Schwierigkeiten läuft. Schliesslich hatten beide eher ältere Smartphones, ebenfalls sollte die App Freie Software sein. Dafür sprechen viele praktische und philosophischethische Gründe, aber dazu später mehr. Bei den Funktionen waren wir uns auch einig und wir hatten eine Menge Ideen, um einen vollumfänglichen Email Client zu erstellen. Der Name snailmail ist in einem Brainstorming aus der wörtlichen Übersetzung vom deutschen Wort Schneckenpost entstanden. Gedanke zu dem Design machten wir sie sich zuerst nicht, da sie es schlicht und funktional halten wollten. Sie hatten beide eine gewisse Vorstellung ihrer App und inwiefern wie sie diese bisher erreicht haben, wird sich im Laufe dieser Arbeit herausstellen.

Hiermit erklären wir, die vorliegende Maturaarbeit selbst verfasst (sowie das in der Arbeit beschriebene Produkt selbst gestaltet bzw. das beschriebene Projekt selbst durchgeführt) zu haben. Stellen, die wörtlich oder sinngemäss anderen Veröffentlichungen oder anderen Quellen, insbesondere dem Internet, entnommen sind, sind als solche eindeutig und wiederauffindbar erkenntlich gemacht. Alle diese Quellen sind vollständig und abschliessend im Literaturverzeichnis aufgeführt. Die vorliegende Arbeit ist in gleicher oder ähnlicher Form noch nicht veröffentlicht.

Datum: 18.10.21 Ort: Basel-Stadt

Simon Hammer  Noah Vogt

Noah Vogt & Simon Hammer  2 EINLEITUNG

2 Einleitung

2.1 Arbeitskonzept

2.1.1 Quellcode Modell

Um ein Programm zu programmieren, werden menschenlesbare Instruktionen in ein oder mehrere Textdateien geschrieben, die dann in Sprache, welche die Computerhardware interpretieren und ausführen kann, übersetzt.

Abbildung 1: Quellcode (engl. “source code”) wird in ausführbaren Maschinencode umgewandelt [SGF02]

Hier als Beispiel der Source Code zu einem simplen Programm helloworld.c geschrieben in der Programmiersprache C, welches in der Konsole ein simples “Hello World” ausgibt:

 1 #include <stdio.h>

2

 3 int main() {
 4  printf("Hello␣World\n");
 5  return 0;
 6 }

Ein Teil der kompilierten, ausführbaren Version des Programmes ./helloworld sieht aber so aus:

Gymnasium Kirschgarten  Seite 4

1 0011010001100000010111110110111101101100011001110110001001101111011011000110000101100100
2 1111101101111011101000111001101110010011000010101111100000000000000110100011100000111100
3 1101010110001100000000011011010110111101101100011100000111010001100101011001000110010100
4 0000010111001011111000000000000000000000011010010000000011001000101111101011111011011110
5 1100011001110110001001101111011011000110000101100100010111110110111101110100011100110111
6 0000000000000001101001001000001100001010111110111100001110101011001100101111101101110011

Wie zu sehen ist, geht bei diesem Prozess des Kompilierens die Lesbarkeit für den Menschen grösstenteils verloren. Um ein Programm ausführen zu können, braucht der Nutzer also keinen Zugang zum Quellcode. Doch wenn er wissen will, was das Programm macht - es könnte ihn ausspionieren oder andere bösartige Dinge im Hintergrund machen - oder einfach das Programm verändern will, braucht er unbedingt Zugang zum Source Code.

2.1.2 Lizensierung

Grundsätzlich gibt es die Unterscheidung zwischen freien Softwarelizenzen und proprietären Softwarelizenzen. Doch auch bei Open Source Software gibt es verschiedene Lizenzmodelle, welche gewählt werden können. Diese lassen sich ziemlich gut in zwei Kategorien unterteilen: in Permissive Softwarelizenzen und in Copyleft-Softwarelizenzen.

Die Autoren dieser App halten Copyleft Software in ethischer und praktischer Hinsicht für die beste Wahl bei der Softwarelizensierung. Weshalb entschieden wurde, für dieses Softwareprojekt die GNU General Public License (GPL) Version 3 [Sta07] der Free Software Foundation zu verwenden, da diese eine der bekanntesten, strengsten und somit effektivsten Copyleft-Lizenzen ist.

2.1.3 Philosophie (suckless)

Many (open source) hackers are proud if they achieve large amounts of code, because they believe the more lines of code they’ve written, the more progress they have made. The more progress they have made, the more skilled they are. This is simply a delusion.

— https://suckless.org Manifest [suc21]

Eine grosse Anzahl Open-Source-Entwickler sind stolz darauf, Software mit scheinbar möglichst vielen Features zu schreiben. Dies führt zu einer grossen Codebasis, die mit jedem Release grösser und grösser wird. Dadurch wird es schwieriger, die ständig wachsende Codebasis zu unterhalten. Es treten immer mehr Fehler auf, die Sicherheit und - vor allem - die Leistung leidet unter diesen Bedingungen. Dies führt zu einer Verschlechterung der Code-Qualität der Software, da es die gängige Praxis ist, “Zeit und Geld zu sparen”. [BGV20] Hier kommt nun die Suckless Philosphie ins Spiel: Sie zielt darauf ab, Software mit Hinblick auf Einfachheit zu entwickeln: Weniger Quellcodezeilen, um das Projekt nicht in ähnlicher Weise unüberschaubar zu machen, wie oben erwähnt. Diese Art zu programmieren ist viel schwieriger, aber der Aufwand ist es meistens wert. Diese Programmierphilosophie bietet auch Anreize für das qualitativ hochwertige Neuschreiben von Programmen, was bei der sogenannten Bloated Software [BGV20] viel seltener vorkommt, dazu gibt es dem Benutzer mehr Alternativen zur Auswahl.

2.1.3.1 Hintergründe, Technologisch, UNIX, KISS

Die Suckless Philosophie ist aber längst nicht die erste Philosophie im Softwarebereich, welche auf Simplizität beruht; so beispielsweise eine beliebte Definition der altbekannten UNIX Philosophy:

This is the Unix philosophy. Write programs that do one thing and do it well. Write programs to work together. Write programs that handle text streams, because that is a universal interface.

— A Quarter Century Of UNIX [Sal94]

Bekannt ist auch das KISS Prinzip: “Keep it simple, stupid”. Dieses Prinzip kommt ursprünglich vom U.S. Admiral Stroop, der das “Project KISS” 1960 ins Leben gerufen hatte, welches die Verlässlichkeit verbessern und die Kosten für amerikanische Militärausrüstungen senken soll. [DP09] Gerne wird dieses Prinzip zitiert, wenn jemand der Meinung ist, unnötige Komplexität sei vorhanden in einem Softwareprojekt.

Gymnasium Kirschgarten  Seite 6

2.2 Arbeitsziele

Wir wissen, was ein Email Client können muss, und haben nicht vor, eine App zu designen, welche vollkommen überladen ist mit Funktionen die keiner braucht.

Die App soll die Basisfunktionen eines klassischen Email Clients erfüllen. Dazu gehören das Lesen, Schreiben, Empfangen und Versenden von Emails, das Öffnen und Anfügen von Anlagen, die Setzung einer Email-Signatur und das Erstellen und Speichern von Entwürfen. Ebenso soll er verschiedene Ordner unterstützen, wie z.B. einen Spam/Junk oder einen Archiv Ordner. Dazu soll es möglich sein E-Mails visuell sortieren zu können, beispielsweise indem die Ordner im Client nach Datum des Empfangs oder dem Absender sortiert werden können. E-Mails sollen markiert, gelöscht und weitergeleitet werden können und es soll eine Suchfunktion für jeden Mailordner geben.

Ebenso soll es einen Account Manager geben, was voraus setzt, dass es möglich ist, sich mit verschiedenen Accounts anzumelden und diese bei Bedarf zu wechseln. Beim Anmelden einer E-Mail, soll es dem Nutzer leicht gemacht werden, mit eingebauten Konfigurationen für beliebte Emailprovider in der Schweiz. Darunter diese Anbieter: stud.edubs.ch, gmail.com, gmx.ch, outlook.com, yahoo.com, icloud.com, hotmail.com, web.de.

Ein Element, welches fast jede App heutzutage besitzt, sind Pushnachrichten, welche auch eingebaut werden sollen. Dabei sollen neue Nachrichten mit dem Absender und dem Beginn der E-Mail angezeigt werden. Dies soll ein weiteres Feature der App sein. Wie es für leichte Email-Clients oft üblich ist, werden Bilder erst angezeigt, sobald es der Nutzer ausdrücklich möchte. Dieses Verhalten soll in den App-Einstellungen steuerbar gemacht werden. Eine sehr praktische Funktion soll sein, dass E-Mail-Adressen gespeichert werden und beim Schreiben einer neuen E-Mail direkt verfügbar sind und ausgewählt werden können.

Das letzte Feature soll sein, dass Links direkt in einem Browser geöffnet werden können. Die Einstellungen sollen zudem das Farblayout der App, die Synchronisationsintervalle und Einstellungen an den Pushnachrichten ändern können, Kontaktlisten verwalten und Einstellungen zur Privatsphäre beinhalten. Im Unterschied zur Konkurrenz soll diese App so programmiert werden, dass sie alle nötigen Grundfunktionen für einen Email Client auf dem Smartphone beinhaltet, aber schneller starten soll als die Apps der Konkurrenz, weniger Speicherplatz und Ressourcen verbrauchen und nicht mit unnötigen Funktionen überladen sein soll.

Ein Pluginmanager soll auch eingebaut werden, um weitere Funktionen, welche das Programm verlangsamen würden oder nicht für jedermann geeignet sind, hinzufügen zu können. Es existiert natürlich auch die Möglichkeit, nach Abschluss dieser Arbeit die App zu verbessern und auf Nutzerwünsche anzupassen, doch hier wurden jetzt die ungefähren, geplanten Grundfunktionen genannt, um die Ziele der Funktionalität besser zu beleuchten. Es wurden viele Ziele gesetzt und es wurde angenommen, dass noch mehr erreicht werden kann. Weshalb dies nicht der Fall ist, wird noch genauer betrachtet.

Noah Vogt & Simon Hammer  3 ARBEITSPROZESS

3 Arbeitsprozess

3.1 Programmiermittel

Um ein Programm, mit grösserem Umfang zu entwickeln, ist es nützlich, Hilfsmittel zu verwenden, welche sich grössere Projekte spezialisiert haben. Eines dieser Hilfsmittel sind Version Control Systems. Diese sind eine sehr praktische Methode um Funktionen in ein Programm einzubauen ohne das Risiko, das Programm komplett Überarbeiten zu müssen, wenn eine einzige Funktion einen Fehler hervorruft. In diesem Fall wurde Git als VCS genutzt, um für jegliche Funktionen einen eigenen Branch zu erstellen und diesen wieder mit dem Hauptbranch zu mergen, wenn die Funktion fertig ist.[CS14a] [Lim20]

Abbildung 2: parallele Featureentwicklung mit Git [Raj]

Um zu zweit an einem Projekt gleichzeitig zu arbeiten, gibt es viel Möglichkeiten, sich das aktualisierte Projekt zur Verfügung zu stellen. Die “Einfachste” ist, sich das Projekt immer wieder zu mailen, wobei schon nur bei Textarbeiten dabei Probleme auftauchen können, weshalb bei diesem Projekt GitHub verwendet wurde. Über GitHub konnten die einzelnen Versionen des Programms, welche durch den Gebrauch von Git entstanden sind, geteilt werden. Auf GitHub ist das Programm öffentlich und wird dadurch auch quelloffen. Es kann aber nicht durch eine dritte Person ohne Einwilligung von Noah in den Source-Code des Programms geschrieben werden. Falls dies aber der Fall gewesen wäre, würde die dritte Person als mitwirkende Person auf GitHub aufgelistet werden. [Lim20]

Beim Programmieren einer Arbeit dieser Grösse, erweist es sich besonders nützlich, ein Integrated Development Environment zu verwenden. Es ist zu Android Studio gegriffen worden, weil sich dieses IDE speziell auf die Android Entwicklung spezialisiert hat. Android Studio besitzt viele Hilfsmittel, welche das Programmieren einer Androidapp erleichtern. Zum Beispiel ist der ”Visual Layout Editor” eine grosse Hilfe beim Designen. Android Studio bringt auch einen Compiler und einen Emulator mit sich, womit eine debug APK und eine release APK version der App erstellt werden kann. Um die App zu testen, wurde öfters ein debug APK File erstellt und auf einem Emulator aus Android Studio getestet. Mit Android Studio können auch Apps mit speziellen Keys unterzeichnet werden, damit sie im Google Play Store veröffentlicht werden können. Die App sollte aber nicht nur auf Emulatoren laufen, um auch das Gefühl des Designs besser zu empfinden oder den Gebrauch im Alltag zu testen, wurde die Android Debugging Bridge benutzt. Mit Android Studio können auch Daten über die Effizienz der App aufgenommen werden. [Deve]

Open-Source Programme wurden bei dieser Arbeit mehrmals genutzt, um gewisse Funktionen einzubauen und ein Gefühl für das Programmieren solcher Funktionen zu bekommen. Die Programme waren sehr hilfreich beim Lernen, da die Autoren teilweise noch gar keine Erfahrung in gewissen Bereichen hatten. Was genau aus diesen Programmen entnommen wurde und um welche Programme es sich handelt, wird genauer im Anhang besprochen.

3.2 Programmstruktur

3.2.1 Hauptziele

Gemäss den Zielen soll die App eine Verbindung mit einem Server erstellen und mit ihm interagieren können. Das heisst, sie soll die Informationen über einen Account, die der Nutzer eingibt, überprüfen können und weiter die Emails, die ein Nutzer auf einem Server hat, herunterladen. Ebenso soll die App Nachrichten weiter über einen Server verschicken können. Um das zu realisieren, haben sich die Autoren nach passenden libraries für Java umgeschaut. Das Resultat dieser Suche waren zwei Libraries.

Weil nach dem Herunterladen der Nachrichten vom Server viele Daten gespeichert werden müssen, muss eine Möglichkeit her, wie diese Daten möglichst schnell, und der Einfachheit halber mit einer gewissen Abstraktion, in einer sinnvollen Datenstruktur gespeichert werden können. Dazu taugte eine Database. Um dies zu erreichen, las sich einer der Autoren in ein Buch ein. Dieses Buch sollte ihm Aufschluss über das Erstellen einer Database geben.

Es wurde klar, dass eine Database für Android meist mit SQL oder SQLite geschrieben wird. Jedoch sind diese Sprachen nicht wirklich handlich und es liess sich auch nicht mit dem Zeitplan verknüpfen eine weitere Programmiersprache zu lernen, weshalb zu Room gegriffen wurde. Room ist eine abstrakte Klasse über SQLite und kann mit dieser kommunizieren. Mit ihr können SQL queries fast vollständig in Java geschrieben und ausgeführt werden. Ebenso ist Room für die Fehlersuche besser geeignet, weil es beim compilen der App die SQL queries und entities überprüft. [Raw19] Abbildung 3: Beispiel vom RecyclerView Damit die heruntergeladenen und gespeicherten Nachrichten auch angezeigt werden können, benötigt es ein Interface. Dieses sollte so schlicht und ordentlich wie möglich gehalten werden. Die Recyclerview Library ist eine optimale Möglichkeit, Daten in Form von Nachrichten als eine Auflistung zu zeigen. Sie bringt einen Vorteil gegenüber einer Liste mit und zwar verwendet sie Views wieder, die angezeigt wurden. Was dem Recyclerviewer einen Vorteil im Punkt Effizienz gegenüber der Liste bringt. [Deva] Neben der Recyclerview Library werden auch andere Bibliotheken gebraucht, um das User Interface zu erstellen. Einer dieser libraries ist Material oder Material Design. Den Autoren hat sie schlicht gefallen und sie ist nicht schwer zu benutzen, weshalb diese Library genutzt wurde. Sie ist nach ganz klaren Prinzipien aufgebaut und von Google erstellt worden, um hochwertige Designs zu kreieren. [Teab]

3.2.2 Aufbau

Die App kann grob in drei Teile unterteil werden. In User Interface, in Database und in Serververbindung. Abbildung 4: grober Aufbau der App Diese drei Komponenten bilden zusammen die App, wobei der Teil der Serververbindung nicht immer aktiv ist. Er wird von dem User Interface aufgerufen, wenn sich zum Beispiel ein neuer Nutzer mit einem Emailaccount anmelden möchte. Dann werden die Accountdaten an den Server geschickt und überprüft. Wenn diese korrekt sind, werden alle Nachrichten, die dieser Nutzer auf dem Server hat, heruntergela-den und weiter an die Database gegeben. Abgesehen von dem Speichern der Nachrichten, die frisch vom Server kommen, macht die Database nur noch zwei Dinge. Sie kann durch das Interface entstandene Nachrichten so abspeichern, dass sie vom User Interface im Ordner Draft angezeigt werden. Und die Database kann weiter gespeicherte Nachrichten so bearbeiten, dass sie vom User Interface in einem anderen Ordner angezeigt werden.

3.2.3 Startup UI

Abbildung 5: die Startup UI von snailmail

Wenn man die App startet, sieht man als allererstes die durchscrollbare Inbox (siehe mittleres Bild), hier mit vollkommen arbiträren Testdaten. Bei den 3 Menüpunkten soll im weiteren Verlauf der Entwicklung die Funk-

Gymnasium Kirschgarten  Seite 11

tionalität hinzugefügt werden, Emails zu sortieren und zu durchsuchen.

Wenn im Bild in der Mitte unten rechts das Pluszeichen angetippt wird, erscheint ein Fenster, wo man eine neue Email schreiben kann (Bild rechts). Man kann sie entweder versenden, oder als Entwurf speichern. Wenn der Nutzer sich mit einem Account angemeldet hat, wird die Adresse des Absenders - im Bild entspricht das dem Textfeld mit dem Platzhalter “From (Email)” - automatisch mit der aktuellen Email Adresse vervollständigt.

Wenn man im mittleren Bild oben links auf das sogenannte “Hamburgermenü” drückt, oder wie auf vielen anderen Apps auch von links nach rechts swiped (dt. streicht), erscheint der sog. “Drawer” (im Bild links ersichtlich). Dort sieht man den eingeloggten Account, die verschiedenen Mailboxen und ein paar Buttons, um zu den Einstellungen zu gelangen (unten links), einen neuen Email Account hinzuzufügen (unten Mitte) und um zum Account Manager zu gelangen (durchs Tippen auf das Profilbild). Dort kann auf eine andere Mailbox geklickt werden, sodass diese ausgewählt und geöffnet wird.

3.2.4 Account Management

Wenn man im Drawer den Add Email Button drückt, erscheint ein Pop-up Fenster, in dem man seine Anmeldedaten für ein neues Email Konto angeben kann. Da ein Mailserver aber auch von gewissen Standardeinstellungen, wie beispielsweise vom standardmässigen IMAP Port 993 (wie definiert von der Internet Engineering Task Force (IETF) in der IMAP Spezifikation rfc9051 [For]) abweichen kann, werden in diesem Fenster zuerst die Standardeinstellungen getestet, indem eine kurze Anfrage an den Server ausgeführt wird. Zuerst wird geschaut, dass nicht bereits ein Account mit der gleichen Email Adresse wie der zu Hinzufügende, wobei dann eine Meldung erscheint für den Nutzer. Dann werden die Anmeldedaten anschliessend mit der Funktion checkConnection überprüft, um zu überprüfen, ob man sich mit diesen zum Mailserver verbinden kann.

 1 def checkConnection(host, username, password, port):
 2  try:
 3  connection = imaplib.IMAP4_SSL(host, port)
 4  connection.login(username, password)
 5  connection.logout()
 6  return True
 7  except Exception as e:
 8  print("host:␣" + host)
 9  print("username:␣" + username)
 10  print("port:␣" + str(port))
 11  print(str(e))
 12  return False

Wenn die Anfrage erfolgreich ist, werden die Anmeldedaten in der App gespeichert. Wenn nicht, erscheint ein neues Dialogfenster, in welchem der Nutzer gefragt wird, ob er noch weitere Angaben angeben möchte, um diese dann testen zu können.

Wie schon in Punkt 3.2.3 erwähnt, muss man im Drawer auf das Profil klicken, um zum Account Manager zu gelangen, wo dann ein Dialogfenster erscheint. Zuerst wird der Benutzer vom Programm angewiesen mit der Nachricht “select Account” ein Konto im Drop-Down Menü auszuwählen. Dann kann er eine Aktion ausführen, indem er einen der korrespondierenden Knöpfe drückt, oder mit “exit”-Button das Dialogfenster wieder schliessen.

Abbildung 6: das Account Management

Der Nutzer kann entweder den ausgewählten Account löschen, zu ihm wechseln, oder seine Server Settings ändern. Beim Letzteren erscheint das gleiche Menü wie in den erweiterten Einstellungen, um einen neuen Account hinzuzufügen. Wenn der Nutzer seine neuen Mailservereinstellungen speichern will, wird zuerst geschaut, ob die App sich immer noch mit dem Mailserver verbinden kann. Wenn nicht, erscheint eine Fehlermeldung für den Nutzer und die neuen Angaben werden nicht gespeichert.

Zur Hilfe wird im Dialog des Account Managers die ganze Zeit zur Hilfe der aktuell aktive Account angezeigt. Nach jeder der Account Manager Aktionen werden immer noch diese Anzeige und die Textfelder im Drawer, wo der Nutzer seinen zur Zeit aktiven Email Account sehen kann, in Echtzeit aktualisiert.

3.2.5 Recyclerviewer

Wie im Kapitel “Hauptziele” schon angedeutet, braucht es einen Recyclerviewer um Nachrichten aufgelistet anzuzeigen. Ein Recyclerviewer ist in fünf grundlegende Teile aufgeteilt.

1. Das Recyclerview Objekt, welches ein Container ist und in das User Interface eingebaut wird. Es beinhaltet verschiedene Views, welche nochmals unterteilt werden können. In einer View wird in diesem Fall eine Nachricht eingebaut mit dem Absender, der Absendezeit, einem Betreff und dem Endsender der Nachricht.

2. Der Layoutmanager. Er ist für die Form einer einzelnen View verantwortlich. Der Layout manager kann auch wieder in drei Arten unterteilt werden. Der Linearlayoutmanager sorgt für eine Horizontale oder vertikale Unterteilung einer View. Hingegen führt der Gridlayoutmanager zu einer horizontalen und vertikalen Unterteilung der View. Für den Email-Client bietet er die beste Oberfläche, um Nachrichten darzustellen. Es gibt nämlich noch den den Staggeredgridlayoutmanager, welcher für eine versetzte Unterteilung der View sorgen kann. Dies ist aber für einen Email-Client unbrauchbar.

Abbildung 7: Layout Manager Recyclerview [Anoa]

3. Der View Holder beschreibt die Position einer View oder Metadaten innerhalb des Recyclerviewers.

4. Der Adapter ist wohl eines der wichtigsten Teile des Recyclerviewers. Er sorgt für das Erstellen des ViewHolder-Objekts und bindet auch die Daten aus der Database an den View Holder

5. Die Database ist das Herzstück dieser App und wird auch für den Recyclerviewer verwendet, um die Views mit den richtigen Informationen zu füllen. [Cod] [Devb]

Die Wahl des Layoutmanagers wurde sehr schnell getroffen. Es war klar, dass eine Nachricht nicht nur eine Information auf horizontaler Ebene anzeigen muss, sondern z.B. auch das Datum nicht versetzt angezeigt werden soll. Deshalb wurde der Gridlayout Manager gewählt.

Mit Hilfe eines Open-Source Programms, welches eine Demonstration eines Recyclerviewers war, haben sich die Autoren über diesen informiert. [Anob] Nachdem dieses Programm ausgetestet und beliebig modifiziert wurde, sollte es in die App eingebaut werden. Der erste Versuch scheiterte daran, dass die App abstürzte, ohne einen Error zu melden. Nach einiger Zeit war die beste Lösung wieder an einen Punkt zu gehen, an welchem die App noch funktionierte, nur ohne vollständigen Recyclerviewer. Es dauerte einen ganzen Monat bis eine weitere Version mit Recyclerviewer bereit war. Nur diesmal funktionierte die App.

3.2.6 Input Validation

Abbildung 8: Input Validation Bei den meisten Textfeldern, wo der Benutzer etwas eingeben kann und es sinnvoll gecheckt werden kann gibt es in snailmail eine Input Validation. Dort wird gecheckt, ob die Eingabe korrekt ist, also ob der Nutzer eine z.B. gültige Email Adresse eingegeben hat oder dass er ein Eingabefeld nicht leer lässt. Das Feld mit der falschen Eingabe wird rot markiert und der Nutzer weiss somit, an welcher Stelle er seine Eingabe korrigieren muss. Diese Praxis ist mittlerweile weitverbreitet und auf mobilen graphischen Oberflächen wurde diese von den Autoren als sinnvoll erachtet, weshalb sie auch in ihrer App davon Nutzen gemacht haben.

3.2.7 Datenbank

Ein relational database management system ist ein Datenbank-System, in welchem die Informationen als tables gespeichert werden. Ein table besteht aus Reihen und Spalten. Eine Reihe repräsentiert jeweils ein Object der Database und eine Spalte repräsentiert ein Wert eines Attributes. Im Fall dieser App gibt es 9 Attribute und einen Objectkey. [Ric01a]

Database Table

ObejctKey To  cc  bcc  from  date  subject textContent folder seen
01  Valentin null  null  Lennard 01.03.13 Schule Hallo Herr Draft  true

Der Objektkey wird dafür genutzt, das Objekt zu identifizieren und aufzurufen. Es können auch weitere Dinge mit dem Objektkey gemacht werden. Je nachdem, wie die Database eingelesen wird, kann am Objektkey festgestellt werden, zu welchem Zeitpunkt ein Objekt erstellt wurde. Bis auf seen und dem ObjektKey sind alle Attribute Strings.

To ist das Attribut, welches angibt, an wen die Email geschickt werden soll, From ist das genaue Gegenstück dazu. Cc und bcc sind die Email-Adressen, welche die Emails auch bekommen. Der einzige Unterschied ist, dass bei bcc diese Adressen nicht einsehbar sind und somit nicht bekannte ist, wer diese Email auch liest. Date gibt das Datum an, an welchem die Email verschickt wurde. Subject ist ein Betreff für die Email und textContent ist der Text, welcher in der Email verfasst wurde. Mit dem Attribut seen war geplant, es von false zu true wechseln zu lassen, wenn der Nutzer eine ungelesene Nachricht öffnet. Dazu sollte dann die Schriftart, in welcher die Nachricht im Recyclerviewer angezeigt wird, geändert werden. Leider hat diese Funktion es nicht in die App geschafft, aufgrund Zeitmangels und der eher geringen Wichtigkeit dieser Funktion. Dennoch wird sie sicher nach der Abgabe dieser Arbeit noch eingebaut.

Die Attribute To, from, date, folder und seen wurden im Databaseconstructor als @NonNull definiert. Das heisst, sie müssen eingelesen werden und können nicht null sein. Das macht soweit Sinn, weil eine Email bis auf seen nicht ohne diese Angaben versendet werden können und ohne zu wissen, in welchem Ordner die Email einzuordnen ist, kann die Email auch nicht richtig angezeigt werden.

Als Letztes gibt es noch das Attribut folder, es gibt an, von welcher Art die Email ist. Es gibt in der App fünf Ordner. Sie heissen Draft, Sent Inbox, Spam und Archive. Die Database kann nach einzelnen Attributen ausgelesen werden. So können die Emails mit den richtigen folder Attributen in den richtigen Ordnern angezeigt werden. Jeder Ordner hat sein eigenes Fragment, welches aufgerufen wird, wenn der Ordner ausgewählt wird. Wenn ein solches Fragment aufgerufen wird, wird auch die Database mit den richtigen Befehlen neu ausgelesen.

Abbildung 9: Room Struktur [Devh] Room ist eine Art Schicht über der SQLite database. Room besteht grundsätzlich aus drei Teilen. Die Database dient als Hauptzugriffspunkt für die gespeicherten Daten der App. Sie ist mit @Database markiert. Eine Entity repräsentiert einen table in der Database und die DAO Klasse beinhaltet die Methoden, um auf die Database zuzugreifen. Sie kommuniziert mit SQ-Lite, um den Zugriff auf die Daten zu ermöglichen. [Gar]

3.2.7.1 MessageDao

In der DAO-Klasse können SQL statements verwendet werden. Um auf die Database zuzugreifen und nur Gewisse Objekte zu erfassen, braucht es SQL. Mit diesen Codezeilen kann dann nach den Ordnern in der Spalte folder gesucht werden. SQL ist in diesem Fall sehr selbsterklärend, dennoch werden wir darauf eingehen.

 1  /* get Draft messages*/
 2  @Query("SELECT␣*␣FROM␣message_table␣WHERE␣folder␣LIKE␣'Draft'␣ORDER␣BY␣date␣ASC")
 3  LiveData<List<Message>> getDraftMessages();

Querys sind Anfragen an die Database nach Informationen. Sie können auf verschiedene tables zugreifen und Informationen abgleichen und auswählen. In einer DAO von Room werden die SQL-statements mit @Query markiert. SELECT heisst, dass etwas ausgewählt werden soll und mit * ist alles gemeint. Mit FROM wird angegeben von welchem table, in diesem Fall vom message table. Mit WHERE können Spalten der Entity ausgewählt werden. Hier wird die folder Spalte gewählt um mit LIKE ein Attribut zu bestimmen. So wird nun ein Attribut namens ’Draft’ gewählt. Mit ORDER By kann die Ausgabe noch sortiert werden. So wird die Ausgabe anhand der Spalte ’date’ aufsteigend sortiert. [Teaa] Dieses Query wird über das Repository und das Viewmodel, welche gleich erklärt werden, im Fragment Draft ausgeführt. Dieses Fragment wird aufgerufen, wenn der Nutzer auf den Ordner Draft drückt. Also ist es so, wenn dieser Ordner aufgerufen wird, wird die Database nach dem Wert ’Draft’ im Attribut folder abgefragt.

3.2.8 Repository/ViewModel

Abbildung 10: EmailViewModel and Reposito- ry [Devh] Damit die Database die Daten einlesen kann, braucht es eine Repository. Über das Repository werden normalerweise Daten aus aller Art von Datenquellen eingelesen. Jedoch werden in diesem Fall keine Daten vom Server direkt im Repository eingelesen, denn sie gehen zuerst über das Viewmodel. Weil das Herunterladen der Daten vom Mailserver leider erst sehr spät funktioniert hatte, haben sich die Autoren dazu entschlossen, das Einlesen der Daten über das Viewmodel zu machen. Dieses hat eine sehrähnliche Funktion,

Gymnasium Kirschgarten  Seite 17

es leitet die Daten ebenfalls weiter, nur gibt es LiveData zurück, was dazu führt, dass in der Mainactivity oder im entsprechenden Fragment ein Observer eingebaut werden kann. Dieser informiert die Klasse dann über Veränderungen in der Database, um sie dann im Recyclerviewer anzeigen zu lassen. [Devh]

Dies ist die Funktion, welche an einer Variable vom Typ EmailViewModel ausgeführt wird. In dem Fragment ’HomeFragment’ in der onCreateView Funktion, welcher immer ausgeführt wird wenn dieses Fragment aufgerufen wird.

1  mEmailViewModel = new ViewModelProvider(this).get(EmailViewModel.class);
2  mEmailViewModel.getInboxMessage().observe(getViewLifecycleOwner(), messages -> {
3  /* Update the cached copy of the messages in the adapter*/
4  adapter.submitList(messages);
5  });

Die Funktion getInboxMessage() ist in der Klasse EmailViewModel und EmailRepository definiert und gibt LiveData <List <Message >>zurück, was soviel ist wie eine Liste der Objekte in der Database, eingebettet in LiveData.

1  public LiveData<List<Message>> getInboxMessage(){ return mInboxMessage;}
1  private LiveData<List<Message>> mInboxMessage;

2

3  public EmailViewModel(Application application) {
4  super(application);
5  mEmailRepository = new EmailRepository(application);
6  mInboxMessage = mEmailRepository.getInboxMessages();
7  }

8

9  public LiveData<List<Message>> getInboxMessage(){ return mInboxMessage;}
1  private LiveData<List<Message>> mInboxMessage;

2

3  public EmailRepository(Application application) {
4  EmailRoomDatabase db = EmailRoomDatabase.getDatabase(application);
5  messageDao = db.messageDao();
6  mInboxMessage = messageDao.getInboxMessages();
7  }

8

9  public LiveData<List<Message>> getInboxMessages() {
10  return mInboxMessage;

11  }

Es ist ein Schlange, welche sich durch EmialViewModel und EmailRepository zieht. In den beiden Constructor wird etwa das gleiche gemacht. Im EmailRepository werden die Query aus dem MessageDAO ausgeführt, um die Daten in Variablen für jeden Ordner zu speichern. Und im EmailViewModel werden, durch Funktionen aus dem Repository die Variablen abgerufen und wieder neu gespeichert, um am Schluss diese Variablen in einem Fragment aufzurufen und dem Adapter gegeben, wie es am Anfang dieser Seite beschrieben wird.

3.2.9 Draft Messages

Abbildung 11: Email Writer Vorhin wurde beschrieben, wie Daten aus der Database ausgelesen werden, wie sie eingelesen werden und wie sie gespeichert werden. Jetzt wird kurz noch gezeigt, wann und wie Entwürfe unter dem Namen “Drafts” gespeichert werden.

Nachdem eine Nachricht geschrieben wurde, kann sie versendet werden oder auch gespeichert werden, wenn im Email Writer das Kreuz gewählt wird, wird der Nutzer gefragt, ob er die Nachricht abspeichern möchte. Wenn er die Nachricht speichern will, werden im MessageCreateFragment, welches dem Email Writer entspricht, die eingegebenen Informationen ausgelesen. Über einen Intent werden diese Informationen weiter an die MainActivity gesendet und dort mit dem Folder Attribut “Draft” in die Database eingelesen.

3.2.10 Server Connection

Abbildung 12: Diagramm Email Versand

Vereinfacht funktioniert der Versand von Emails wie im obigen Diagramm: Ein Nutzer, der eine Email versenden will, interagiert mit seinem Mail-Client und gibt durch ihn den Befehl, die Email zu versenden. Der Email Client verschickt die Mail an den SMTP Server des sendenden Nutzers, wo dieser zum SMTP Server des empfangenden Nutzers gelangt, von dort aus zu seinem IMAP oder POP3 Server. Wenn der Mail Client des Empfängers eine Anfrage an seinem SMTP / POP 3 macht, kann er diese einlesen und der Nutzer kann nun seine neue Email lesen.

Das Versenden von Mails wird in der App einzeln gemacht: Für jede zu sendende Email wird die Funktion sendStarttls (siehe folgend) aufgerufen. Zuerst wird der der SSL/TLS Kontext initialisiert, dann werden die Angaben der Mail zu einer korrekt kodierten und formatierten Nachricht umgewandelt und schliesslich mit der smtplib Bibliothek versendet.

 1 def sendStarttls(host, sendingMail, receivingMail, password, message="",
 2  subject="", port=587, cc=[], bcc=[]):
 3  context = ssl.create_default_context()

4

 5  if type(cc) is not str:
 6  cc = ",".join(cc)

 7  if type(bcc) is not str:
 8  bcc = ",".join(bcc)
 9  utf8Message = ("Subject:␣" + subject + "\nCC:␣" + cc + "\nBCC:␣" + bcc +
 10  "\n\n" + message)
 11  decoded = utf8Message.encode('cp1252').decode('utf-8')

12

 13  with smtplib.SMTP(host, port) as serverConnection:
 14  serverConnection.starttls(context=context)
 15  serverConnection.login(sendingMail, password)
 16  serverConnection.sendmail(sendingMail, receivingMail, decoded)

3.3 Umsetzung

3.3.1 Bugs

Programmierfehler schleichen sich in jedem Softwareprojekt ab einer gewissen Komplexitätsstufe ein. Damit hatten auch die Entwickler dieses Projektes zu kämpfen. Hier dazu ein kleines Beispiel:

Als der RecyclerViewer das erste Mal eingebunden werden konnte, ohne dass die App nach dem Öffnen direkt abstürzte, war das Problem, dass am oberen Teil des UI Inhalte abgeschnitten waren. Das konnte gelöst werden, indem diese Codezeile in der Datei app/src/main/res/layout/activity main.xml an der richtigen Stelle eingefügt wurde:

 1 android:paddingTop="50dp"

Es gab sehr viele Bugs, erst recht gegen Ende der Matur, weil dort erst die meisten Funktionen fertig wurden. Ein Bug, der bis Heute nicht gelöst werden konnte, ist das Löschen des Tables in der Database. Eigentlich sollte dies eine Leichtigkeit sein, dennoch war es den Autoren nicht möglich, ein einfaches Room/SQL statement zu finden, welches alle Informationen in der Database löscht.

Die Lösung zu diesem Problem hat leider auch einen Haken: Es muss jeder Ordner einmal ausgewählt werden, bevor alle Nachrichten gelöscht werden können. Die Lösung an sich war, dass, wenn einer der Ordner geöffnet wird, alle Nachrichten in diesem Ordner in einer Liste gespeichert werden. Wenn dann die Option ”Delete all Folder”gewählt wird, wird ein Loop gestartet, welcher durch die Liste geht und jede Nachricht einzeln ausgibt. Diese Nachricht wird weiter über Umwege an die MessageDAO Klasse gebracht und dort kann eine einzelne Nachricht gelöscht werden. Es ist eine umständliche Lösung und noch nichteinmal ausgereift. Dennoch besser, als wenn es nicht möglich wäre.

Vor kurzer Zeit war dieser Bug noch störender, denn die Nachrichten mussten auch gelöscht werden, wenn ein neuer Account angemeldet wurde. Jedoch konnte das umgangen werden, sobald der Account Manager aufkam. Mit diesem mussten die Nachrichten einfach auch nach dem Account abgerufen werden und die Nachrichten wurden nicht mehr gelöscht. Es wurden einfach nur die Richtigen angezeigt.

Die Autoren sind sich ziemlich sicher, dass es weitere Bugs in der App geben wird, da nicht genügend Zeit für das debugging eingeplant .

3.3.2 Probleme / Hiccups

Probleme waren die unnötig vielen Layouts, welche bei der App entstanden sind. Vielleicht hätten diese minimiert werden können, wenn die Entwickler eine signifikant höhere Erfahrung im Bereich der Android Entwicklung gehabt hätten, oder wenn die verschiedenen Inhalte beim Aufrufen weniger Layouts generieren würden, oder diese könnten besser wieder referenziert werden.

Mit gewissen Bibliotheken sind auch Probleme entstanden, dazu wird später in diesem Text noch das Problem mit den Email-Bibliotheken geschildert.

3.3.3 Kommunikation

Die Menge an Kommunikation hat sich eingependelt zwischen den Anforderungen, Bedürfnissen und sozialen Kapazitäten der beiden Autoren. Einer wollte eher etwas mehr Dialog, der andere weniger. Das gegenseitige Vertrauen war aber auch soweit vorhanden, dass man sicher sein konnte, dass der andere gewisse abgemachte Zeiten einhält und Nachrichten nicht unnötig lange unbeantwortet lässt.

Es konnten auch gute Strukturen für die Kommunikation geschaffen werden, so wurde eine diary, also eine Art Tage- oder Logbuch verwendet, um den Arbeitsprozess zu dokumentieren, was sich insbesondere bei den Anfängen des Projektes als nützlich herausstellte. Auf diesem Dokument und der Git Commit History basiert die Dokumentation dieser Arbeit.

Sowohl im Programm-Quellcode der App als auch im Quellcode dieser Arbeit haben die beiden Autoren Notizen in Form von Codekommentaren gemacht - teilweise sich sogar gegenseitig- voll nach dem Motto: “Hey, kannst du das dann dort noch einfügen? Du kannst das ja besser als ich.”

Auch haben sich die beiden zeitweise Montags zusammen hingesetzt um den Arbeitsprozess in dieser Weise zu besprechen und um die nächsten Aufgaben zu verteilen.

Insgesamt verlief die Kommunikation doch reichhaltig, obwohl einer der beiden Autoren doch etwasüberdurchschnittlich schwer digital erreichbar ist. Die grobe Aufteilung des Programmes, um daran zu entwickeln und die Komponenten wieder zusammenzufügen, hatte etwas von der typischen Modularität von Linux.

3.3.4 Namensfindung

Für die App musste auch noch ein Name her, doch die aller längste Zeit hatten die beiden Autoren entweder keine Idee oder der Name wurde schon von einer anderen App verwendet. Doch als einer der beiden Autoren seinen Vater nach Namensideen fragte, war einer der Vorschläge “Schneckenpost”. Dies ist natürlich eine offensichtliche ironische Anspielung darauf, dass unsere App schneller sein soll als die meisten Apps. Doch da ein englischer Name erwünscht war, wurde es einfach direkt übersetzt in “snail mail”. Nun war nur noch die Frage, wie man es darstellen sollte, etwa “SnailMail” (CamelCase), “snailMail” (mixedCase), “Snail Mail”,

Noah Vogt & Simon Hammer  4 RESULTATE

“snail mail” oder “snailmail”. Es wurde für das Letzteres entschieden, da dies das wichtigste Designkonzept der App am besten widerspiegelt: Die Einfachheit. Gleich wie die App lautet auch übrigens der Name des GitHub Repositorys der App:

https://github.com/noahvogt/snailmail

3.4 Testing

Zum Testen gibt es soweit nicht sehr viel zu sagen, da die Autoren fortlaufend das Programm ausprobiert haben und die Resultate direkt wieder in das Programm flossen. Es hätte keinen Mehrwert gehabt, die “Ergebnisse” solcher einfachen Tests zu dokumentieren. Wofür die Zeit leider nicht gereicht hat, war das richtige Testen der App im Alltag. Da die App noch nicht fertig ist und die neuste Version auch erst vor Kurzem entstand, konnte die App nicht an Bekannte gegeben werden und ein paar Tage getestet werden. Das Interface wurde zwar getestet aber darüber hinaus leider nicht viel.

4 Resultate

4.1 Vergleich mit unseren ursprünglichen Zielen

Das User Interface ist erfreulich gut im Einklang mit den ursprünglichen Zielen; es ist wirklich einfach ohne irgendwelchen unnötigen Schnickschnack. Simpel ist das GUI also, doch wie steht es mit der Bedienerfreundlichkeit? Dazu haben wir Freunde und Bekannte eingespannt, ihnen ein Handy mit der App in die Hand gedrückt und gesagt, sie sollen einen Mail Account einrichten, um dies herauszufinden. Dabei haben sich die meisten gut und schnell zurechtgefunden, obwohl die App ja noch nicht fertig ist.

Die App selber ist wie von uns in den Zielen vorgegeben Free Software. Doch erst kürzlich kam auf, dass die von diesem Projekt verwendete “chaquopy” Bibliothek proprietär ist, und somit indirekt ein Konflikt mit den ursprünglichen Zielen steht: Es wurde zwar nicht explizit angegeben, dass alle Bibliotheken zwingend auch Open Source sein sollen, doch es ist nicht im Sinne der Autoren eine nichtfreie Library zu verwenden. Im Laufe der weiteren Softwareentwicklung wird dieser Fehler noch unbedingt behoben werden müssen. Dieser Missstand ist auch teilweise dem Dependencymanagement von Gradle anzulasten, da dieser immer nur die binäre Version herunterlädt und der Source Code von Dependencies nirgends gescheit verlinkt ist.

Die wichtigsten Funktionen der App wurden erreicht, es können Emails geschrieben, gelesen werden, es bestehen verschiedene Mailboxen und jeder kann seine Email Accounts gut managen, also hinzufügen, ändern und entfernen. Gewisse Features, wie Pushnachrichten, Suchfunktionen, ein visuelles Attribut, wo zu sehen ist, ob eine Nachricht gelesen wurde, fehlen noch ganz. Funktionen wie die Einstellungen, das synchronisieren der Datenbank mit dem Mailserver und die Anhang Funktionalität sind noch nicht fertiggestellt. Es gibt auch noch gewisse Bugs bei der Entstehung von “edge cases” [Jos] bei bestimmten einzelnen Emails.

Noah Vogt & Simon Hammer  5 SELBSTREFLEXION

Ursprünglich wurde zusätzlich ein Pluginmanager - dabei angelehnt an die Funktionsweise von vim-plug [Cho] - geplant einzubauen, doch diese Idee wurde mittlerweile verworfen, da es weitaus sinnvoller und effizienter von den Autoren angesehen wurde, einfach klassische Patches zu verwenden. Ähnlich wie dies bei der suckless.org Software ist. [suc]

4.2 Vergleich mit der Konkurrenz

Es ist gar nicht so einfach, diese App zu vergleichen mit ihrer Konkurrenz, da sie noch nicht fertig entwickelt ist. Aus diesem Standpunkt heraus vergleichen wir nur die fertigen Funktionen mit der Konkurrenz.

Im Vergleich mit der Konkurrenz sticht die App heraus durch ihre simple Art, so wie das geplant war. Die Funktionalitäten sind dabei auch wesentlich rudimentärer, oder besser gesagt, mehr “suckless”, als die der Konkurrenz. Die Farben und das Layout des User Interface sollte zwar simpel sein, doch das visuelle Zusammenspielen von Farben und dem Layout haben gewisse Konkurrenzprodukte, welche immerhin auch von Fortune 500 Unternehmen entwickelt werden, zweifelsohne besser umgesetzt, als die Autoren dieser App.

4.3 Vor- und Nachteile unserer App

4.3.1 Pro

Für die Nutzung der App sprechen simple Nutzeroberfläche und Codebasis, welche nach Fertigstellung der initialen Entwicklung einer der besten simplen Email-Clients werden kann.

4.3.2 Kontra

Dagegen sprechen, dass gewisse Funktionen, welche laut den Autoren nicht in einen Email-Client gehören, nicht vorhanden sind, wie beispielsweise die Funktionalität eines eingebauten Kalenders, wie es der allseits bekannte Mailclient Thunderbird zu tun pflegt.[Moz]

5 Selbstreflexion

5.1 Was Gut Lief

Das Arbeiten mit Git als Version Control System verlief gut und half enorm beim Arbeitsprozess und dessen Strukturierung. Mit der Syntax der verwendeten Programmier- und Markupsprachen Java, Python und XML konnte gut umgegangen werden, obwohl die beiden noch recht wenig Erfahrung mit Java hatten. Die Codestruktur fanden sie den Umständen entsprechen gut und sinnvoll.

5.2 Was Schlecht Lief

Es gab keine mit Gradle funktionierende, ausreichend dokumentierte und/oder nicht veraltete IMAP- und Email Bibliotheken für Java. Deshalb wichen wir auf die um Welten besser funktionierende Python Bibliotheken imap und emaillib aus. Dazu mussten wir eine Library namens chaquopy benutzen, um Python als Bytecode kompiliert in unsere Java App einbauen zu können. Das ist natürlich unschön, aber die Funktionalität hatte die oberste Priorität.

Etwas, das nicht direkt schlecht lief, aber sehr viel Zeit raubte ist, dass wenn einer der Autoren zum Beispiel eine Database für den Recyclerviewer gemacht hatte, zwar nur eine Testversion, er diese im späteren Verlauf komplett überarbeiten durfte. Es war zwar nur eine Testversion, aber, dass diese so weit von einer professionelle Database entfernt war, war ihm nicht klar. In so einer Situation war er nicht nur bei der Database. Mit dem Recyclerviewer hatte er solche Probleme sogar öfters. Oft hat zwar noch nicht viel funktioniert, aber er musste den Recyclerviewer mehrmals komplett umschreiben.

Etwas, das sicher hätte besser laufen sollen, war das Zeitmanagement. Wir hatten zwar mögliche Komplikationen miteinberechnet im Zeitplan, doch wir hatten viel mehr und verheerendere Probleme, welche unseren Zeitplan regelrecht herausforderten, schlisslich waren wir beinahe immer in Zeitverzug. Im Sommer dachten wir noch, wir wären perfekt in der Zeit und dies wurde uns auch bestätigt. Jedoch als wir aus den Sommerferien kamen, wurde uns bewusst, wie viel es noch zu tun gab. Wir haben alles gegeben, jedoch wurde die App leider nicht fertig.

5.3 Was Wir Gleich Machen Würden

Wenn wir in die Vergangenheit reisen und die App von Neuem machen könnten, würden wir am User Design nichts ändern, und auch weiterhin mit Git als VCS arbeiten und für jedes noch nicht einsatzbereite Feature einen neuen Branch machen. Die Arbeitsweise an sich hat sich aus unserer Sicht bewährt und ist ein passabler Weg, kollaborativ an einem Softwareprojekt zu arbeiten.

5.4 Was Wir Anders Machen Würden

Der Code, der in Java geschrieben wurde, kann nicht nativ auf einer Maschine laufen, sondern muss durch eine virtuelle Maschine, die Java Virtual Machine (JVM) während der Ausführung in nativen Code umgewandelt werden. Deshalb würde bei einem Rewrite wohl besser mehr Code in C oder C++ geschrieben werden, um die Geschwindigkeit und Portabilität zu erhöhen. Java komplett wegzulassen, ist weder vorgesehen, noch praktisch sinnvoll umsetzbar.

Uns ist öfters gesagt worden, dass das Managen der Zeit sehr wichtig ist. Wir sind davon ausgegangen, dass wir diese auch gut eingeplant hatten. Dem war leider nicht so und wir würden uns mehr Gedanken machen beim Planen, wie auch, wie lange wir an einem Problem arbeiten, bevor wir das Feature entfernen, als dass wir sehr lange daran arbeiten.

5.5 Abschliessende Persönliche Schlussfolgerung

Wir haben das Gefühl, einen guten ersten Einblick in die native Android Programmierung mit Java und Python bekommen zu haben. Wir haben uns vertraut gemacht mit den Vorzügen, aber auch Nachteilen dieser Art von Programmierung und der Plattform Android.

Wir sind zwar etwas enttäuscht, dass wir nicht alle geplanten Ziele erreicht haben, doch wir haben noch genug Motivation, die App in den nächsten paar Wochen und Monaten fertigzustellen. Denn die Arbeit hat uns insgesamt doch gefallen, trotz einigen Motivationstiefs, sodass wir auch gerne unseren Freunden und Familien von

Noah Vogt & Simon Hammer  6 DANKSAGUNG

ihr erzählt haben. Wir können sicher sagen, dass wir jetzt eine Smartphone App als grösseres Projekt ansehen als das, was wir dachten. Eine App ist nicht so simpel wie wir erwartet haben.

Was uns auch noch sehr gefallen hat, ist das Arbeiten mit dem Version Control System Git und der Plattform Github, denn so konnte man gut den Fortschritt sehen und tracken, schliesslich machte das kollaborative Arbeiten an einem Projekt dieser Grösse besonders Sinn und konnte gut Nutzen machen von der Funktionalität dieses Systems. Dazu war das eine sehr gute Lehre wie später in grösseren Teams solche Programme entstehen. Wir sind jetzt sicher etwas besser ausgerüstet als andere.

6 Danksagung

Wir - Simon und Noah - möchten uns bei unserer Betreuungslehrperson Dr. Viktor Yakonthov, und unserem Koreferenten D. Bühler bedanken, dass sie uns die Arbeit haben durchführen lassen und ihre Bereitschaft gezeigt haben, bei allfälligen Fragen zu helfen.

Ein besonderer Dank gilt auch unseren beiden Müttern, welche den Text durchgelesen haben und versucht haben, unsere sprachlichen Fehler zu korrigieren. Ausserdem möchten wir uns noch bei Noahs Vater bedanken, welcher uns die Namenidee für unsere App gab.

Noah Vogt & Simon Hammer  7 GLOSSAR

7 Glossar

Android Debugging Bridge Eine Software mit verschiedenen Tools, mit der man mit einem physischen Android Gerät interagieren kann, welches per USB-Anschluss an den PC angeschlossen ist. Man kann z.B. Apps des angeschlossenen vom Computer aus löschen und Neue installieren, Screenshots aufnehmen, oder Dateien transferieren.. 9

Android Studio Ein von Google entwickeltes IDE, welches auf dem Editor IntelliJ IDEA basiert und für die Android Entwicklung spezialisiert wurde. [Deve]. 8, 9

APK APK steht für “Android Package”, welches dem Format entsprechen soll, in dem Software dem Android Betriebssystem entwickelt wird.. 9

Branch Beim Version Control Systems Git handelt es sich hier um eine abgetrennte Arbeitsachse, welche erlaubt, verschieden Aufgaben in der Softwareentwicklung, wie z.B. das Programmieren neuer Features getrennt oder parallel voneinander zu entwickeln, um sie später in einem Git Merge wieder zusammenzuführen. Weiterführend: [CS14b].. 8, 24

Compiler Ein Programm, welches den vom Menschen lesbaren Quellcode in die vom Computer ausführbare Form bringt.. 9

Copyleft-Softwarelizenzen Wie bei permissiven Lizenzen können Sie das Programm für JEDEN Zweck ausführen, den Quellcode lesen, ändern und die Änderungen veröffentlichen. Der Trick liegt jedoch in den restriktiven Redistributionsbedingungen: Sie dürfen das Programm NUR verbreiten, wenn Ihre Version die gleichen Freiheiten bietet. Dies geschieht in der Regel dadurch, dass die Weitergabe nur unter der gleichen Lizenz erlaubt ist. Der Name “copyleft” ist eine offensichtliche Anspielung auf das Wort “Copyright”, da es versucht, dessen Konzept genau umzukehren: Anstatt die nahezu weltweit vorhandenen Kopierrechtsgesetze dazu zu verwenden, Nutzerfreiheiten einzuschränken, werden Copyleft-Lizenzen dazu eingesetzt, diese zu bewahren und zu erweitern. [Kum11]. 5

Database dt. Datenbank, ist ein System, welches Daten effizient speichern und abrufbar machen kann.. 9

Email Client Ein Programm, welches Emails verwaltet, sendet und empfängt.. 3

Email Writer Der Teil der App, in welchem Emails entworfen werden können.. 17

Emulator Ein Emulator ist ein Programm, welches ein Gerät oder Betriebssystem simuliert, sodass man es innerhalb eines anderen Betriebssystems laufen lassen kann.. 9

Entity Eine Entity speichert Informationen über ein Objekt ab. z.B über eine Person wird ihr Alter und Name gespeichert. Die Person ist das Objekt.. 9

Fragment Eine Klasse, welche ein Teil des UI ist und ihr eigenes Layout, ihren eigener Lebenszyklus und ihren eigenen Input hat. [Devc]. 13 Free Software Foundation dt. “Stiftung für freie Software”, ist eine von Richard Stallman[Wik] gegründete

Stiftung, ursprünglich mit dem Ziel die Entwicklung des GNU Projekts zu finanzieren, was mittlerweile erweitert und erstetzt wurde durch die allgemeine Förderung und Entwicklung von freier Software.. 5, 22, 24

Freie Software engl. “free software”, ist nach der Definition der Free Software Foundation Software, welche die vier von ihnen definierten Grundfreiheiten garantiert: Das Verwenden der Software für jeden Zweck (keine willkürlichen, z.B. geografischen Einschränkungen etc.), der Quellcode darf ohne Vertraulichkeitsvereinbarungen oder ähnliche Einschränkungen von allen untersucht und gelesen werden, darf beliebig modifiziert und angepasst werden und alle modifizierten sowie nichtmodifizierten Versionen der Software dürfen weitergegeben werden.[Eur]. 22, 23

Git Ein populäres Programm, welches die Funktion eines Version Control Systems übernimmt und auf einem lokalen Gerät benutzt und installiert wird. Zusätzlich kann es auch auf einem Server installiert werden, um die eigenen lokalen Änderungen hochzuladen, neue fremde Änderungen herunterladen und Änderungen zu synchronisieren, um mit mehreren Leuten kollaborativ an einem Softwareprojekt arbeiten zu können.[CS14a]. 8, 24

Git Merge Beim Version Control Systems Git unterschiedliche Branches zusammenzuführen in einen neuen, ähnlich dem Reissverschlussprinzip bei der zwei Strassenspuren in eine einzige zusammengeführt werden [Lim20].. 8, 24

GitHub Die grösste, global öffentlich zugängliche Plattform für Hosting von Git Repositories. [Lim20]. 8

IDE Ein Programm, welches den Programmierer beim Programieren unterstütz, indem es z.B Textvorschläge gibt oder das compilen des codes übernimmt.. 8, 23

Library Eine Library (dt. Bibliothek) ist eine Sammlung von Programmen, Programmfunktionen und Skripts, welche in einem anderen Programm verlinkt werden, um gewisse generische Funktionalitäten nicht jedes mal neu entwickeln zu müssen oder unnötig ein Klon davon in den Quellcode einfügen zu müssen. [Hop21]. 9

List Ein Datentyp, welcher erlaubt, mehrere einzelne Variablen aneinander zu ketten, was beispielsweise etwa so dargestellt werden kann: List<Integer> = {1, 3, 4, 5}.. 10

LiveData Eine Klasse, welche beobachtbar in einem gewissen Lebenszyklus ist und Daten speichern kann. [Devd]. 15

Observer Informiert die Klasse über eine Änderung bei einem beobachtbaren Objekt. [Devf]. 15

Permissive Softwarelizenzen Mit diesen Lizenzen hat man das Recht das Programm für JEDEN Zweck zu benutzen, den Source Code zu lesen, ändern und seine Änderungen zu veröffentlichen. Ihr Name kommt von der Tatsache, dass sie “permissiv” sind, wenn es um ihre wenigen Einschränkungen geht: Sie schränken die Verbreitung des Quellcodes nicht sehr stark ein und erlauben es oft, die Software unter JEGLICHEN Bedingungen weiterzugeben. Das bedeutet, es ist möglich, den Fork eines permissiv

Gymnasium Kirschgarten  Seite 28

lizenzierten Programms proprietär zu machen. Das bedeutet, dass Sie den Code nicht davor schützen, in anderen Projekten, selbst wenn diese proprietär sind, verwendet zu werden, ohne etwas zurück geben zu müssen. Das ist ein eindeutiger Nachteil und der Grund, warum manche Leute - meist auf Imageboards [Ano20] - diese Lizenzen als “Cuck Licenses” beschimpfen, sie werden auch reichlich kritisiert auf diversen technologiebezogenen Blogposts[Smi21].. 5

Query Eine Anfrage inklusive Wert, welche an ein Programm, z.B. eine Datenbank gesendet werden.. 9

Recyclerview Eine stark anpassbare, durchscrollbare, dynamisch veränderbare Liste von der verschiedene Views und (Text-)Objekten.. 10

Server Damit beschreibt man in der IT hauptsächlich diese beiden Dinge: Ein Programm, welches die ganze Zeit läuft, damit ein anderes Programm mit diesem interagieren kann, was dynamische Änderungen erlaubt. Die andere Bedeutung ist ein dedizierter Computer, auf welchem Serverprozesse laufen, beispielsweise ein Mailserver oder eine Website.. 9

SQL Kurz für “Structure Query Language”. Eine Sprache, um einer Datenbank Befehle oder Anweisungen zu übermitteln. [Ric01b]. 9

SQLite SQLite unterstützt viele Funktionen von SQL hat aber keinen eigene Serverprozesse und ist deshalb leichter an Systemressourcen.. 9

User Interface Oberbegriff für die ganze graphische Oberfläche, bestehend aus Inhalten wie Buttons, Text, Bildern, mit welcher der Nutzer interagieren kann durch Tippen, Scrollen oder Tastatureingaben in Textfeldern.. 10

Version Control Systems Ein System oder Programm, welches die Versionierung des Quellcodes einer Software verwaltet.. 8, 24

View Im Kontext der Android Entwicklung ist eine View ein rechteckiges Fenster, welches auf dem Display angezeigt wird, wobei es diverse Inhalte wie Buttons, Switches oder Text enthalten kann. [Devg]. 10

Noah Vogt & Simon Hammer  8 LITERATURVERZEICHNIS

8 Literaturverzeichnis

[Sal94] P.H. Salus. A Quarter Century of UNIX. Addison-Wesley UNIX and Open Systems Series. Addison-Wesley Publishing Company, 1994, S. 66. isbn: 9780201547771.

[Ric01a] G. Riccardi. Principles of Database Systems with Internet and Java Applications. Addison-Wesley, 2001, S. 4. isbn: 9780201612479.

[Ric01b] G. Riccardi. Principles of Database Systems with Internet and Java Applications. Addison-Wesley, 2001, S. 14. isbn: 9780201612479.

[SGF02] R. Stallman, J. Gay und F.S. Foundation. Free Software, Free Society: Selected Essays of Richard M. Stallman. Free Software Foundation, 2002, S. 9–11. isbn: 9781882114986.

[Sta07] Richard Stallman. The GNU General Public License v3.0 - GNU Project - Free Software Founda-

         tion. https://www.gnu.org/licenses/gpl-3.0.en.html. (besucht am 17.09.2021). Juni

2007.

[DP09] T. Dalzell und E. Partridge. The Routledge Dictionary of Modern American Slang and Unconventional English. Routledge, 2009, S. 595. isbn: 9780415371827.

[Kum11] C.A. Kumar. Welcome to the ’free’ World: A Free Software Initiative. Indian Universities Press, 2011, S. 28–29.

[CS14a] Scott Chacon und Ben Straub. Pro Git. Das Buch ist open-source und über diesen Link erreichbar https://github.com/progit/pogit2. 2014, S. 12. isbn: 978-1484200773.

[CS14b] Scott Chacon und Ben Straub. Pro Git. 2014, S. 63. isbn: 978-1484200773.

[Raw19] Ashish Rawat. Using Room Database — Android Jetpack — by Ashish Rawat — MindOrks — Me-

         dium. https://medium.com/mindorks/using-room-database-android-jetpack-675a89a0e942.

(besucht am 11.10.2021). Feb. 2019.

[Ano20] Anonymous. /t/ - Open Source Licenses. https://8chan.moe/t/res/865.html. (besucht am 19.09.2021). Aug. 2020.

[BGV20] S. Bhattacharya, K. Gopinath und D. Voigt. Resource Proportional Software Design for Emerging Systems. CRC Press, 2020. isbn: 9781351682336.

[Lim20] Sebastian De Lima. What Is GitHub? https://medium.com/swlh/what-is-github-423f9049ab2d.

(besucht am 11.10.2021). Juli 2020.

[Hop21] Computer Hope. What is a Library? (besucht am 11.10.2021). Feb. 2021. url: https://www.computerhope.com/jargon/l/library.htm.

[Smi21] Luke Smith. Why I Use the GPL and Not Cuck Licenses – Luke Smith. https://lukesmith.xyz/articles/why-i-use-the-gpl-and-not-cuck-licenses.

(besucht am 19.09.2021). Apr. 2021.

[suc21] suckless.org. software that sucks less — suckless.org software that sucks less. https://suckless.org/philosophy/.

(besucht am 16.09.2021). 2021.

[Anoa] Anonoymous. LayoutManager — Android — myMusing. https://mymusing.co/layoutmanager-android/.

Edited by Simon, (besucht am 19.09.2021).

[Anob] Anonym. views-widgets-samples/RecyclerView at main · android/views-widgets-samples · GitHub.

         https://github.com/android/views-widgets-samples/tree/main/RecyclerView.

(besucht am 14.10.2021).

[Cho] Junegunn Choi. vim-plug, a minimalist Vim plugin manager. (besucht am 13.10.2021). url:

         https://github.com/junegunn/vim-plug.

[Cod] Codepath. Using the RecyclerView — CodePath Android Cliffnotes. https://guides.codepath.com/android/Using-the-RecyclerView. (Accessed on 17/10/2021).

[Deva] Developers. Create dynamic lists with RecyclerView — Android Developers. https://developer.android.com/guide/topics/ui/layout/recyclerview. (besucht am 11.10.2021).

[Devb] Developers. Create dynamic lists with RecyclerView — Android Developers. https://developer.android.com/guide/topics/ui/layout/recyclerview. (Accessed on 17/10/2021).

[Devc] Developers. Fragments — Android Developers. https://developer.android.com/guide/fragments.

(besucht am 15.10.2021).

[Devd] Developers. LiveData — Android Developers. https://developer.android.com/reference/androidx/lifecycle/LiveData.

(besucht am 15.10.2021).

[Deve] Developers. Meet Android Studio — Android Developers. https://developer.android.com/studio/intro.

(besucht am 11.10.2021).

[Devf]  Developers. Observer — Android Developers. https://developer.android.com/reference/java/util/Observer.

(besucht am 15.10.2021).

[Devg] Developers. View — Android Developers. (besucht am 11.10.2021). url: https://developer.android.com/reference/android/view/View.

[Devh] Android Developers. Android Room with a View - Java. https://developer.android.com/codelabs/android-room-with-a-view#15.

Edited by Simon, (besucht am 19.09.2021).

[Eur] Free Software Foundation Europe. Freie Software - FSFE. (besucht am 13.10.2021). url: https://fsfe.org/freesoftware/freesoftware.de.html.

[For] Internet Engineering Task Force. rfc9051. (besucht am 15.10.2021). url: https://datatracker.ietf.org/doc/html/rfc9051.

[Gar] Sagar Garg. Room Persistence Library - DZone Database. (besucht am 19.09.2021). url: https://dzone.com/articles/room-persistence-library.

[Jos] Jonathan Clark Josh Zimmermann. Principles of Imperative Computation. (besucht am 13.10.2021).

         url: https://www.cs.cmu.edu/~rjsimmon/15122-s13/rec/07.pdf.

[Moz] Mozilla. Thunderbird - Make Email easier. (besucht am 13.10.2021). url: https://www.thunderbird.net/en-GB/.

[Mun] Avatar Florina Muntenescu. GitHub - googlecodelabs/android-room-with-a-view. https://github.com/googlecodelabs/android-room-with-a-view. Edited by Simon, (besucht am 19.09.2021).

[Raj] Prabhu Vignesh Kumar Rajagopal. GIT Branch and its Operations. - An Easy Understanding - Di-

         gital Varys. (besucht am 19.09.2021). url: https://digitalvarys.com/git-branch-and-its-operations/.

[suc] suckless.org. dwm - dynamic window manager — suckless.org software that sucks less. (besucht

         am 13.10.2021). url: https://dwm.suckless.org.

[Teaa] Google Team. Query syntax in Standard SQL — BigQuery — Google Cloud. (besucht am

         13.10.2021). url: https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#order_by_clause.

Gymnasium Kirschgarten  Seite 31

Noah Vogt & Simon Hammer  9 ABBILDUNGSVERZEICHNIS

[Teab] Material Designe Team. Introduction - Material Design. https://material.io/design/introduction. (besucht am 11.10.2021).

[Wik] Wikipedia. Richard Stallman. (besucht am 13.10.2021). url: https://de.wikipedia.org/wiki/Richard_Stallman.

9 Abbildungsverzeichnis

1 Quellcode (engl. “source code”) wird in ausführbaren Maschinencode umgewandelt [SGF02] . 4 2 parallele Featureentwicklung mit Git [Raj] . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3 Beispiel vom RecyclerView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 4 grober Aufbau der App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5 die Startup UI von snailmail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 6 das Account Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 7 Layout Manager Recyclerview [Anoa] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 8 Input Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 9 Room Struktur [Devh] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 10 EmailViewModel and Repository [Devh] . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 11 Email Writer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 12 Diagramm Email Versand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

Noah Vogt & Simon Hammer

Anhang

Open-Source Programme

Es wurden Open-Source Programme genutzt um verschiedene Elemente einbauen zu können. Für die Library Room haben sich die Autoren an diesem Programm bedient. [Mun] Stark betroffen sind die Dateien EmailViewModel.java, EmailViewHolder.java, CustomAdapter.java, EmailRepository.java, EmailRoom-Database.java, Message.java, MessageDao.java und NewDraftMessageActivity.java. Bei diesen Dateien handelt es sich um Templates, sie wurden stark erweitert und dazu werden sie von anderen Funktionen aufgerufen. Die Dateien von denen sie inspiriert wurden, heissen fast gleich. Es muss nur “Email” und “Message” durch “Word” ersetzt werden und Sie finden die Dateien. Die Dateien ArchiveFragment.java, GalleryFragment.java, HomeFragment.java, DraftFragment.java, SpamFragment.java und MainActivity.java beinhalten alle vier Zeilen beginnend mit der Variabel “mEmailViewModel” vom Typ “EmailViewModel”. Diese vier Zeilen sind jeweils auch aus dem Basisprogramm. Die Zeilen sehen etwa so aus:

 1  mEmailViewModel = new ViewModelProvider(this).get(EmailViewModel.class);
 2  mEmailViewModel.getArchiveMessage().observe(getViewLifecycleOwner(), messages -> {
 3  /* Update the cached copy of the messages in the adapter*/
 4  adapter.submitList(messages);

Weiter beinhaltet die Datei MainActivity.java eine Funktion namens “onActivityResult”, welche auch aus dem Basisprogramm stammt.

 1  public void onActivityResult(int requestCode, int resultCode, Intent data) {
 2  super.onActivityResult(requestCode, resultCode, data);

3

 4  if (requestCode == NEW_WORD_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
 5  Word word = new Word(data.getStringExtra(NewWordActivity.EXTRA_REPLY));
 6  mWordViewModel.insert(word);
 7  } else {
 8  Toast.makeText(
 9  getApplicationContext(),
 10  R.string.empty_not_saved,
 11  Toast.LENGTH_LONG).show();

12  }
13  }

Diese Zeilen waren Grundlage für die nachfolgenden Zeilen.

 1 public void onActivityResult(int requestCode, int resultCode, Intent data) {
 2  super.onActivityResult(requestCode, resultCode, MessageCreateFragment.
                 replyIntent);

3

 4  /* Creates class for the Date when Email is written */
 5  Date dNow = new Date();
 6  SimpleDateFormat ft =
 7  new SimpleDateFormat("dd.MM.yy");

8  System.out.println(dNow);

9

10  Message word = new Message(userGlobal,
11  MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.
                    EXTRA_TO),
12  MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.
                    EXTRA_CC),
13  MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.
                    EXTRA_BCC),
14  MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.
                    EXTRA_FROM),
15  ft.format(dNow),
16  MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.
                    EXTRA_SUBJECT),
17  MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.
                    EXTRA_MESSAGE),
18  "Draft",false);
19  mEmailViewModel.insert(word);

20  }

Sehr ähnliche Zeilen befinden sich auch in der messageCreateFragment.java Datei von Zeile 150-171. Diese stammen ursprünglich auch aus dem Basisprogramm, wurden aber überarbeitet.

1 final Button button = findViewById(R.id.button_save);
2  button.setOnClickListener(view -> {
3  Intent replyIntent = new Intent();
4  if (TextUtils.isEmpty(mEditWordView.getText())) {
5  setResult(RESULT_CANCELED, replyIntent);
6  } else {
7  String word = mEditWordView.getText().toString();
8  replyIntent.putExtra(EXTRA_REPLY, word);
9  setResult(RESULT_OK, replyIntent);

10  }

11  finish();
12  });

Diese Zeilen waren Grundlagen für die nachfolgenden Zeilen.

1 activity.setResult(RESULT_CANCELED, replyIntent);

2

3  String from = sendingAddressObject.getText().toString();
4  String to = receivingAddressObject.getText().toString();
5  String subject = subjectObject.getText().toString();
6  String message = messageBodyObject.getText().toString();
7  String cc = ccObject.getText().toString();
8  String bcc = bccObject.getText().toString();

9 10

Gymnasium Kirschgarten  Seite 34

11  replyIntent.putExtra(EXTRA_FROM, from);
12  replyIntent.putExtra(EXTRA_TO, to);
13  replyIntent.putExtra(EXTRA_CC, cc);
14  replyIntent.putExtra(EXTRA_BCC, bcc);
15  replyIntent.putExtra(EXTRA_SUBJECT, subject);
16  replyIntent.putExtra(EXTRA_MESSAGE, message);
17  activity.setResult(RESULT_OK, replyIntent);

18

19  activity.finish();

20

21  Intent intent = new Intent(getContext(), NewDraftMessageActivity.class);
22  startActivityForResult(intent, MainActivity.NEW_WORD_ACTIVITY_REQUEST_CODE);