Android: Unterschied zwischen den Versionen

Aus m-wiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „* Fast alle Java-Klassen stehen zur Verfügung plus Verschlüsselung, HTTP, JSON, XML Bibliotheken\ * Keine main()-Funktion - stattdessen: lose gekoppelte…“)
 
 
(31 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
* Fast alle [[Java]]-Klassen stehen zur Verfügung plus Verschlüsselung, HTTP, JSON, XML Bibliotheken\
= Einführung =
* Keine main()-Funktion - stattdessen: lose gekoppelte Komponenten, eine oder mehrere davon als Einstiegspunkt definierbar\
* Fast alle [[Java]]-Klassen stehen zur Verfügung plus Verschlüsselung, HTTP, [[JSON]], XML Bibliotheken
* Wichtigste Komponente: "Activity" - entspricht einem sichtbaren Fenster auf dem Screen (Ähnlich wie Tabs eines Browsers). Man kann etwa ein Programm mit Screen 1 (Hauptseite) aufrufen oder direkt Screen 2 (Unterseite). Der Aufruf geschieht über die App-Icons.\
* Für die Programmierung steht in neueren Versionen [https://de.wikipedia.org/wiki/Kotlin_(Programmiersprache) Kotlin] zur Verfügung.
== Entwicklungsumgebung ==\
* Keine main()-Funktion - stattdessen: lose gekoppelte Komponenten, eine oder mehrere davon als Einstiegspunkt definierbar
Zum konkreten Einrichten siehe die [[Android#Links|Links]] zu den Tutorials (Link 2).\
* Wichtigste Komponente: "Activity" - entspricht einem sichtbaren Fenster auf dem Screen (Ähnlich wie Tabs eines Browsers). Man kann etwa ein Programm mit Screen 1 (Hauptseite) aufrufen oder direkt Screen 2 (Unterseite). Der Aufruf geschieht über die App-Icons.
* Eclipse herunterladen, entpacken und ins gewünschte Verzeichnis kopieren\
 
* "Android SDK Starter Package" herunterladen, installieren und starten\
= Entwicklungsumgebung =
* die gewünschten Android Versionen und das Usb Driver Package anwählen und einrichten lassen\
Zum konkreten Einrichten siehe das Buch [[Links und Bücher|Android Apps programmieren]]). Kapitel 2.1.1 Installation.
* Im Android das "ADT (Android Development Tools) Eclipse Plugin" einrichten\
 
* Anschliessend kann ein neues Projekt erstellt werden\
== Neues Projekt ==
=== Neues Projekt ===\
Mit dem Assistenten wird ein neues Projekt erstellt. Im Android-Buch hat es eine bebilderte Anleitung im Kapitel 3.1.1 ab Seite 62. Je nach Version kann es hier sein, dass gewisse Optionen anders heissen oder Felder neu hinzukommen oder verschwinden. Entsprechend muss man halt schauen, was es braucht oder im Internet nachschauen.<br />
Mit dem ADT-Assistenten wird ein neues Projekt erstellt: <br />\
Wähle "File" → "New" → "New Project..."; im "New Project"-Dialog wähle "A new Android Project" aus dem "Android" Order.
Wähle "File" → "New" → "Project..."; im "New Project"-Dialog wähle "Android Project" aus dem "Android" Order.\
<br />
<br />\
 
\
Füll den "New Android Project"-Dialog wie folgt aus:
Füll den "New Android Project"-Dialog wie folgt aus:\
* Project/Application name: "Hello Workshop"
*Project name: "Hello Workshop"\
* Company domain: Beliebige domain, die man entweder besitzt oder die es nicht gibt. testprojekt.test.tt, zeit.dict.ch. Ergibt umgekehrt den package name (tt.test.testprojekt, ch.dict.zeit).
*Verwende die "default location" oder lege eine andere Location fest\
* Verwende die "default location" oder lege eine andere Location fest
*Build target: Android 1.6 (für Kompatibilität mit älteren Versionen kann man später noch schauen)\
* Je nach Kenntnissen und Bedürfnissen kann man auch c++ und/oder Kotlin einbinden
*Application name: "Hello Workshop"\
* Build target: API21 oder was notwendig wählen. Wenn man bestimmte Funktionen braucht, muss man halt unter "Help me choose" schauen, welche Version welches Feature eingeführt hat (Bluetooth usw.). Aktuelle Daten der Verwendung der Geräte unter: https://developer.android.com/about/dashboards
*Package name: "de.test.hello"\
* Auswahl der gewünschten Vorlage  (No Activity, Basic, usw.)
*Create Activity: "HelloWorkshopActivity"\
* Activity Name: "HelloWorkshopActivity" -> entspricht der Java-Klasse der Haupt-Activity und wird ohne Vorgabe entsprechend ''MainActivity'' genannt. Klassen, welche Fenster steuern, sollten als Konvention auf "Activity" enden, doch dies ist natürlich nur eine Konvention. Damit man weiss, was die Klasse tut, sollte man sie entsprechend der Projektvorgaben nennen.
*Min SDK Version: "4" \
* Layout Name: "activity_hello_workshop" -> Layouts sollten klein geschrieben werden und mit dem "_" aufgeteilt werden. Layouts für Activities sollten entsprechend mit "activity_" beginnen.
\
 
Klicke auf den "Finish"-Button.\
Klicke auf den "Finish"-Button und warte, bis das Projekt erstellt wurde.
\
 
=== Emulator ===\
== Emulator ==
Falls kein Andoid-Gerät vorhanden ist, oder das gewünschte Gerät fehlt.\
 
\
=== Gerät einrichten ===
Klicke auf das "Android SDK and AVD manager"-Icon in der Icon-Leiste von Eclipse. \
Falls kein Andoid-Gerät vorhanden ist, oder das gewünschte Gerät fehlt.
Klicke auf "New" \
 
Im "Create new AVD"-Dialog, gib folgendes ein:\
Klicke auf das "Android SDK and AVD manager"-Icon in der Icon-Leiste.
* Name: "G1"\
Klicke auf "New"  
* Target: "Android 1.6 - API Level 4"\
Im "Create new AVD"-Dialog, gib folgendes ein:
* SD Card Size: "1024" MiB\
* Name: "G1"
* Skin: Built-in: "Default (HVGA)" \
* Target: "Android 1.6 - API Level 4"
\
* SD Card Size: "1024" MiB
Dann klicke auf "Create AVD" (kann eine Weile - bis zu einigen Minuten - dauern) \
* Skin: Built-in: "Default (HVGA)"  
\
 
=== Verwendete Dateien ===\
Dann klicke auf "Create AVD" (kann eine Weile - bis zu einigen Minuten - dauern)
Um die verwendeten Dateien zu sehen, muss man den Navigator einschalten. Diesen findet man unter Window -> Show View -> Navigator.\
 
Falls man mehrere Projekte offen hat, zum gewünschten Projekt navigieren.\
Bei der Geräteauswahl kann man auch Geräte mit Playstore anwählen, doch dann kann man bei diesen Geräten keinen Root-Zugriff machen. Man erkennt diese Möglichkeit bei der Auswahl, wenn es ein Icon in der betreffenden Spalte hat.
{| class="wikitable"\
 
|-\
=== App auf Gerät testen ===
! Datei !! Beschreibung\
Beim Start auf das Play-Icon wird das verknüpfte Gerät gestartet und die App ausgeführt.
|-\
 
| HelloWorkshopActivity.java || Klasse der Haupt-Activity. Verweist mit setContentView(R.layout.main); auf das Layout, welches in der main.xml definiert wurde.\
Hier kann es sein, dass ein Gerät gestartet wird, doch die App startet nicht und auf der Konsole kommt die Meldung: "Installation did not succeed. The application could not be installed." In diesem Fall wird zwar im AVD-Manager das korrekte Geräte angezeigt, doch unten rechts im Studio beim Design ist ein anderes Gerät angewählt. Dadurch ergibt sich keine Übereinstimmung vom Layout und vom Gerät und somit kann die App nicht starten. In diesem Fall muss das Gerät beim Designer umgestellt werden, auf das vom AVD-Manager und nach einem Neustart der App wird dies auch angezeigt, wenn es nicht noch weitere Fehler gibt.
|-\
 
| R.java || Resourcen-ID-Definitionen (automatisch erstellt, nicht editieren!)\
== Verwendete Dateien ==
|-\
Um die verwendeten Dateien zu sehen, muss man den Navigator einblenden, der auf der linken Seite zusammengeklappt werden kann. Anschliessend muss man dann oberhalb der Ansicht unterhalb vom Projektnamen die Art der Darstellung wählen. Falls man mehrere Projekte offen hat, zum gewünschten Projekt navigieren.
|/assets || Ordner für Binär-Dateien (alles, was Android nicht selbst verwaltet)\
 
|-\
Bei der Ansicht '''Android''' wird das Projekt "logisch" aufgelistet und entsprechend Dateien, die zusammengehören, wie etwa die Ressourcen zusammen aufgeführt.<br />
|/res || Ordner für Resource-Dateien (Bilder, Layouts, Strings, ...)\
Will man hingegen die wirkliche Datenstruktur sehen, so wechselt man auf '''Project Files''', welches den Baum auflistet.<br />
|-\
Die Projekte werden standardmässig unter folgendem Pfad gespeichert:<br />
|/res/drawable-hdpi/icon.png || Logo in hoher Auflösung (72 x 72 Pixel – 240 dpi)\
C:\Users\<Benutzername>\AndroidStudioProjects\<Projektname>
|-\
 
|/res/drawable-ldpi/icon.png || Logo in niedriger Auflösung (36 x 36 Pixel – 120 dpi)\
Die folgende Tabelle gibt den Stand von Nov. 2020 mit Android Studio 4.1 wieder. Die Entwicklung ist dynamisch und daher kann es gut sein, dass Dateien immer noch verschoben werden und auch Verzeichnisse anders aufgebaut werden. Entsprechend muss man manche Dateien halt suchen, wenn sie nicht am entsprechenden Ort gefunden werden können oder man schaut im Studio, wohin referenziert wird.<br />
|-\
Da im Projekt sehr viele Dateien involviert sind, werden "interne" Verzeichnisse und Dateien wie etwa die diversen Build- und Testverzeichnisse nicht aufgeführt. Auch Verzeichnisse, welche nur für die Versionsverwaltung oder fürs Kompilieren verwendet werden, werden nicht aufgelistet.
|/res/drawable-mdpi/icon.png || Logo in mittlerer Auflösung (48 x 48 Pixel – 160 dpi)\
 
|-\
{| class="wikitable"
|/res/layout/main.xml || Layout-Definition für die View der Haupt-Activity. Wird erstellt aus dem Namen, den man beim generieren des Projekts für das Layout wählt. Ohne Anpassung wird er aus dem Projektnamen gebildet.\
|-
|-\
! Datei/Ordner !! Beschreibung
|/res/values/strings.xml || String-Definitionen, welche im Programm oder anderen Dateien referenziert werden\
|-
|-\
| /app || Ordner in dem sich das aktuelle Modul befindet. Bei grösseren Projekten können mehrere Module definiert werden.
|AndroidManifest.xml || "Manifest"-Datei, definiert Infos wie Name, Logo und Haupt-Activity\
|-
|-\
| /app/src || Source-Ordner aller Klassen des Moduls
|default.properties || Projekt-Eigenschaften\
|-
|}\
| /app/src/main/'''AndroidManifest.xml''' || Linked alle wichtigen Dateien des Projekts. Dort werden auch die Berechtigungen fürs Projekt angemeldet (Datei- und Internetzugriff usw.). Dazu muss man dort Services anmelden oder wenn man ContentProvider für externe Apps bereitstellt.
==== AndroidManifest.xml ====\
|-
Legt diverse Werte zum aussehen und verhalten des Programms fest. Siehe dazu auch Link 2 mit der Beschreibung der Standardeinträge.<br />\
| /app/src/main/java/<domain>/<projektname>/'''MainActivity.java''' || Klasse der Haupt-Activity. Verweist mit setContentView(R.layout.main); auf das Layout, welches in der main.xml definiert wurde.
Folgende Einträge sind zusätzlich notwendig:\
|-
<pre>\
| /app/src/main/res || Layout- Sprach- und Bilddateien.
<supports-screens android:anyDensity="true"\
|-
                  android:largeScreens="true" \
| /app/src/main/res/drawable || Bilddateien. Diese werden in den entsprechenden Unterordnern auflösungsabhängig gespeichert, damit die App auch bei unterschiedlichen Geräten in etwa gleich ausschaut.
                  android:smallScreens="true" />\
|-
</pre>\
| /app/src/main/res/layout || Layouts. Da das Layout beim drehen meist etwas anders angezeigt wird, gibt es auch den Ordner layout-land, in dem das "landscape" Layout abgelegt wird.
* anyDensity für hohe Auflösungen\
|-
* largeScreens bei grossen Displays\
| /app/src/main/res/layout/'''activity_main.xml''' || Das Layout wird als XML-Datei erstellt. Die Ressourcen werden dort entsprechend auf die Text-Ressource-Dateien verwiesen, damit man die App nur einmal kompilieren muss und trotzdem verschiedene Sprachen anbieten kann. Wird erstellt aus dem Namen, den man beim generieren des Projekts für das Layout wählt. Ohne Anpassung wird er aus dem Projektnamen gebildet.
* smallScreens für kleine Displays\
|-
\
| /app/src/main/res/menu || Falls man ein Menü in der Action-Bar anbieten will, werden die Ressourcen dafür hier angelegt. Standardmässig wird das Manü aber nicht angelegt.
Wenn man Eclipse verwendet, kann man aus den Warnungen ableiten, wenn man etwas falsch definiert. Dazu kann man entweder die Datei direkt bearbeiten oder dies über den Tab umstellen und manches direkt grafisch anpassen.\
|-
\
| /app/src/main/res/mipmap* || Icons. Diese werden in den entsprechenden Unterordnern auflösungsabhängig gespeichert, damit diese auch bei unterschiedlichen Geräten in etwa gleich ausschauen. (xxxhdpi = 192 x 192 Pixel – 640 dpi / xxhdpi = 144 x 144 Pixel – 480 dpi / xhdpi = 96 x 96 Pixel – 320 dpi / hdpi = 72 x 72 Pixel – 240 dpi / mdpi = 48 x 48 Pixel – 160 dpi / ldpi = 36 x 36 Pixel – 120 dpi)
==== HelloWorkshopActivity.java ====\
|-
Enthält, wie unter [[Java#Programmierung|Programmierung]] gezeigt, das Hauptprogramm. Hier werden unter anderem die Elemente definiert.\
| /app/src/main/res/values(-xx) || Text-Ressource-Dateien. Diese Dateien enthalten Wertepaare für verschiedene Anwendungen wie Farben oder Strings, welche man dann in verschiedene Sprachen überstzene kann und die dann das entsprechende Länderkürzel angehängt bekommen.
private Button hiButton;\
|-
private Button helloButton;\
|/assets || Ordner für Binär-Dateien (alles, was Android nicht selbst verwaltet). Wird standardmässig nicht angelegt.
\
|-
==== strings.xml ====\
|/gradle || Wird für die Versionsverwaltung eingesetzt.
Legt die Werte für die Strings fest. Hier wurden zwei Srings "hello" und "app_name" definiert, welche nun in anderen Dateien verwendet werden können (Layout oder Programm).\
|}
<pre>\
 
<?xml version="1.0" encoding="utf-8"?>\
=== AndroidManifest.xml ===
<resources>\
Legt diverse Werte zum Aussehen und Verhalten des Programms fest. https://developer.android.com/guide/topics/manifest/manifest-intro
    <string name="hello">Hello World, HelloWorkshopActivity!</string>\
 
    <string name="app_name">Hello Workshop</string>\
Folgende Einträge sind für die Unterstützung von unterschiedlichen Geräte möglich. Evtl. bei neueren Versionen nicht mehr notwendig.
</resources>\
<pre>
</pre>\
<supports-screens android:anyDensity="true"
\
                  android:largeScreens="true"
== Programmierung ==\
                  android:smallScreens="true" />
Zuerst ein Beispiel, welches unten erklärt wird:\
</pre>
<pre>\
* anyDensity für hohe Auflösungen
class MyActivity extends Activity {\
* largeScreens bei grossen Displays
\
* smallScreens für kleine Displays
  onCreate {\
 
    View view = ... // erstellt den sichtbaren Teil\
Für Berechtigungen werden Einträge in folgender Weise hinzugefügt:
    setContentView(view);\
<pre>
    ...\
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  } // end Eventhandler onCreate\
<uses-permission android:name="android.permission.INTERNET" />
\
</pre>
  onClick {\
 
    ...\
Wenn man Eclipse verwendet, kann man aus den Warnungen ableiten, wenn man etwas falsch definiert. Dazu kann man entweder die Datei direkt bearbeiten oder dies über den Tab umstellen und manches direkt grafisch anpassen.
    Intent intent = ... // Zugriff auf externes Programm\
 
    startActivity (intent);\
Ein Beispiel ist im Android-Buch auf Seite 39 (Kap. 2.2.2 App-Bausteine) aufgeführt.
  } // end Eventhandler onClick\
 
\
=== MainActivity.java ===
} // end class MyActivity\
Enthält, wie unter [[Java#Programmierung|Programmierung]] gezeigt, das Hauptprogramm. Der Name wird entsprechend bei Projekteröffnung festgelegt. Hier werden unter anderem die Elemente definiert.
</pre>\
 
=== Activity ===\
private Button hiButton;
* definiert eine "View", zur Anzeige auf dem Screen\
private Button helloButton;
* behandelt "Events" (z. B. Klick auf einen Button)\
 
* benutzt "Intents", um andere Activities zu starten \
=== strings.xml ===
\
Legt die Werte für die Strings fest. Hier wurden zwei Srings "hello" und "app_name" definiert, welche nun in anderen Dateien verwendet werden können (Layout oder Programm). Siehe dazu den Abschnitt [[Android#Texte|Texte]].
=== View ===\
<pre>
* eine "View" ist der sichtbare Teil der Activity\
<?xml version="1.0" encoding="utf-8"?>
* definiert in einer XML-Layout-Datei (oder im Code) \
<resources>
\
    <string name="hello">Hello World, HelloWorkshopActivity!</string>
=== Events / Programmablauf ===\
    <string name="app_name">Hello Workshop</string>
* werden ausgelöst, wenn etwas geschieht (z. B ein Button geklickt wird)\
</resources>
* ruft eine Listener-Methode auf, sofern ein Listener definiert ist \
</pre>
Ein Beispiel mit mehreren Events für einen Programmablauf sieht man hier: http://www.androidpit.de/de/android/wiki/view/Datei:Beginners_Workshop_Activity_LC.png <br />\
 
Um Datenverlust oder den Verlust des Zustands einer Activity zu vermeiden, müssen die Daten/der Zustand der Activity gesichert werden, wenn diese pausiert (nicht mehr im Vordergrund, aber noch sichtbar) oder gestoppt (nicht mehr sichtbar) wird. \
== Android-App kompilieren (Gradle) ==
\
Im Gegensatz zu einem "normalen" Programm, müssen bei einer Android-App viele verschiedene Tools zusammenarbeiten, um am Schluss eine lauffähige App bereitstellen zu können. Gradle ist ein Build Management Tool für Java, das diese Aufgaben bündelt.
==== onClick() ====\
# Herunterladen von externen Abhängigkeiten (externe Bibliotheken)
* Aufruf beim Drücken auf einen Button\
# Kompilieren der Java-Dateien in DEX
<pre>\
# Kompilieren der Ressourcen (Bilder, Icons, usw.)
EditText nameField = (EditText) findViewById(R.id.name_field);\
# Verpacken als APK-Datei (DEX + Ressourcen)
String name = nameField.getText().toString();\
# Signieren der APK-Datei
if (name.length() == 0) {\
# Optimieren der App auf Speicherverbrauch
    new AlertDialog.Builder(this) \
 
                  .setMessage(R.string.error_name_missing)\
Gradle benutzt eine auf [https://de.wikipedia.org/wiki/Groovy Groovy] aufbauende [https://de.wikipedia.org/wiki/Dom%C3%A4nenspezifische_Sprache DSL] (Domain Specific Language). Wenn man weiss wie und es braucht, so kann man den Build-Prozess entsprechend anpassen. Siehe dazu den Link: https://developer.android.com/studio/build
                  .setNeutralButton(R.string.error_ok, null)\
 
                  .show();\
Für die Einbindung der externen Bibliotheken wird das [https://de.wikipedia.org/wiki/Apache_Maven Maven-Repository] eingebunden.
    return;\
 
} // end if\
= Programmierung =
</pre>\
== Zustände einer App ==
\
Grafik aus dem Androidbuch.<br />
==== onCreate() ====\
[[Datei:App-Zyklus.jpg|100px|mini|links|Zyklus einer App]]<br /><br /><br /><br /><br /><br />
* wird einmalig beim Programmstart aufgerufen\
 
* muss die View und die Elemente darin definieren\
Zuerst ein Beispiel, welches unten erklärt wird:
* springt anschliessend weiter nach onStart()\
<pre>
* definiert die Listener-Aufrufe\
class MyActivity extends Activity {
<pre>\
 
hiButton = (Button)findViewById(R.id.hi_button);\
  onCreate {
hiButton.setOnClickListener(this);\
    View view = ... // erstellt den sichtbaren Teil
helloButton = (Button)findViewById(R.id.hello_button);\
    setContentView(view);
helloButton.setOnClickListener(this);\
    ...
</pre>\
  } // end Eventhandler onCreate
\
 
==== onDestroy() ====\
  onClick {
* Wird nur aufgerufen, wenn das Programm explizit beendet wird\
    ...
\
    Intent intent = ... // Zugriff auf externes Programm
==== onPause() ====\
    startActivity (intent);
* Geht weiter nach onResume, wenn es wieder in den Vordergrund geholt wird oder nach onStop, wenn es gar nicht mehr sichtbar ist\
  } // end Eventhandler onClick
* Da das Programm bei Speichermangel in diesem Zustand "abgeschossen" werden kann, müssen spätestens hier die Benutzerdaten gesichert werden\
 
\
} // end class MyActivity
==== onRestart() ====\
</pre>
* Falls das Programm gestoppt wurde, doch noch nicht wegen Speichermangels aus dem RAM entfernt wurde und nun wieder in den Vordergrund kommt, wird diese Methode aufgerufen\
 
* Springt anschliessend direkt nach onStart()\
== Activity ==
\
* definiert eine "View", zur Anzeige auf dem Screen. Entspricht einem Fenster.
==== onResume() ====\
* behandelt "Events" (z. B. Klick auf einen Button)
* Wird jedes Mal aufgerufen, wenn die App nach einer Pause (wieder) in den Vordergrund kommt\
* benutzt "Intents", um andere Activities zu starten
\
 
==== onStart() ====\
== Fragment ==
* Springt weiter nach onResume()\
Wurden mit Android 3.1 eingeführt und sind selbständige Teilbereiche einer Activity. Können entsprechend auf verschiedenen Activities wiederverwendet oder in einer Activity mehrfach eingesetzt werden.
\
 
==== onStop() ====\
== View ==
* Wird aufgerufen, wenn das Programm nicht mehr sichtbar ist\
* eine "View" ist der sichtbare Teil der Activity
* Je nach weiterer Folge, geht der Programmlauf weiter mit onDestroy oder onRestart.\
* definiert in einer XML-Layout-Datei (oder im Code)  
\
 
=== Intent === \
== Events / Programmablauf ==
* startet eine andere Activity ("öffnet ein neues Fenster")\
* werden ausgelöst, wenn etwas geschieht (z. B ein Button geklickt wird)
* kann Daten an die zu startende Activity übergeben\
* ruft eine Listener-Methode auf, sofern ein Listener definiert ist
* kann Activities aus anderen Apps starten!\
Ein Beispiel mit mehreren Events für einen Programmablauf sieht man hier: http://www.androidpit.de/de/android/wiki/view/Datei:Beginners_Workshop_Activity_LC.png <br />
\
Um Datenverlust oder den Verlust des Zustands einer Activity zu vermeiden, müssen die Daten/der Zustand der Activity gesichert werden, wenn diese pausiert (nicht mehr im Vordergrund, aber noch sichtbar) oder gestoppt (nicht mehr sichtbar) wird.
=== Layouts und Elemente ===\
 
Wie oberhalb erwähnt, wird in /res/layout/main.xml das Layout der Hauptdatei festgelegt. Das heisst, hier werden die Elemente festgelegt. \
=== onClick() ===
\
* Aufruf beim Drücken auf einen Button
==== vertikale und horizontale Layouts ====\
<pre>
Layouts können auch geschachtelt werden. Das Hauptlayout ist meist vertikal.\
EditText nameField = (EditText) findViewById(R.id.name_field);
\
String name = nameField.getText().toString();
Vertikales Layout mit einem Titel:\
if (name.length() == 0) {
<pre>\
    new AlertDialog.Builder(this)
<?xml version="1.0" encoding="utf-8"?>\
                  .setMessage(R.string.error_name_missing)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\
                  .setNeutralButton(R.string.error_ok, null)
  android:orientation="vertical"\
                  .show();
  android:layout_width="fill_parent"\
    return;
  android:layout_height="fill_parent"\
} // end if
>\
</pre>
  <TextView  \
 
    android:layout_width="fill_parent" \
=== onCreate() ===
    android:layout_height="wrap_content" \
* wird einmalig beim Programmstart aufgerufen
    android:text="@string/hello"\
* muss die View und die Elemente darin definieren
  />\
* springt anschliessend weiter nach onStart()
</LinearLayout>\
* definiert die Listener-Aufrufe
</pre>\
<pre>
Der Inhalt des Strings wird in der [[Android#strings.xml|/res/layout/strings.xml]] definiert\
hiButton = (Button)findViewById(R.id.hi_button);
\
hiButton.setOnClickListener(this);
Horizontales Layout mit zwei Knöpfen.\
helloButton = (Button)findViewById(R.id.hello_button);
<pre>\
helloButton.setOnClickListener(this);
<LinearLayout \
</pre>
    android:orientation="horizontal"\
 
    android:layout_width="fill_parent"\
=== onDestroy() ===
    android:layout_height="wrap_content"\
* Wird nur aufgerufen, wenn das Programm explizit beendet wird
    >\
 
    <Button \
=== onPause() ===
        android:id="@+id/hi_button"\
* Geht weiter nach onResume, wenn es wieder in den Vordergrund geholt wird oder nach onStop, wenn es gar nicht mehr sichtbar ist
        android:layout_width="wrap_content"\
* Da das Programm bei Speichermangel in diesem Zustand "abgeschossen" werden kann, müssen spätestens hier die Benutzerdaten gesichert werden
        android:layout_height="wrap_content"\
 
        android:layout_weight="1"\
=== onRestart() ===
        android:text="@string/hi_button" \
* Falls das Programm gestoppt wurde, doch noch nicht wegen Speichermangels aus dem RAM entfernt wurde und nun wieder in den Vordergrund kommt, wird diese Methode aufgerufen
        />\
* Springt anschliessend direkt nach onStart()
    <Button \
 
        android:id="@+id/hello_button"\
=== onResume() ===
        android:layout_width="wrap_content"\
* Wird jedes Mal aufgerufen, wenn die App nach einer Pause (wieder) in den Vordergrund kommt
        android:layout_height="wrap_content"\
 
        android:layout_weight="1"\
=== onStart() ===
        android:text="@string/hello_button" \
* Springt weiter nach onResume()
        />\
 
</LinearLayout>\
=== onStop() ===
</pre>\
* Wird aufgerufen, wenn das Programm nicht mehr sichtbar ist
\
* Je nach weiterer Folge, geht der Programmlauf weiter mit onDestroy oder onRestart.
==== TextView (Label) ====\
 
<pre>\
== Intent ==
<TextView  \
* startet eine andere Activity ("öffnet ein neues Fenster")
    android:layout_width="fill_parent" \
* kann Daten an die zu startende Activity übergeben
    android:layout_height="wrap_content" \
* kann Activities aus anderen Apps starten!
    android:layout_marginTop="20dp"\
 
    android:text="@string/enter_your_name"\
== Layouts und Elemente ==
/>\
Siehe im Androidbuch Kapitel 2.2.3 ab Seite 42.
</pre>\
Wie oberhalb erwähnt, wird in /res/layout/<NameMainActivity>.xml das Layout der Hauptdatei festgelegt. Das heisst, hier werden die Elemente festgelegt. Layouts werden extra in XML-Dateien erstellt, damit man eine exakte Trennung zum Code erhält, auch wenn man natürlich das Layout auch im Java-Code erstellen kann.
Hier müssten wir noch den String "enter_your_name" in der strings.xml definieren.\
Alle sichtbaren Elemente leiten sich von der Basisklasse View ab, wobei die Elemente in zwei Gruppen aufgeteilt werden:
\
* ViewGroup
==== EditText (Eingabefeld) ====\
* View
<pre>\
Wobei jede ViewGroup Views und weitere ViewGroups enthalten kann.
<EditText\
 
    android:id="@+id/name_field"\
=== ViewGroups (Layouts) ===
    android:layout_width="fill_parent" \
Siehe im Androidbuch ab Seite 75 Kapitel 3.3 Layout-Erstellung.
    android:layout_height="wrap_content" \
Folgende ViewGroups werden standardmässig unterstützt:
/>\
* LinearLayout: Die enthaltenen Views werden unter- ober nebeneinander aufgelistet. Je nachdem, wie man die Eigenschaft ''orientation'' gesetzt hat. Die enthaltenen Views kann man mit %-Angaben aufteilen.
</pre>\
* RelativeLayout: Ordnet die Views im Verhältnis zu sich selbst oder anderen Elementen an. Dies kann sein: rechts von View 2, oberhalb von View 3, zentriert im Container, unterhalb vom oberen Rand, usw.
Hier bekommt das Feld eine id("name_field"), welche man später im Programm verwenden kann, um den Wert auszulesen.\
* TableLayout: Ordnet die Views als Zeilen und Spalten an. Die Breite der Spalten wird durch die Breite des Inhalts bestimmt.
\
* GridLayout: Ähnlich wie TableLayout, doch braucht keinen Container. Dazu können die Zellen gewichtet aufgeteilt werden (prozentual). Für Abstände kann man auf die Eigenschaft Space zurückgreifen. Views können über mehrere Zeilen/Spalten "aufgespannt" werden. Dies ermöglicht komplexe Layouts, ohne dass man dafür mehrere Layouts verschachteln müsste.
==== Button (Knopf) ====\
* ConstraintLayout: Verwandt mit RelativeLayout, doch flexibler. Die Elemente stehen zwar in Beziehung, doch diese Kopplung ist loser und ermöglicht präzise Positionierungen. Die Beziehungen werden durch "Spannfedern" dargestellt.
<pre>\
* ListView: Wird normalerweise nur verwendet, um Daten etwa aus einer Datenbank automatisch abzufüllen und als Liste darzustellen.
<Button \
* GridView: Hier werden die Daten wie bei einer ListView abgefüllt, doch etwa wie die Bilderansicht im Explorer in einem Gitter dargestellt.
    android:id="@+id/hi_button"\
 
    android:layout_width="wrap_content"\
==== vertikale und horizontale Layouts ====
    android:layout_height="wrap_content"\
Layouts können auch geschachtelt werden. Das Hauptlayout ist meist vertikal.
    android:layout_weight="1"\
 
    android:text="@string/hi_button" \
Vertikales Layout mit einem Titel:
/>\
<pre>
</pre>\
<?xml version="1.0" encoding="utf-8"?>
Der Knopf braucht neben der Beschriftung, welche in der strings.xml definiert wird, noch eine id, welche wieder im Programm über ein [[Java#Events|Event]] ausgewertet werden kann.\
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
\
  android:orientation="vertical"
=== Programmierbeispiel komplett ===\
  android:layout_width="fill_parent"
Wenn man ein Android-Projekt unter Eclipse erstellt, so generiert Eclipse mehrere [[Android#Verwendete Dateien|Dateien]]. Hier werden nun alphabetisch alle Dateien aufgeführt, welche im [[Android#Entwicklungsumgebung|Beispielprojekt]] manuell angepasst wurden.\
  android:layout_height="fill_parent"
\
>
==== AndroidManifest.xml ====\
  <TextView 
<pre>\
     android:layout_width="fill_parent"  
<?xml version="1.0" encoding="utf-8"?>\
    android:layout_height="wrap_content"  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"\
    android:text="@string/hello"
    package="com.example.helloworkshop"\
  />
    android:versionCode="1"\
</LinearLayout>
    android:versionName="1.0" >\
</pre>
\
Der Inhalt des Strings wird in der [[Android#strings.xml|/res/layout/strings.xml]] definiert
    <uses-sdk\
 
        android:minSdkVersion="8"\
Horizontales Layout mit zwei Knöpfen.
        android:targetSdkVersion="16" />\
<pre>
    \
<LinearLayout
    <supports-screens \
    android:orientation="horizontal"
    \ android:anyDensity="true"\
    android:layout_width="fill_parent"
        android:largeScreens="true" \
    android:layout_height="wrap_content"
        android:smallScreens="true" />\
    >
      \ \
     <Button
     <application\
        android:id="@+id/hi_button"
        android:allowBackup="true"\
        android:layout_width="wrap_content"
        android:icon="@drawable/ic_launcher"\
        android:layout_height="wrap_content"
        android:label="@string/app_name"\
        android:layout_weight="1"
        android:theme="@style/AppTheme" >\
        android:text="@string/hi_button"
        <activity\
        />
            android:name="com.example.helloworkshop.HelloWorkshopActivity"\
    <Button
            android:label="@string/app_name" >\
        android:id="@+id/hello_button"
            <intent-filter>\
        android:layout_width="wrap_content"
                <action android:name="android.intent.action.MAIN" />\
        android:layout_height="wrap_content"
\
        android:layout_weight="1"
                <category android:name="android.intent.category.LAUNCHER" />\
        android:text="@string/hello_button"
            </intent-filter>\
        />
        </activity>\
</LinearLayout>
     </application>\
</pre>
\
 
</manifest>\
=== Views (Elemente) ===
</pre>\
Die Elemente werden wie erwähnt in den Layouts platziert und vom Benutzer verwendet, während die ViewGroup im Hintergrund "nur" den Platz aufteilt. Die Elemente werden am einfachsten in der "Designer-Ansicht" auf der Activity verteilt, da man so nicht alles im XML-Code erstellen muss, sondern nur noch die Beziehungen oder Positionen sauber setzen muss.
\
 
==== HelloWorkshopActivity.java ====\
==== Button (Knopf) ====
<pre>\
Ermöglicht das entgegennehmen von Aktionen und deren Auswertung im Code.
package com.example.helloworkshop;\
<pre>
\
<Button  
import android.app.Activity;\
     android:id="@+id/hi_button"
import android.app.AlertDialog;\
     android:layout_width="wrap_content"
import android.os.Bundle;\
    android:layout_height="wrap_content"
import android.view.Menu;\
    android:layout_weight="1"
import android.view.View;\
    android:text="@string/hi_button"
import android.view.View.OnClickListener;\
/>
import android.widget.Button;\
</pre>
import android.widget.EditText;\
Der Knopf braucht neben der Beschriftung, welche in der strings.xml definiert wird, noch eine id, welche wieder im Programm über ein [[Java#Events|Event]] ausgewertet werden kann.
import android.widget.TextView;\
 
import android.widget.Toast;\
==== EditText (Eingabefeld) ====
\
Dieses Feld kann Text vom Benutzer entgegen nehmen. Durch setzen der Eigenschaft ''inputType'' kann man die Eingaben einschränken etwa auf Text, URI, E-Mail, Zahlen, Passwort, Dezimalzahlen, Datum, Uhrzeit, Telefonnummer, usw. (eigene Filter sind möglich).
\
<pre>
public class HelloWorkshopActivity extends Activity implements OnClickListener {\
<EditText
\
     android:id="@+id/name_field"
\ private Button hiButton;\
     android:layout_width="fill_parent"
\ private Button helloButton;\
    android:layout_height="wrap_content"
\
/>
     @Override\
</pre>
     protected void onCreate(Bundle savedInstanceState) {\
Hier bekommt das Feld eine id("name_field"), welche man später im Programm verwenden kann, um den Wert auszulesen.
        super.onCreate(savedInstanceState);\
 
        setContentView(R.layout.main);\
==== ImageView ====
        \
Ermöglicht das Darstellen von Bildern. Diese kann man aus den Ressourcen laden oder vom internen Speicher.
        hiButton = (Button)findViewById(R.id.hi_button);\
 
        hiButton.setOnClickListener(this);\
==== Spinner ====
        \
Entspricht in anderen Sprachen einer Radiobox, bei der man von mehreren Einträgen nur einen auswählen kann.
        helloButton = (Button)findViewById(R.id.hello_button);\
 
        helloButton.setOnClickListener(this);\
==== Switch ====
    } // end onCreate\
Auswahl zwischen zwei Werten. Entspricht einer Checkbox.
\
 
     @Override\
==== TextView (Label) ====
     public boolean onCreateOptionsMenu(Menu menu) {\
Stellt einen nicht bearbeitbaren Text dar etwa für Beschriftungen.
        // Inflate the menu; this adds items to the action bar if it is present.\
<pre>
        getMenuInflater().inflate(R.menu.hello_workshop, menu);\
<TextView
        return true;\
    android:layout_width="fill_parent"
    } // end onCreateOptionsMenu\
    android:layout_height="wrap_content"
    \
    android:layout_marginTop="20dp"
    public void onClick(View v) {\
    android:text="@string/enter_your_name"
        EditText nameField = (EditText) findViewById(R.id.name_field);\
/>
        \
</pre>
        String name = nameField.getText().toString();\
Hier müssten wir noch den String "enter_your_name" in der strings.xml definieren.
\
 
        if (name.length() == 0) {\
==== WebView ====
            new AlertDialog.Builder(this).setMessage(\
Darin lässt sich eine (lokale) Webseite direkt anzeigen. Kann man auch für Hilfeseiten verwenden.
                    R.string.error_name_missing).setNeutralButton(\
 
                    R.string.error_ok,\
== Verweise ==
                    null).show();\
Damit man aus dem Java-Code auf die einzelnen Elemente der Oberfläche zugreifen kann, braucht es eine eindeutige ID, welche man jedem Element vergeben muss, das man im Code ansprechen möchte. Dazu dient die ID bei den Eigenschaften in der <code>Layout-Datei</code>.
            return;\
<pre>
        }\
<TextView
\
android:id="@+id/TextStartDateTime"
        if (v == hiButton || v == helloButton) {\
</pre>
            int resourceId = v == hiButton ? R.string.hi_greeting\
Das + vor der ID ist notwendig, damit Android weiss, dass die Ressource vor dem Zugriff evtl. noch erstellt werden muss.
                    : R.string.hello_greeting;\
 
\
== Ressourcen ==
            String greeting = getResources().getString(resourceId, name);\
Damit man Texte übersetzen oder Bilder verwenden kann, muss man diese im Programm zur Verfügung stellen. Eine kurze Übersicht sieht man im Abschnitt [[Android#Verwendete Dateien|Verwendete Dateien]]. Während Bilder oder Videos einfach referenziert werden, möchte man Sprachen auch übersetzen. Entsprechend verwendet man im Programm nur eine Referenz, welche dann je nach Spracheinstellung auf den richtigen Spracheintrag verweist.
            Toast.makeText(this, greeting, Toast.LENGTH_LONG).show();\
 
\
Für den Zugriff auf diese Dateien, muss man die ID entsprechend als [[Android#Verweise|Verweis]] gestalten.
            TextView greetingField = (TextView) findViewById(R.id.greeting_field);\
 
            greetingField.setText(greeting);\
=== Texte ===
        }\
Standardmässig steht [[Android#strings.xml|strings.xml]] zur Verfügung, doch man kann mit der entsprechenden Referenz auch auf andere Dateien verweisen, falls man etwa pro Activity eine eigene Referenzdatei möchte.
    } // end onClick\
Damit die Referenzdatei auch verwendet wird, muss man im Layout auch darauf verweisen. Dazu wird bei der Eigenschaft des Elements entsprechend nicht einfach ein Text hinterlegt, sondern ein Verweis auf eine Textressource. Anstatt <code>android:text="Beschriftung"</code> heisst es dann <code>@string/LabelStartTime</code>. Damit verweist man auf eine Stringressource mit Namen <code>LabelStartTime</code>. Nun kann in der Datei <code>strings.xml</code> der Eintrag zu den Ressourcen hinzugefügt werden: <code><string name="LabelStartTime">Start</string></code>.
    \
 
} // end class HelloWorkshopActivity\
Will man mehrere Sprachen zur Verfügung stellen, so werden entsprechend Kopien der strings.xml erstellt, doch nicht mehr im Unterordner <code>values</code>, sondern bei englisch etwa <code>values-en</code> oder französisch <code>values-fr</code>. In der Datei werden dann einfach die übersetzen Texte hineingeschrieben und so kann Android je nach Sprachwahl die korrekten Texte anzeigen. Wichtig ist, dass die Datei weiterhin strings.xml heisst oder wie auch immer man die Referenzdatei genannt hat.<br />
</pre>\
Das Erstellen der Ordner kann man auch im Studio mittels Rechtsklick auf den Ressourcen-Ordner <code>values</code> -> New -> Values ressource File durchführen. Dort den Namen der Datei (strings) eingeben und unten locale wählen und danach die gewünschte Sprache (mit Lokalisierung) wählen.<br />
\
Um anschliessend die Übersetzungen zu verwalten, kann man einfach die originale Datei öffnen und nachher rechts oben den Eintrag <code>Open editor</code> wählen, worauf man die Sprachdateien sauber nachtragen kann.
==== main.xml ====\
 
<pre>\
Leider weiss ich noch nicht, wo man die Referenz setzt, wenn man etwa einen anderen Namen oder mehrere Dateien möchte. Der Verweis kann entweder manuell in den Dateien erstellt werden oder über einen Rechtsklick auf den Eintrag in der layout.xml Datei mit dem Menü "Extract string ressource". Es ist auch direkt im Designer mittels Doppelklick aufs Element möglich. Dort bei den Eigenschaften verweist man dann mit "Add New Ressource -> new string value" auf den String. Siehe Im Androidbuch Kapitel 3.3.2 Ressourcen für die Texte ab Seite 83.
<?xml version="1.0" encoding="utf-8"?>\
 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\
=== Bilder und Videos ===
    android:orientation="vertical"\
 
    android:layout_width="fill_parent"\
=== Abstände ===
    android:layout_height="fill_parent"\
Siehe im Androidbuch ab Seite 92 das Kapitel Innenabstand als Ressource.<br />
    >\
Damit man Abstände nicht manuell anpassen muss, kann man diese genauso wie Texte als Ressource auslagern und darauf verweisen. So muss man anschliessend die Anpassungen nur noch in der Ressourcendatei vornehmen und kann dort auf mehrere Orte verweisen. Normalerweise wird dafür die Datei <code>dimens.xml</code> verwendet.
    \
 
\ <TextView  \
Die Abstände können in folgenden Masseinheiten angegeben werden:
    \ android:id="@+id/greeting_field"\
* dp oder dip: Auflösungsunabhängiges Pixel, welches je nach Auflösung grösser dargestellt wird, damit es immer gleich gross aussieht.
\     android:layout_width="fill_parent" \
* sp: Ähnlich dp, doch kann es skaliert werden. Wird meist für Texte verwendet.
\     android:layout_height="wrap_content" \
* pt: 1/72 Zoll fix
\     android:text="@string/hello"\
* px: Reales Pixel. Entsprechend wäschst oder schrumpft eine solche Angabe je nach Auflösung
\ />\
* mm: Milimeter
\ \
* in: Zoll (inch)
\ <TextView  \
 
\     android:layout_width="fill_parent" \
== Services ==
\     android:layout_height="wrap_content" \
Laufen im Hintergrund. Werden verwendet, um Operationen aufzuführen, welche länger dauern und daher ausgelagert werden, wie etwa das herunterladen einer Datei von einem Server.
\     android:layout_marginTop="20dp"\
 
\     android:text="@string/enter_your_name"\
== Content Provider ==
    />\
Sind die Schnittstellen nach aussen. So kann man mit der entsprechenden Berechtigung etwa die Kontaktdaten abfragen oder einen Telefonanruf starten, ohne selber eine Telefon-Activity programmieren zu müssen. Damit nicht jede App einfach auf ein anderes Programm zugreifen kann, muss man den Zugriff in der [[Android#AndroidManifest.xml|AndroidManifest.xml]] anmelden und der Benutzer muss beim ersten Zugriff dies erlauben.
\ \
 
\ <EditText\
== Broadcast Receiver ==
\     android:id="@+id/name_field"\
Sind Benachrichtigungen, welche vom Betriebssystem und zum Teil auch von Apps versandt werden und auf die man entsprechend reagieren kann. Dies kann etwa "Power connected" oder Airplane Mode" sein. Eine Liste enthält dieser Link: https://developer.android.com/guide/components/broadcasts
\     android:layout_width="fill_parent" \
 
\     android:layout_height="wrap_content" \
== Programmierbeispiel komplett ==
\ >\
Wenn man ein Android-Projekt unter Eclipse erstellt, so generiert Eclipse mehrere [[Android#Verwendete Dateien|Dateien]]. Hier werden nun alphabetisch alle Dateien aufgeführt, welche im [[Android#Entwicklungsumgebung|Beispielprojekt]] manuell angepasst wurden.
\ </EditText>\
\ \
==== AndroidManifest.xml ====
\ <LinearLayout \
<pre>
\     android:orientation="horizontal"\
<?xml version="1.0" encoding="utf-8"?>
\     android:layout_width="fill_parent"\
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
\     android:layout_height="wrap_content"\
    package="com.example.helloworkshop"
    >\
    android:versionCode="1"
\     <Button \
    android:versionName="1.0" >
\         android:id="@+id/hi_button"\
 
\         android:layout_width="wrap_content"\
    <uses-sdk
\         android:layout_height="wrap_content"\
        android:minSdkVersion="8"
\         android:layout_weight="1"\
        android:targetSdkVersion="16" />
\         android:text="@string/hi_button" \
   
\     />\
    <supports-screens
\     <Button \
        android:anyDensity="true"
\         android:id="@+id/hello_button"\
        android:largeScreens="true"
\         android:layout_width="wrap_content"\
        android:smallScreens="true" />
\         android:layout_height="wrap_content"\
 
\         android:layout_weight="1"\
    <application
\         android:text="@string/hello_button" \
        android:allowBackup="true"
\     />\
        android:icon="@drawable/ic_launcher"
\ </LinearLayout>\
        android:label="@string/app_name"
\
        android:theme="@style/AppTheme" >
</LinearLayout>\
        <activity
</pre>\
            android:name="com.example.helloworkshop.HelloWorkshopActivity"
\
            android:label="@string/app_name" >
==== strings.xml ====\
            <intent-filter>
<pre>\
                <action android:name="android.intent.action.MAIN" />
<?xml version="1.0" encoding="utf-8"?>\
 
<resources>\
                <category android:name="android.intent.category.LAUNCHER" />
    <string name="action_settings">Settings</string>\
            </intent-filter>
    <string name="app_name">Hello Workshop</string>\
        </activity>
    <string name="enter_your_name">Gib bitte Deinen Namen ein:</string>\
    </application>
\ <string name="error_name_missing">Please enter your name.</string>\
 
\ <string name="error_ok">OK</string>\
</manifest>
     <string name="hello">Hallo Welt Workshop!</string>\
</pre>
\ <string name="hello_button">Say Hello!</string>\
 
\ <string name="hello_greeting">Hello %s!</string>\
=== HelloWorkshopActivity.java ===
     <string name="hi_button">Say Hi!</string>\
<pre>
\ <string name="hi_greeting">Hi %s!</string>\
package com.example.helloworkshop;
</resources>\
 
</pre>\
import android.app.Activity;
== Programm auf Gerät verschieben ==\
import android.app.AlertDialog;
=== Mittels Google-Konto ===\
import android.os.Bundle;
# Im Ordner bin/res befindet sich die Datei "Projektname.apk". Diese ist die notwendige Datei.\
import android.view.Menu;
# Die Datei als Anhnag ans Google-Konto senden\
import android.view.View;
# Den Anhang im Gerät anwählen und danach installieren. Will das Gerät dies nicht, kann evtl. das Programm AKPatcher verwendet werden (hat bei mir aber immer nur den Info-Screen angezeigt)\
import android.view.View.OnClickListener;
# Anschliessend kann die App übers App-Menü gestartet werden\
import android.widget.Button;
\
import android.widget.EditText;
=== Mittels USB-Verbindung ===\
import android.widget.TextView;
Folgende Bildergalerie verwenden:\
import android.widget.Toast;
http://www.chip.de/bildergalerie/So-geht-s-APKs-via-USB-installieren-Galerie_56637615.html\
 
# Einstellung: Unbekannte Quellen zulassen\
 
# Verbinden im Massenspeicher Modus\
public class HelloWorkshopActivity extends Activity implements OnClickListener {
# APK-Datei auf das Gerät in den gewünschten Ordner kopieren \
 
# Mit dem Dateimanager ins obige Verzeichnis navigieren und die Datei anwählen und installieren\
private Button hiButton;
\
private Button helloButton;
== Links ==\
 
{| class="wikitable"\
    @Override
|-\
    protected void onCreate(Bundle savedInstanceState) {
! Link !! Beschreibung !! Niveau\
        super.onCreate(savedInstanceState);
|-\
        setContentView(R.layout.main);
| [[Java|Java]] || Java-Wiki || Anfänger\
       
|-\
        hiButton = (Button)findViewById(R.id.hi_button);
| http://www.androidpit.de/de/android/wiki/view/Android_Anf%C3%A4nger_Workshop || Android-Einführungstutorial deutsch || Anfänger\
        hiButton.setOnClickListener(this);
|-\
       
| http://www.vogella.com/articles/Android/article.html || Android-Einführungstutorial englisch || Anfänger-Fortgeschrittene\
        helloButton = (Button)findViewById(R.id.hello_button);
|-\
        helloButton.setOnClickListener(this);
| http://www.makeuseof.com/tag/write-google-android-application/ || Android erste Applikation von Google englisch || Anfänger\
    } // end onCreate
|-\
 
| http://www.kammerath.net/android-app-programmieren.html || Android app programmieren deutsch || Anfänger\
    @Override
|-\
    public boolean onCreateOptionsMenu(Menu menu) {
| http://www.vogella.com/articles/AndroidIntent/article.html || Android Intents englisch || Fortgeschrittene\
        // Inflate the menu; this adds items to the action bar if it is present.
|}\
        getMenuInflater().inflate(R.menu.hello_workshop, menu);
        return true;
    } // end onCreateOptionsMenu
 
    public void onClick(View v) {
        EditText nameField = (EditText) findViewById(R.id.name_field);
 
        String name = nameField.getText().toString();
 
        if (name.length() == 0) {
            new AlertDialog.Builder(this).setMessage(
                    R.string.error_name_missing).setNeutralButton(
                    R.string.error_ok,
                    null).show();
            return;
        }
 
        if (v == hiButton || v == helloButton) {
            int resourceId = v == hiButton ? R.string.hi_greeting
                    : R.string.hello_greeting;
 
            String greeting = getResources().getString(resourceId, name);
            Toast.makeText(this, greeting, Toast.LENGTH_LONG).show();
 
            TextView greetingField = (TextView) findViewById(R.id.greeting_field);
            greetingField.setText(greeting);
        }
    } // end onClick
   
} // end class HelloWorkshopActivity
</pre>
 
=== main.xml ===
<pre>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
 
<TextView 
    android:id="@+id/greeting_field"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
/>
 
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:text="@string/enter_your_name"
    />
<EditText
    android:id="@+id/name_field"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
>
</EditText>
<LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    <Button
        android:id="@+id/hi_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/hi_button"
    />
    <Button
        android:id="@+id/hello_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/hello_button"
    />
</LinearLayout>
 
</LinearLayout>
</pre>
 
=== strings.xml ===
<pre>
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="action_settings">Settings</string>
    <string name="app_name">Hello Workshop</string>
    <string name="enter_your_name">Gib bitte Deinen Namen ein:</string>
    <string name="error_name_missing">Please enter your name.</string>
    <string name="error_ok">OK</string>
     <string name="hello">Hallo Welt Workshop!</string>
    <string name="hello_button">Say Hello!</string>
    <string name="hello_greeting">Hello %s!</string>
     <string name="hi_button">Say Hi!</string>
    <string name="hi_greeting">Hi %s!</string>
</resources>
</pre>
 
= Programm auf Gerät verschieben =
== Mittels Google-Konto ==
# Im Ordner bin/res befindet sich die Datei "Projektname.apk". Diese ist die notwendige Datei.
# Die Datei als Anhnag ans Google-Konto senden
# Den Anhang im Gerät anwählen und danach installieren. Will das Gerät dies nicht, kann evtl. das Programm AKPatcher verwendet werden (hat bei mir aber immer nur den Info-Screen angezeigt)
# Anschliessend kann die App übers App-Menü gestartet werden
 
== Mittels USB-Verbindung ==
Folgende Bildergalerie verwenden:
http://www.chip.de/bildergalerie/So-geht-s-APKs-via-USB-installieren-Galerie_56637615.html
# Einstellung: Unbekannte Quellen zulassen
# Verbinden im Massenspeicher Modus
# APK-Datei auf das Gerät in den gewünschten Ordner kopieren  
# Mit dem Dateimanager ins obige Verzeichnis navigieren und die Datei anwählen und installieren
 
= Links =
{| class="wikitable"
|-
! Link !! Beschreibung !! Niveau
|-
| [[Java|Java]] || Java-Wiki || Anfänger
|-
| http://www.vogella.com/articles/Android/article.html || Android-Einführungstutorial englisch || Anfänger-Fortgeschrittene
|-
| http://www.makeuseof.com/tag/write-google-android-application/ || Android erste Applikation von Google englisch || Anfänger
|-
| http://www.kammerath.net/android-app-programmieren.html || Android app programmieren deutsch || Anfänger
|-
| http://www.vogella.com/articles/AndroidIntent/article.html || Android Intents englisch || Fortgeschrittene
|}
[[Kategorie:Computer]][[Kategorie:Programmierung]]
[[Kategorie:Computer]][[Kategorie:Programmierung]]

Aktuelle Version vom 15. Februar 2021, 21:27 Uhr

Einführung

  • Fast alle Java-Klassen stehen zur Verfügung plus Verschlüsselung, HTTP, JSON, XML Bibliotheken
  • Für die Programmierung steht in neueren Versionen Kotlin zur Verfügung.
  • Keine main()-Funktion - stattdessen: lose gekoppelte Komponenten, eine oder mehrere davon als Einstiegspunkt definierbar
  • Wichtigste Komponente: "Activity" - entspricht einem sichtbaren Fenster auf dem Screen (Ähnlich wie Tabs eines Browsers). Man kann etwa ein Programm mit Screen 1 (Hauptseite) aufrufen oder direkt Screen 2 (Unterseite). Der Aufruf geschieht über die App-Icons.

Entwicklungsumgebung

Zum konkreten Einrichten siehe das Buch Android Apps programmieren). Kapitel 2.1.1 Installation.

Neues Projekt

Mit dem Assistenten wird ein neues Projekt erstellt. Im Android-Buch hat es eine bebilderte Anleitung im Kapitel 3.1.1 ab Seite 62. Je nach Version kann es hier sein, dass gewisse Optionen anders heissen oder Felder neu hinzukommen oder verschwinden. Entsprechend muss man halt schauen, was es braucht oder im Internet nachschauen.
Wähle "File" → "New" → "New Project..."; im "New Project"-Dialog wähle "A new Android Project" aus dem "Android" Order.

Füll den "New Android Project"-Dialog wie folgt aus:

  • Project/Application name: "Hello Workshop"
  • Company domain: Beliebige domain, die man entweder besitzt oder die es nicht gibt. testprojekt.test.tt, zeit.dict.ch. Ergibt umgekehrt den package name (tt.test.testprojekt, ch.dict.zeit).
  • Verwende die "default location" oder lege eine andere Location fest
  • Je nach Kenntnissen und Bedürfnissen kann man auch c++ und/oder Kotlin einbinden
  • Build target: API21 oder was notwendig wählen. Wenn man bestimmte Funktionen braucht, muss man halt unter "Help me choose" schauen, welche Version welches Feature eingeführt hat (Bluetooth usw.). Aktuelle Daten der Verwendung der Geräte unter: https://developer.android.com/about/dashboards
  • Auswahl der gewünschten Vorlage (No Activity, Basic, usw.)
  • Activity Name: "HelloWorkshopActivity" -> entspricht der Java-Klasse der Haupt-Activity und wird ohne Vorgabe entsprechend MainActivity genannt. Klassen, welche Fenster steuern, sollten als Konvention auf "Activity" enden, doch dies ist natürlich nur eine Konvention. Damit man weiss, was die Klasse tut, sollte man sie entsprechend der Projektvorgaben nennen.
  • Layout Name: "activity_hello_workshop" -> Layouts sollten klein geschrieben werden und mit dem "_" aufgeteilt werden. Layouts für Activities sollten entsprechend mit "activity_" beginnen.

Klicke auf den "Finish"-Button und warte, bis das Projekt erstellt wurde.

Emulator

Gerät einrichten

Falls kein Andoid-Gerät vorhanden ist, oder das gewünschte Gerät fehlt.

Klicke auf das "Android SDK and AVD manager"-Icon in der Icon-Leiste. Klicke auf "New" Im "Create new AVD"-Dialog, gib folgendes ein:

  • Name: "G1"
  • Target: "Android 1.6 - API Level 4"
  • SD Card Size: "1024" MiB
  • Skin: Built-in: "Default (HVGA)"

Dann klicke auf "Create AVD" (kann eine Weile - bis zu einigen Minuten - dauern)

Bei der Geräteauswahl kann man auch Geräte mit Playstore anwählen, doch dann kann man bei diesen Geräten keinen Root-Zugriff machen. Man erkennt diese Möglichkeit bei der Auswahl, wenn es ein Icon in der betreffenden Spalte hat.

App auf Gerät testen

Beim Start auf das Play-Icon wird das verknüpfte Gerät gestartet und die App ausgeführt.

Hier kann es sein, dass ein Gerät gestartet wird, doch die App startet nicht und auf der Konsole kommt die Meldung: "Installation did not succeed. The application could not be installed." In diesem Fall wird zwar im AVD-Manager das korrekte Geräte angezeigt, doch unten rechts im Studio beim Design ist ein anderes Gerät angewählt. Dadurch ergibt sich keine Übereinstimmung vom Layout und vom Gerät und somit kann die App nicht starten. In diesem Fall muss das Gerät beim Designer umgestellt werden, auf das vom AVD-Manager und nach einem Neustart der App wird dies auch angezeigt, wenn es nicht noch weitere Fehler gibt.

Verwendete Dateien

Um die verwendeten Dateien zu sehen, muss man den Navigator einblenden, der auf der linken Seite zusammengeklappt werden kann. Anschliessend muss man dann oberhalb der Ansicht unterhalb vom Projektnamen die Art der Darstellung wählen. Falls man mehrere Projekte offen hat, zum gewünschten Projekt navigieren.

Bei der Ansicht Android wird das Projekt "logisch" aufgelistet und entsprechend Dateien, die zusammengehören, wie etwa die Ressourcen zusammen aufgeführt.
Will man hingegen die wirkliche Datenstruktur sehen, so wechselt man auf Project Files, welches den Baum auflistet.
Die Projekte werden standardmässig unter folgendem Pfad gespeichert:
C:\Users\<Benutzername>\AndroidStudioProjects\<Projektname>

Die folgende Tabelle gibt den Stand von Nov. 2020 mit Android Studio 4.1 wieder. Die Entwicklung ist dynamisch und daher kann es gut sein, dass Dateien immer noch verschoben werden und auch Verzeichnisse anders aufgebaut werden. Entsprechend muss man manche Dateien halt suchen, wenn sie nicht am entsprechenden Ort gefunden werden können oder man schaut im Studio, wohin referenziert wird.
Da im Projekt sehr viele Dateien involviert sind, werden "interne" Verzeichnisse und Dateien wie etwa die diversen Build- und Testverzeichnisse nicht aufgeführt. Auch Verzeichnisse, welche nur für die Versionsverwaltung oder fürs Kompilieren verwendet werden, werden nicht aufgelistet.

Datei/Ordner Beschreibung
/app Ordner in dem sich das aktuelle Modul befindet. Bei grösseren Projekten können mehrere Module definiert werden.
/app/src Source-Ordner aller Klassen des Moduls
/app/src/main/AndroidManifest.xml Linked alle wichtigen Dateien des Projekts. Dort werden auch die Berechtigungen fürs Projekt angemeldet (Datei- und Internetzugriff usw.). Dazu muss man dort Services anmelden oder wenn man ContentProvider für externe Apps bereitstellt.
/app/src/main/java/<domain>/<projektname>/MainActivity.java Klasse der Haupt-Activity. Verweist mit setContentView(R.layout.main); auf das Layout, welches in der main.xml definiert wurde.
/app/src/main/res Layout- Sprach- und Bilddateien.
/app/src/main/res/drawable Bilddateien. Diese werden in den entsprechenden Unterordnern auflösungsabhängig gespeichert, damit die App auch bei unterschiedlichen Geräten in etwa gleich ausschaut.
/app/src/main/res/layout Layouts. Da das Layout beim drehen meist etwas anders angezeigt wird, gibt es auch den Ordner layout-land, in dem das "landscape" Layout abgelegt wird.
/app/src/main/res/layout/activity_main.xml Das Layout wird als XML-Datei erstellt. Die Ressourcen werden dort entsprechend auf die Text-Ressource-Dateien verwiesen, damit man die App nur einmal kompilieren muss und trotzdem verschiedene Sprachen anbieten kann. Wird erstellt aus dem Namen, den man beim generieren des Projekts für das Layout wählt. Ohne Anpassung wird er aus dem Projektnamen gebildet.
/app/src/main/res/menu Falls man ein Menü in der Action-Bar anbieten will, werden die Ressourcen dafür hier angelegt. Standardmässig wird das Manü aber nicht angelegt.
/app/src/main/res/mipmap* Icons. Diese werden in den entsprechenden Unterordnern auflösungsabhängig gespeichert, damit diese auch bei unterschiedlichen Geräten in etwa gleich ausschauen. (xxxhdpi = 192 x 192 Pixel – 640 dpi / xxhdpi = 144 x 144 Pixel – 480 dpi / xhdpi = 96 x 96 Pixel – 320 dpi / hdpi = 72 x 72 Pixel – 240 dpi / mdpi = 48 x 48 Pixel – 160 dpi / ldpi = 36 x 36 Pixel – 120 dpi)
/app/src/main/res/values(-xx) Text-Ressource-Dateien. Diese Dateien enthalten Wertepaare für verschiedene Anwendungen wie Farben oder Strings, welche man dann in verschiedene Sprachen überstzene kann und die dann das entsprechende Länderkürzel angehängt bekommen.
/assets Ordner für Binär-Dateien (alles, was Android nicht selbst verwaltet). Wird standardmässig nicht angelegt.
/gradle Wird für die Versionsverwaltung eingesetzt.

AndroidManifest.xml

Legt diverse Werte zum Aussehen und Verhalten des Programms fest. https://developer.android.com/guide/topics/manifest/manifest-intro

Folgende Einträge sind für die Unterstützung von unterschiedlichen Geräte möglich. Evtl. bei neueren Versionen nicht mehr notwendig.

<supports-screens android:anyDensity="true"
                  android:largeScreens="true" 
                  android:smallScreens="true" />
  • anyDensity für hohe Auflösungen
  • largeScreens bei grossen Displays
  • smallScreens für kleine Displays

Für Berechtigungen werden Einträge in folgender Weise hinzugefügt:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />

Wenn man Eclipse verwendet, kann man aus den Warnungen ableiten, wenn man etwas falsch definiert. Dazu kann man entweder die Datei direkt bearbeiten oder dies über den Tab umstellen und manches direkt grafisch anpassen.

Ein Beispiel ist im Android-Buch auf Seite 39 (Kap. 2.2.2 App-Bausteine) aufgeführt.

MainActivity.java

Enthält, wie unter Programmierung gezeigt, das Hauptprogramm. Der Name wird entsprechend bei Projekteröffnung festgelegt. Hier werden unter anderem die Elemente definiert.

private Button hiButton; private Button helloButton;

strings.xml

Legt die Werte für die Strings fest. Hier wurden zwei Srings "hello" und "app_name" definiert, welche nun in anderen Dateien verwendet werden können (Layout oder Programm). Siehe dazu den Abschnitt Texte.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, HelloWorkshopActivity!</string>
    <string name="app_name">Hello Workshop</string>
</resources>

Android-App kompilieren (Gradle)

Im Gegensatz zu einem "normalen" Programm, müssen bei einer Android-App viele verschiedene Tools zusammenarbeiten, um am Schluss eine lauffähige App bereitstellen zu können. Gradle ist ein Build Management Tool für Java, das diese Aufgaben bündelt.

  1. Herunterladen von externen Abhängigkeiten (externe Bibliotheken)
  2. Kompilieren der Java-Dateien in DEX
  3. Kompilieren der Ressourcen (Bilder, Icons, usw.)
  4. Verpacken als APK-Datei (DEX + Ressourcen)
  5. Signieren der APK-Datei
  6. Optimieren der App auf Speicherverbrauch

Gradle benutzt eine auf Groovy aufbauende DSL (Domain Specific Language). Wenn man weiss wie und es braucht, so kann man den Build-Prozess entsprechend anpassen. Siehe dazu den Link: https://developer.android.com/studio/build

Für die Einbindung der externen Bibliotheken wird das Maven-Repository eingebunden.

Programmierung

Zustände einer App

Grafik aus dem Androidbuch.

Zyklus einer App







Zuerst ein Beispiel, welches unten erklärt wird:

class MyActivity extends Activity {

  onCreate {
    View view = ... // erstellt den sichtbaren Teil
    setContentView(view);
    ...
  } // end Eventhandler onCreate

  onClick {
    ...
    Intent intent = ... // Zugriff auf externes Programm
    startActivity (intent);
  } // end Eventhandler onClick

} // end class MyActivity

Activity

  • definiert eine "View", zur Anzeige auf dem Screen. Entspricht einem Fenster.
  • behandelt "Events" (z. B. Klick auf einen Button)
  • benutzt "Intents", um andere Activities zu starten

Fragment

Wurden mit Android 3.1 eingeführt und sind selbständige Teilbereiche einer Activity. Können entsprechend auf verschiedenen Activities wiederverwendet oder in einer Activity mehrfach eingesetzt werden.

View

  • eine "View" ist der sichtbare Teil der Activity
  • definiert in einer XML-Layout-Datei (oder im Code)

Events / Programmablauf

  • werden ausgelöst, wenn etwas geschieht (z. B ein Button geklickt wird)
  • ruft eine Listener-Methode auf, sofern ein Listener definiert ist

Ein Beispiel mit mehreren Events für einen Programmablauf sieht man hier: http://www.androidpit.de/de/android/wiki/view/Datei:Beginners_Workshop_Activity_LC.png
Um Datenverlust oder den Verlust des Zustands einer Activity zu vermeiden, müssen die Daten/der Zustand der Activity gesichert werden, wenn diese pausiert (nicht mehr im Vordergrund, aber noch sichtbar) oder gestoppt (nicht mehr sichtbar) wird.

onClick()

  • Aufruf beim Drücken auf einen Button
EditText nameField = (EditText) findViewById(R.id.name_field);
String name = nameField.getText().toString();
if (name.length() == 0) {
    new AlertDialog.Builder(this) 
                   .setMessage(R.string.error_name_missing)
                   .setNeutralButton(R.string.error_ok, null)
                   .show();
    return;
} // end if

onCreate()

  • wird einmalig beim Programmstart aufgerufen
  • muss die View und die Elemente darin definieren
  • springt anschliessend weiter nach onStart()
  • definiert die Listener-Aufrufe
hiButton = (Button)findViewById(R.id.hi_button);
hiButton.setOnClickListener(this);
helloButton = (Button)findViewById(R.id.hello_button);
helloButton.setOnClickListener(this);

onDestroy()

  • Wird nur aufgerufen, wenn das Programm explizit beendet wird

onPause()

  • Geht weiter nach onResume, wenn es wieder in den Vordergrund geholt wird oder nach onStop, wenn es gar nicht mehr sichtbar ist
  • Da das Programm bei Speichermangel in diesem Zustand "abgeschossen" werden kann, müssen spätestens hier die Benutzerdaten gesichert werden

onRestart()

  • Falls das Programm gestoppt wurde, doch noch nicht wegen Speichermangels aus dem RAM entfernt wurde und nun wieder in den Vordergrund kommt, wird diese Methode aufgerufen
  • Springt anschliessend direkt nach onStart()

onResume()

  • Wird jedes Mal aufgerufen, wenn die App nach einer Pause (wieder) in den Vordergrund kommt

onStart()

  • Springt weiter nach onResume()

onStop()

  • Wird aufgerufen, wenn das Programm nicht mehr sichtbar ist
  • Je nach weiterer Folge, geht der Programmlauf weiter mit onDestroy oder onRestart.

Intent

  • startet eine andere Activity ("öffnet ein neues Fenster")
  • kann Daten an die zu startende Activity übergeben
  • kann Activities aus anderen Apps starten!

Layouts und Elemente

Siehe im Androidbuch Kapitel 2.2.3 ab Seite 42. Wie oberhalb erwähnt, wird in /res/layout/<NameMainActivity>.xml das Layout der Hauptdatei festgelegt. Das heisst, hier werden die Elemente festgelegt. Layouts werden extra in XML-Dateien erstellt, damit man eine exakte Trennung zum Code erhält, auch wenn man natürlich das Layout auch im Java-Code erstellen kann. Alle sichtbaren Elemente leiten sich von der Basisklasse View ab, wobei die Elemente in zwei Gruppen aufgeteilt werden:

  • ViewGroup
  • View

Wobei jede ViewGroup Views und weitere ViewGroups enthalten kann.

ViewGroups (Layouts)

Siehe im Androidbuch ab Seite 75 Kapitel 3.3 Layout-Erstellung. Folgende ViewGroups werden standardmässig unterstützt:

  • LinearLayout: Die enthaltenen Views werden unter- ober nebeneinander aufgelistet. Je nachdem, wie man die Eigenschaft orientation gesetzt hat. Die enthaltenen Views kann man mit %-Angaben aufteilen.
  • RelativeLayout: Ordnet die Views im Verhältnis zu sich selbst oder anderen Elementen an. Dies kann sein: rechts von View 2, oberhalb von View 3, zentriert im Container, unterhalb vom oberen Rand, usw.
  • TableLayout: Ordnet die Views als Zeilen und Spalten an. Die Breite der Spalten wird durch die Breite des Inhalts bestimmt.
  • GridLayout: Ähnlich wie TableLayout, doch braucht keinen Container. Dazu können die Zellen gewichtet aufgeteilt werden (prozentual). Für Abstände kann man auf die Eigenschaft Space zurückgreifen. Views können über mehrere Zeilen/Spalten "aufgespannt" werden. Dies ermöglicht komplexe Layouts, ohne dass man dafür mehrere Layouts verschachteln müsste.
  • ConstraintLayout: Verwandt mit RelativeLayout, doch flexibler. Die Elemente stehen zwar in Beziehung, doch diese Kopplung ist loser und ermöglicht präzise Positionierungen. Die Beziehungen werden durch "Spannfedern" dargestellt.
  • ListView: Wird normalerweise nur verwendet, um Daten etwa aus einer Datenbank automatisch abzufüllen und als Liste darzustellen.
  • GridView: Hier werden die Daten wie bei einer ListView abgefüllt, doch etwa wie die Bilderansicht im Explorer in einem Gitter dargestellt.

vertikale und horizontale Layouts

Layouts können auch geschachtelt werden. Das Hauptlayout ist meist vertikal.

Vertikales Layout mit einem Titel:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
>
  <TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
  />
</LinearLayout>

Der Inhalt des Strings wird in der /res/layout/strings.xml definiert

Horizontales Layout mit zwei Knöpfen.

<LinearLayout 
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
     >
    <Button 
        android:id="@+id/hi_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/hi_button" 
        />
    <Button 
        android:id="@+id/hello_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/hello_button" 
        />
</LinearLayout>

Views (Elemente)

Die Elemente werden wie erwähnt in den Layouts platziert und vom Benutzer verwendet, während die ViewGroup im Hintergrund "nur" den Platz aufteilt. Die Elemente werden am einfachsten in der "Designer-Ansicht" auf der Activity verteilt, da man so nicht alles im XML-Code erstellen muss, sondern nur noch die Beziehungen oder Positionen sauber setzen muss.

Button (Knopf)

Ermöglicht das entgegennehmen von Aktionen und deren Auswertung im Code.

<Button 
    android:id="@+id/hi_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="@string/hi_button" 
/>

Der Knopf braucht neben der Beschriftung, welche in der strings.xml definiert wird, noch eine id, welche wieder im Programm über ein Event ausgewertet werden kann.

EditText (Eingabefeld)

Dieses Feld kann Text vom Benutzer entgegen nehmen. Durch setzen der Eigenschaft inputType kann man die Eingaben einschränken etwa auf Text, URI, E-Mail, Zahlen, Passwort, Dezimalzahlen, Datum, Uhrzeit, Telefonnummer, usw. (eigene Filter sind möglich).

<EditText
    android:id="@+id/name_field"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
/>

Hier bekommt das Feld eine id("name_field"), welche man später im Programm verwenden kann, um den Wert auszulesen.

ImageView

Ermöglicht das Darstellen von Bildern. Diese kann man aus den Ressourcen laden oder vom internen Speicher.

Spinner

Entspricht in anderen Sprachen einer Radiobox, bei der man von mehreren Einträgen nur einen auswählen kann.

Switch

Auswahl zwischen zwei Werten. Entspricht einer Checkbox.

TextView (Label)

Stellt einen nicht bearbeitbaren Text dar etwa für Beschriftungen.

<TextView
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginTop="20dp"
    android:text="@string/enter_your_name"
/>

Hier müssten wir noch den String "enter_your_name" in der strings.xml definieren.

WebView

Darin lässt sich eine (lokale) Webseite direkt anzeigen. Kann man auch für Hilfeseiten verwenden.

Verweise

Damit man aus dem Java-Code auf die einzelnen Elemente der Oberfläche zugreifen kann, braucht es eine eindeutige ID, welche man jedem Element vergeben muss, das man im Code ansprechen möchte. Dazu dient die ID bei den Eigenschaften in der Layout-Datei.

<TextView
android:id="@+id/TextStartDateTime"

Das + vor der ID ist notwendig, damit Android weiss, dass die Ressource vor dem Zugriff evtl. noch erstellt werden muss.

Ressourcen

Damit man Texte übersetzen oder Bilder verwenden kann, muss man diese im Programm zur Verfügung stellen. Eine kurze Übersicht sieht man im Abschnitt Verwendete Dateien. Während Bilder oder Videos einfach referenziert werden, möchte man Sprachen auch übersetzen. Entsprechend verwendet man im Programm nur eine Referenz, welche dann je nach Spracheinstellung auf den richtigen Spracheintrag verweist.

Für den Zugriff auf diese Dateien, muss man die ID entsprechend als Verweis gestalten.

Texte

Standardmässig steht strings.xml zur Verfügung, doch man kann mit der entsprechenden Referenz auch auf andere Dateien verweisen, falls man etwa pro Activity eine eigene Referenzdatei möchte. Damit die Referenzdatei auch verwendet wird, muss man im Layout auch darauf verweisen. Dazu wird bei der Eigenschaft des Elements entsprechend nicht einfach ein Text hinterlegt, sondern ein Verweis auf eine Textressource. Anstatt android:text="Beschriftung" heisst es dann @string/LabelStartTime. Damit verweist man auf eine Stringressource mit Namen LabelStartTime. Nun kann in der Datei strings.xml der Eintrag zu den Ressourcen hinzugefügt werden: <string name="LabelStartTime">Start</string>.

Will man mehrere Sprachen zur Verfügung stellen, so werden entsprechend Kopien der strings.xml erstellt, doch nicht mehr im Unterordner values, sondern bei englisch etwa values-en oder französisch values-fr. In der Datei werden dann einfach die übersetzen Texte hineingeschrieben und so kann Android je nach Sprachwahl die korrekten Texte anzeigen. Wichtig ist, dass die Datei weiterhin strings.xml heisst oder wie auch immer man die Referenzdatei genannt hat.
Das Erstellen der Ordner kann man auch im Studio mittels Rechtsklick auf den Ressourcen-Ordner values -> New -> Values ressource File durchführen. Dort den Namen der Datei (strings) eingeben und unten locale wählen und danach die gewünschte Sprache (mit Lokalisierung) wählen.
Um anschliessend die Übersetzungen zu verwalten, kann man einfach die originale Datei öffnen und nachher rechts oben den Eintrag Open editor wählen, worauf man die Sprachdateien sauber nachtragen kann.

Leider weiss ich noch nicht, wo man die Referenz setzt, wenn man etwa einen anderen Namen oder mehrere Dateien möchte. Der Verweis kann entweder manuell in den Dateien erstellt werden oder über einen Rechtsklick auf den Eintrag in der layout.xml Datei mit dem Menü "Extract string ressource". Es ist auch direkt im Designer mittels Doppelklick aufs Element möglich. Dort bei den Eigenschaften verweist man dann mit "Add New Ressource -> new string value" auf den String. Siehe Im Androidbuch Kapitel 3.3.2 Ressourcen für die Texte ab Seite 83.

Bilder und Videos

Abstände

Siehe im Androidbuch ab Seite 92 das Kapitel Innenabstand als Ressource.
Damit man Abstände nicht manuell anpassen muss, kann man diese genauso wie Texte als Ressource auslagern und darauf verweisen. So muss man anschliessend die Anpassungen nur noch in der Ressourcendatei vornehmen und kann dort auf mehrere Orte verweisen. Normalerweise wird dafür die Datei dimens.xml verwendet.

Die Abstände können in folgenden Masseinheiten angegeben werden:

  • dp oder dip: Auflösungsunabhängiges Pixel, welches je nach Auflösung grösser dargestellt wird, damit es immer gleich gross aussieht.
  • sp: Ähnlich dp, doch kann es skaliert werden. Wird meist für Texte verwendet.
  • pt: 1/72 Zoll fix
  • px: Reales Pixel. Entsprechend wäschst oder schrumpft eine solche Angabe je nach Auflösung
  • mm: Milimeter
  • in: Zoll (inch)

Services

Laufen im Hintergrund. Werden verwendet, um Operationen aufzuführen, welche länger dauern und daher ausgelagert werden, wie etwa das herunterladen einer Datei von einem Server.

Content Provider

Sind die Schnittstellen nach aussen. So kann man mit der entsprechenden Berechtigung etwa die Kontaktdaten abfragen oder einen Telefonanruf starten, ohne selber eine Telefon-Activity programmieren zu müssen. Damit nicht jede App einfach auf ein anderes Programm zugreifen kann, muss man den Zugriff in der AndroidManifest.xml anmelden und der Benutzer muss beim ersten Zugriff dies erlauben.

Broadcast Receiver

Sind Benachrichtigungen, welche vom Betriebssystem und zum Teil auch von Apps versandt werden und auf die man entsprechend reagieren kann. Dies kann etwa "Power connected" oder Airplane Mode" sein. Eine Liste enthält dieser Link: https://developer.android.com/guide/components/broadcasts

Programmierbeispiel komplett

Wenn man ein Android-Projekt unter Eclipse erstellt, so generiert Eclipse mehrere Dateien. Hier werden nun alphabetisch alle Dateien aufgeführt, welche im Beispielprojekt manuell angepasst wurden.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloworkshop"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />
    
    <supports-screens 
        android:anyDensity="true"
        android:largeScreens="true" 
        android:smallScreens="true" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.helloworkshop.HelloWorkshopActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

HelloWorkshopActivity.java

package com.example.helloworkshop;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;


public class HelloWorkshopActivity extends Activity implements OnClickListener {

	private Button hiButton;
	private Button helloButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        hiButton = (Button)findViewById(R.id.hi_button);
        hiButton.setOnClickListener(this);
        
        helloButton = (Button)findViewById(R.id.hello_button);
        helloButton.setOnClickListener(this);
    } // end onCreate

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.hello_workshop, menu);
        return true;
    } // end onCreateOptionsMenu

    public void onClick(View v) {
        EditText nameField = (EditText) findViewById(R.id.name_field);

        String name = nameField.getText().toString();

        if (name.length() == 0) {
            new AlertDialog.Builder(this).setMessage(
                    R.string.error_name_missing).setNeutralButton(
                    R.string.error_ok,
                    null).show();
            return;
        }

        if (v == hiButton || v == helloButton) {
            int resourceId = v == hiButton ? R.string.hi_greeting
                    : R.string.hello_greeting;

            String greeting = getResources().getString(resourceId, name);
            Toast.makeText(this, greeting, Toast.LENGTH_LONG).show();

            TextView greetingField = (TextView) findViewById(R.id.greeting_field);
            greetingField.setText(greeting);
        }
    } // end onClick
    
} // end class HelloWorkshopActivity

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

	<TextView  
    	android:id="@+id/greeting_field"
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content" 
	    android:text="@string/hello"
	/>

	<TextView 
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content" 
	    android:layout_marginTop="20dp"
	    android:text="@string/enter_your_name"
    />
	
	<EditText
	    android:id="@+id/name_field"
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content" 
	>
	</EditText>
	
	<LinearLayout 
	    android:orientation="horizontal"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
     >
	    <Button 
	        android:id="@+id/hi_button"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:layout_weight="1"
	        android:text="@string/hi_button" 
	    />
	    <Button 
	        android:id="@+id/hello_button"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:layout_weight="1"
	        android:text="@string/hello_button" 
	    />
	</LinearLayout>

</LinearLayout>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="action_settings">Settings</string>
    <string name="app_name">Hello Workshop</string>
    <string name="enter_your_name">Gib bitte Deinen Namen ein:</string>
    <string name="error_name_missing">Please enter your name.</string>
    <string name="error_ok">OK</string>
    <string name="hello">Hallo Welt Workshop!</string>
    <string name="hello_button">Say Hello!</string>
    <string name="hello_greeting">Hello %s!</string>
    <string name="hi_button">Say Hi!</string>
    <string name="hi_greeting">Hi %s!</string>
</resources>

Programm auf Gerät verschieben

Mittels Google-Konto

  1. Im Ordner bin/res befindet sich die Datei "Projektname.apk". Diese ist die notwendige Datei.
  2. Die Datei als Anhnag ans Google-Konto senden
  3. Den Anhang im Gerät anwählen und danach installieren. Will das Gerät dies nicht, kann evtl. das Programm AKPatcher verwendet werden (hat bei mir aber immer nur den Info-Screen angezeigt)
  4. Anschliessend kann die App übers App-Menü gestartet werden

Mittels USB-Verbindung

Folgende Bildergalerie verwenden: http://www.chip.de/bildergalerie/So-geht-s-APKs-via-USB-installieren-Galerie_56637615.html

  1. Einstellung: Unbekannte Quellen zulassen
  2. Verbinden im Massenspeicher Modus
  3. APK-Datei auf das Gerät in den gewünschten Ordner kopieren
  4. Mit dem Dateimanager ins obige Verzeichnis navigieren und die Datei anwählen und installieren

Links

Link Beschreibung Niveau
Java Java-Wiki Anfänger
http://www.vogella.com/articles/Android/article.html Android-Einführungstutorial englisch Anfänger-Fortgeschrittene
http://www.makeuseof.com/tag/write-google-android-application/ Android erste Applikation von Google englisch Anfänger
http://www.kammerath.net/android-app-programmieren.html Android app programmieren deutsch Anfänger
http://www.vogella.com/articles/AndroidIntent/article.html Android Intents englisch Fortgeschrittene