Android: Erste App (Währungsrechner) – Teil 2

Den ersten Teil des Workshops finden Sie unter „Android: Erste App (Währungsrechner) – Teil 1„.

Unsere App ist bereits lauffähig. Aber es fehlt noch ein entscheidender Punkt, bevor wir uns der Programmlogik annehmen. Die beiden Auswahlboxen sind momentan ohne Inhalt und somit zwecklos. Das wollen wir natürlich ändern.

Die Auswahlboxen können als Inhalt Daten aus einer Datenbank oder aus einem Array (Auflistung) entgegennehmen. Da wir später noch unsere App mehrsprachig machen wollen, werden wir die Währungen als Ressourcen ablegen.

Dafür befolgen Sie die folgenden Schritte:

  1. Klicken Sie mit der rechten Maustaste auf das Projekt in der Package-Explorer Ansicht.
  2. Wählen Sie den Punkt „Android Tools“ (ganz unten im Kontextmenü).
  3. Wählen Sie im Untermenü „New Resource File ...„.
  4. Geben Sie als File „arrays“ ein.
  5. Wählen Sie als Typ „Values“ aus.
  6. Klicken Sie auf „Finish„.

Damit legen wir eine neue Ressource-Datei, in der wir Auflistungen speichern werden. Wir benötigen insgesamt 2 Auflistungen. In der neuen Datei legen Sie entweder über die graphische Oberfläche über den „Add“ Knopf ein neues StringArray (siehe Bilder) mit dem Namen „waehrung„, oder Sie geben die Werte direkt als XML-Code ein. Die XML-Darstellungen sehen Sie weiter unten.

0.1. array.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="waehrung">
        <item>EUR - Euro</item>
        <item>USD - Amerikanische Dollar</item>
        <item>AUD - Australische Dollar</item>
        <item>RUB - Russische Rubel</item>
        <item>CUD - Kanadische Dollar</item>
        <item>GBP - Englische Pfund</item>
    </string-array>
    <string-array name="waehrung_kurs">
        <item>1</item>
        <item>1.3795</item>
        <item>1.3314</item>
        <item>42.1941</item>
        <item>1.3495</item>
        <item>0.8738</item>
    </string-array>
</resources>

Nun können wir die beiden Auswahllisten mit dem Inhalt der ersten Auslistung füllen. Die zweite Liste benötigen wir später im Code. Es sind die Währungskurse in Bezug auf Euro, die wir für die Umrechnung benötigen.

Um die Auswahlliste an eine Auflistung zu binden, müssen wir nur in unseren Layout-Datei „main.xml“ bei den beiden Auswahllisten (Spinner) folgende Zeile (Zeile Nr. 6) hinzufügen.

<Spinner
	android:layout_height="wrap_content"
	android:layout_width="0dp"
	android:layout_weight="1"
	android:id="@+id/selWaehrungStart"
	android:entries="@array/waehrung">
</Spinner>

Wenn Sie jetzt die App starten, können Sie bereits die Ausgangs- und Zielwährung wählen (siehe Bild).

Nun können wir uns den Java-Quellcode widmen. Als Erstes sollte unser „Berechnen“ Knopf auf das Klicken reagieren. Dazu registrieren wir einen Listener (Zuhörer), der praktisch darauf wartet, bis der Benutzer eine Aktion ausführt. Dazu müssen wir als Erstes die Instanz des Knopfes ermitteln. Nun kommt uns zugute, dass wir unsere Views mit einer eindeutigen ID versehen haben.

Aus dem Java Code zu einer Activity könne wir jederzeit eine Referenz auf ein View mit einer ID ermitteln. Dafür stellt die Activity die Methode findViewById(ID). Da die Methode die Basisklasse „View“ zurückliefert, müssen wir den Rückgabewert noch auf das zu erwartende View (in unserem Fall Button) kasten (Button cmdBerechnen = (Button)findViewById(R.id.cmdBerechnen);). Wie an diesem Beispiel zu sehen ist, greifen wir auf die automatisch generierte „R„-Klasse, die uns die Referenzen auf unsere Ressourcen zur Verfügung stellt. Dabei sind folgende oft verwendete Referenzen wichtig:

  • R.id : Referenzen auf die Views der Layouts. Im Layout sind das die android:id="" Attribute
  • R.layout : Referenzen auf die Layout-Dateien
  • R.string : Referenzen auf unsere definierten Texte
  • R.array : Referenzen auf unsere definierte Auflistungen
  • R.color : Referenzen auf die Farben
  • R.drawable : Referenzen auf die Bilder
  • und einige weitere. Weitere Infos dazu finden Sie unter: developer.android.com

Den Listener fügen Sie mit der folgen Zeile hinzu:

cmdBerechnen.setOnClickListener(new OnClickListener() {
	public void onClick(View v) {
		kursBerechnen();
	}
});

Wir rufen in diesem unsere eigene Methode auf, die die Berechnung und die Ausgabe übernimmt. Das Ganze passiert in der onCreate Methode, die beim Erstellen einer Activity als Erstes aufgerufen wird (Lebenszyklen einer Activity wird in einem anderen Workshop erklärt). Schauen wir uns diese genauer an.

0.2. HauptActivity.java

package de.webducer.android.wrechner;

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

public class HauptActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Init();
    }

    /**
     * Initialisierung des Menüs (wird nur ein mal aufgerufen)
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = new MenuInflater(this);
    	inflater.inflate(R.menu.menu, menu);
    	return super.onCreateOptionsMenu(menu);
    }

    /**
     * Reagieren auf ein Klick auf ein Menüeintrag
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch (item.getItemId()) {
    	// Ergebnisliste löschen
		case R.id.optLoeschen:
			TextView ergebnisse = (TextView)findViewById(R.id.txtErgebnisse);
			ergebnisse.setText("");

			break;

		// Programm schließen
		case R.id.optSchliessen:
			this.finish();

			break;

		default:
			break;
		}
    	return true;
    }

    /**
     * Initialisierung der Oberfläche
     */
    private void Init(){
    	// Button mit einem Listener verbinden
    	Button cmdBerechnen = (Button)findViewById(R.id.cmdBerechnen);
    	cmdBerechnen.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				kursBerechnen();
			}
		});
    }

    /**
     * Berechnung und Ausgabe des Ergebnisses
     */
    private void kursBerechnen(){
    	// Elemente auslesen
    	EditText txtBetrag = (EditText)findViewById(R.id.txtBetrag);
    	TextView txtErgebnis = (TextView)findViewById(R.id.txtErgebnisse);
    	Spinner selWaehrungStart = (Spinner)findViewById(R.id.selWaehrungStart);
    	Spinner selWaehrungEnde = (Spinner)findViewById(R.id.selWaehrungEnde);

    	Boolean failure = false;

    	// Uwandlung des Betrages in eine Zahl
    	String betragText = txtBetrag.getText().toString();
    	Double betrag = 0d;
    	if (betragText != null && betragText != "") {
    		try {
    			betrag = Double.parseDouble(betragText);
			} catch (NumberFormatException e) {
				Toast.makeText(this, R.string.err_betarg_format, Toast.LENGTH_LONG).show();
				failure = true;
			}
		}

    	// Bestimmen der Ausgangs- und Zielwährung
    	int wahrungStart = selWaehrungStart.getSelectedItemPosition();
    	int waehrungEnde = selWaehrungEnde.getSelectedItemPosition();

    	// Bestimmen des jeweiligen Wechselkurses
    	String kursStartText = getResources().getStringArray(R.array.waehrung_kurs)[wahrungStart];
    	String kursEndeText = getResources().getStringArray(R.array.waehrung_kurs)[waehrungEnde];

    	// Umwandlung des Kurses in eine Zahl
    	Double kursStart = 0d;
    	Double kursEnde = 0d;
    	if (kursStartText != null && kursStartText != "" && !failure) {
			try {
				kursStart = Double.parseDouble(kursStartText);
			} catch (NumberFormatException e) {
				Toast.makeText(this, R.string.err_kurs_format, Toast.LENGTH_LONG).show();
				failure = true;
			}
		}
    	if (kursEndeText != null && kursEndeText != "" && !failure) {
			try {
				kursEnde = Double.parseDouble(kursEndeText);
			} catch (NumberFormatException e) {
				Toast.makeText(this, R.string.err_kurs_format, Toast.LENGTH_LONG).show();
				failure = true;
			}
		}

    	if(!failure){
	    	// Umrechnung
	    	Double ergebnis = betrag / kursStart * kursEnde;

	    	// Ergebnis ausgeben
	    	StringBuilder ergebnisText = new StringBuilder();
	    	ergebnisText.append(getResources().getStringArray(R.array.waehrung)[wahrungStart].subSequence(0, 3))
	    		.append(" ")
	    		.append(String.format("%.2f", betrag))
	    		.append(" = ")
	    		.append(getResources().getStringArray(R.array.waehrung)[waehrungEnde].substring(0, 3))
	    		.append(" ")
	    		.append(String.format("%.2f", ergebnis))
	    		.append("\n");
	    	txtErgebnis.setText(txtErgebnis.getText() + ergebnisText.toString());
    	}
    }
}

In der Zeile 21 wird durch den Aufruf der Methode setContentView(R.layout.main); wiesen wir unseren Activity HauptActivity.java ein Layout zu, den wir wieder über die generierte Klasse „R“ ansprechen.

Der Aufruf unserer eigenen Methode Init() in der Zeile 23 setzt den Listener für unseren Berechnungs-Knopf. Nun wenden wir uns der eigentlichen Berechnung zu (Zeilen 75 bis 142).

Als Erstes holen wir uns die Referenzen zu allen Views, die wir für unsere Berechnung benötigen (Betrag, Ausgangswährung, Endwährung und Ergebnisfeld).

In der Zeile 87 erhalten wir durch den Aufruf der Methode getText() den Betrag für die Umrechnung. Das ist allerdings ein Textfeld und wir benötigen eine Zahl. Aus diesem Grund konvertieren wir den erhaltenen Text in ein Double-Format (mit der vorherigen Prüfung, ob der Text überhaupt eingegeben wurde, Zeile 89).

In den Zeilen 99 und 100 erhalten wir den Index des ausgewählten Eintrages aus den Auswahlboxen der Währung. Jetzt kommt uns der zweite Array, in dem wir die Kurse definiert haben, zugute. Dieser ist genauso von der Reihenfolge her aufgebaut, wie das Währungs-Array. Nun können wir durch den Index aus den Zeilen 99 und 100 die Kurse ermitteln (Zeilen 103 und 104). Diese sind wiederum Texte und müssen zuerst in Double konvertiert werden, wie bereit beim Betrag.

Wenn alle Konvertierungen ohne Fehler durchgelaufen sind, berechnen wir nun in der Zeile 128 den umgerechneten Betrag. Um eine schöne Anzeige zu erhalten, formatieren wir nur ein wenig unsere Ausgabe. Die Anzeige soll dann in etwa folgendermassen aussehen:

EUR 125,00 = USD 172,44

Damit wir auch eine Geschichte unserer Berechnungen erhalten, hängen wir in der Zeile 140 unser Ergebnis an den vorhandenen Text an.

Um dem Benutzer zu signalisieren, dass mit der Berechnung etwas schief gelaufen ist, erzeugen wir bei einem Konvertierungsfehler einen Toast (kleine Benachrichtigung, die kurz auf dem Bildschirm erscheint). Das erfolgt in den Zeilen 93, 113 und 121. Wenn Sie einen solchen Fehler provozieren wollen, tauschen Sie einfach in der array.xml-Datei in dem Werte-Array die Punkte durch die Kommas aus (erzeugt Fehler beim Konvertieren).

1. Lokalisierung

Die Lokalisierung ist unter Android relativ einfach gelöst. Die Ressourcen, die keinen Länder-Postfox haben, gehören zu der Standardsprache (in unseren Fall Deutsch). Die Standardsprache muss immer vollständig sein. Weitere Sprachen dagegen nicht. Wird eine spezielle Übersetzung nicht gefunden, wird die der Standard-Übersetzung genommen.

In unserer App müssen die Daten aus der strings.xml und arrays.xml Dateien übersetzt werden. Dafür klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie Android Tools -> New Ressource File... . Wie im Bild zu sehen ist, muss für neue Sprache nun unter „Available Qualifiers“ „Language“ auswählen und auf der rechten Seite den zweistelligen Ländercode eingeben („en“ für Englisch). Nun kann der Inhalt der beiden Dateien in die neuen kopiert werden und die Werte übersetzt werden. Die neuen Dateien landen im Ordner „res/values-en„.

1.1. strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<!-- Globale Strings -->
	<string name="app_name">Currency Calculator</string>

	<!-- View Texte -->
    <string name="betrag_eingeben">Please type the value to calculate!</string>
    <string name="cmd_berechnen">Calculate</string>

    <!-- Menü -->
    <string name="opt_loeschen">Clear Result List</string>
    <string name="opt_loeschen_kurz">Clear</string>
    <string name="opt_schliessen">Close App</string>
    <string name="opt_schliessen_kurz">Close</string>

    <!-- Fehlertexte -->
    <string name="err_betarg_format">The value has wrong format!</string>
    <string name="err_kurs_format">The currency value has wrong format!</string>
</resources>

1.2. arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="waehrung">
        <item>EUR - Euro</item>
        <item>USD - American Dollar</item>
        <item>AUD - Australian Dollar</item>
        <item>RUB - Russian Rubel</item>
        <item>CUD - Canadian Dollar</item>
        <item>GBP - Great Britain Pound</item>
    </string-array>
</resources>

2. Menü

Nun gehen wir an das Menü. Dafür erstellen wir wieder eine neue Android Ressource-Datei von Typ Menü. Diese XML-Datei landet im Ordner „res/menu„.

<?xml version="1.0" encoding="utf-8"?>
<menu
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item
    	android:title="@string/opt_loeschen"
    	android:titleCondensed="@string/opt_loeschen_kurz"
    	android:id="@+id/optLoeschen"
    	android:icon="@drawable/opt_clear" />
    <item
    	android:title="@string/opt_schliessen"
    	android:titleCondensed="@string/opt_schliessen_kurz"
    	android:id="@+id/optSchliessen"
    	android:icon="@drawable/opt_close" />
</menu>

In unseren Activity-Java-Datei müssen nur noch wenige Zeilen hinzugefügt werden, um dem Menü ein Leben einzuhauchen. In den Zeilen 30 bis 34 wir das Menü initialisiert (ähnlich, wie das Layout in der onCreate-Methode). Dafür dient die überschriebene Methode onCreateOptionsMenu(). Unter Optionsmenü versteht man unter Android das Menü, das durch das Betätigen der Menütaste erscheint.

Die Auswertung, welches der Menüpunkte nun ausgewählt wurde, erfolgt in der überschriebenen Methode onOptionsItemSelected(). Über die Item-ID können wir bestimmen, was nun ausgewählt wurde und abhängig davon unseren Code ausführen (hier ist ein CASE-Konstrukt sehr gut geeignet, um die Menüpunkte zu unterscheiden und den Code übersichtlich zu halten). Für das Schließen unseren App benötigen wir nur eine Zeile mit this.finish() (Zeile 51). Um die Ergebnisse zurückzusetzen, müssen wir wieder die Referenz auf das View holen und deren Text auf einen leeren Text setzen (Zeilen 44 und 45).

Damit ist unsere App so weit funktionsfähig und einsatzbereit. Die Kurse können sehr einfach in der XML-Datei angepasst und erweitert werden.

Android: Erste App (Währungsrechner) – Teil 1

Dieser Beitrag zeigt an einer sehr einfach gehaltenen App, wie man seine erste App für Android erstellen kann. Dabei werden die benötigten Elemente und Schritte detailliert beschrieben und bebildert. Das fertige Projekt kann unter dem unten stehenden Link von GitHub heruntergeladen (oder geklont) werden.

GitHub Projekt-Repository

1. Projektbeschreibung (Zielsetzung)

In diesem Beitrag wird ein einfacher Währungsrechner erstellt. Folgende Aufgaben / Voraussetzungen muss die fertige App erfüllen:

  • Eingabe eines Betrages zum Umrechnen
  • Validierung der Eingaben (nur Zahlen)
    • Auswahl der Ausgangs- und Zielwährung
  • Berechnung des Betrages in der Zielwährung
  • Ausgabe der Berechnung
    • Die letzen Ergebnisse in einer Liste ausgeben
  • Löschen der Ergebnisliste über ein Menü
  • Beenden der App über ein Menü
  • Mehrsprachigkeit

Durch diese relativ einfache Anwendung werden die unter Android am meisten benutzte Elemente vorgestellt.

2. Anlegen des Projektes unter Eclipse

Eine genaue Beschreibung, wie Sie Eclipse auf Ihrem System einrichten, finden Sie unter „Android: Eclipse installieren und einrichten„. Im Beitrag „Android: Neues Projekt anlegen“ finden Sie die Beschreibung, wie Sie ein neues Android-Projekt mithilfe des Assistenten unter Eclipse anlegen. Für das folgende Projekt sollten Sie die folgenden Werte beim Anlegen des Projektes angeben, um den Beschreibungen und Code-Ausschnitten besser folgen zu können:

  • Project name: Waehrungsrechner
  • Contents: Create new project in workspace
  • Build target: Android 2.2 (API Level 8 )
  • Application name: Waehrungsrechner
  • Package name: de.webducer.android.wrechner
  • Create Activity (angehackt): HauptActivity
  • Min SDK Version: 8

Nach der Neuanlage des Projektes wird der erste Bildschirm bereits mit einem Element, dass den Text „Hallo World“ enthält. Nun können Sie das Projekt zum ersten Mal starten. Dafür gehen Sie wie folgt vor:

  1. Markieren Sie im „Package Explorer“ das Projekt
  2. Klicken Sie mit der rechten Maustaste darauf und
  3. wählen Sie im Kontextmenü den Punkt „Run as“ -> „Android Application“

Nach einiger Zeit startet zuerst der eingerichtete Emulator (das kann abhängig vom Rechner auch einige Minuten dauern). Danach startet im Emulator das Programm. Schließen den Emulator nicht, dann wird die neue Version sehr schnell auch auf dem Emulator angezeigt.

Aber nun der Reihe nach. Zuerst erkläre ich die Datei-Struktur von unserem Projekt.

3. Ordner und Dateistruktur des Projektes

Projektstruktur
Projektstruktur
src
In diesem Verzeichnis liegen die Quellcode-Dateien zu Ihrer App (Java-Dateien). Im Moment sollte in diesem Ordner nur die Datei „HauptActivity.java“ liegen (im entsprechenden Package „de.webducer.android.wrechner“).
gen
Das ist ein automatisch generiertes Verzeichnis von Android. Die automatisch generierte Klasse „R“ beinhaltet die Verweise auf die Ressourcen-Variablen und dient zum Zugriff auf diese aus dem Quellcode heraus. Zu den Ressourcen gehören unter anderen die übersetzbaren Strings, Layouts, Farben, Arrays, Bilder usw.
Android 2.2
In diesem Ordner ist die Android-Bibliothek abgelegt. Abhängig von der ausgewählten Android-SDK-Version wird eine andere Nummer angezeigt.
assets
In diesem Ordner werden Ressourcen abgelegt, die nicht über den Ressourcen-Manager verwaltet werden und in Unterverzeichnisse gegliedert werden können.
res
In diesem Ordner werden Ressourcen abgelegt, die über den Android-Ressource-Manager zur Verfügung gestellt werden und in der R.-Klasse abgebildet werden. Die einzelnen Unterordner werden weiter unten beschrieben.
drawable-XX
In diesen Ordnern werden die Bilder für die App gespeichert. XX steht dabei für eine bestimmte Ausflösungsdichte und wird dynamisch abhängig vom Auflösungsvermögen des Zielbildschirms ausgelesen.
layout
In diesem Ordner liegen die Layout-Definitionen für unsere App. In unserem Fall sollte am Anfang nur die Datei „main.xml“ vorliegen.
values
In diesem Ordner werden unterschiedliche Werttypen gespeichert. Unter anderem sind hier die Strings-Definitionen für die Mehrsprachigkeit einer App definiert. Weitere Wertgruppen sind zum Beispiel Farben, Designs, Arrays usw.
AndroidManifest.xml
Diese Datei definiert unsere App und regelt unter anderem auch die notwendigen Berechtigungen.

4. Das Layout

Währungsrechner-Layout
Währungsrechner-Layout

Unser Layout für die App besteht aus folgenden Elementen (Widgets):

  • EditText: Für die Eingabe des Betrages für die Umrechnung
  • Spinner: Zwei Auswahlboxen für die Auswahl der Ausgangs- und der Zielwährung
  • Button: Knopf, um die Umrechnung anzustoßen
  • TextView: Bereich, in dem die Ergebnisse angezeigt werden (zusammen mit älteren Umrechnungen)

4.1. 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"
    >
    <EditText
    	android:layout_height="wrap_content"
    	android:id="@+id/txtBetrag"
    	android:layout_width="fill_parent"
    	android:hint="@string/betrag_eingeben"
    	android:inputType="numberDecimal">
    </EditText>
    <LinearLayout
    	android:orientation="horizontal"
    	android:weightSum="3"
    	android:layout_height="wrap_content"
    	android:layout_width="fill_parent">
	    <Spinner
	    	android:layout_height="wrap_content"
	    	android:layout_width="0dp"
	    	android:layout_weight="1"
	    	android:id="@+id/selWaehrungStart">
	    </Spinner>
	    <Spinner
	    	android:layout_height="wrap_content"
	    	android:layout_width="0dp"
	    	android:layout_weight="1"
	    	android:id="@+id/selWaehrungEnde">
	    </Spinner>
	    <Button
	    	android:text="@string/cmd_berechnen"
	    	android:id="@+id/cmdBerechnen"
	    	android:layout_width="0dp"
	    	android:layout_weight="1"
	    	android:layout_height="wrap_content">
	    </Button>
	</LinearLayout>
	<ScrollView
		android:layout_height="fill_parent"
		android:layout_width="fill_parent">
	    <TextView
	    	android:id="@+id/txtErgebnisse"
	    	android:layout_width="fill_parent"
	    	android:layout_height="fill_parent"
	    	android:gravity="top">
	    </TextView>
	</ScrollView>
</LinearLayout>

Ein Android-Layout besteht aus einfachen Views (wie EditText, Button usw.) und den sogenannten View-Gruppen-Elementen, die weitere Elemente enthalten dürfen. Das oberste Element ist immer eine View-Gruppe. In unserem Fall ist es ein LinearLayour. Diese Gruppe richtet die enthaltenen Elemente abhängig von der Orientierung neben- (horizontal) oder übereinander (vertical) an (Zeilen 4 und 17). Das Linear-Layout Element aus der Zeile 2 ordnen somit alle enthaltenen Elemente untereinander. Und das Linear-Layout aus Zeile 15 ordnet die 3 enthaltenen Elemente nebeneinander.

Die Angabe in allen Views android:layout_width bestimmt die Bereite des Elementes, android:layout_height die Höhe. Es sind folgende Werte möglich:

  • fill_parent (oder match_parent): View nimmt die gesamte Breite / Höhe ein, die das Elternelement zur Verfügung stellt.
  • wrap_content: View nimmt die Breite / Höhe des eigenen Inhaltes ein.
  • Wert in Pixel (px) oder Device Independent Pixel (dp / dip).

Somit nimmt unser LinearLayout aus Zeile 2 die gesamte Breite und Höhe (ganzer Bildschirm), das EditText dagegen zwar die gesamte Breite, aber nur eigene Höhe ein.

In der Zeile 10 sehen wir ein spezielles Konstrukt (android:id="@+id/txtBetrag"). Mit dieser Angabe „@+id/“ teilen wir dem Compiler mit, dass dieses Element eine eindeutige ID erhalten soll, gefolgt von dem Namen, den wir frei vergeben können. Über diese ID können wir später auf das View aus dem Quellcode zugreifen (R.id.txtBetrag).

In der Zeile 12 (android:hint="@string/betrag_eingeben") kommt wieder ein spezieller Android-Konstrukt. Über die Angabe „@string/“ können wir auf die String-Ressourcen aus dem „res„-Ordner zugreifen. Das sind die übersetzten Text-Platzhalter. Die string.xml folgt weiter unten. Die Angabe android:hint legt einen Hinweistext fest, der nach der Eingabe der ersten Zahlen verschwindet.

Die Angabe in der Zeile 13 (android:inputType="numberDecimal") legen wir fest, dass im Eingabefeld nur positive Zahlen eingegeben werden dürfen.

Damit wir die 3 Views nebeneinander und in der gleichen Breite darstellen, nutzen wir statt der absoluten Breitenangabe (z.B. Zeile 22 android:layout_width="0dp") eine relative Angabe zum Eleternelemet. LinearLayout aus Zeile 15 definiert, dass den Kindelementen eine Gewichtungssumme von 3 zur Verfügung gestellt wird (Zeile 17 android:weightSum="3"). Die 3 Views haben jeweils eine Gewichtung von 1 (Zeile 23 android:layout_weight="1"), also genau 1/3 der Gesamtgewichtung.

In der Zeile 40 ist das TextView innerhalb eines ScrollView (View-Gruppe) platziert. Das erlaubt uns später durch die Ergebnisse zu scrollen, falls es mehr sein werden, als der Platz auf dem Bildschirm erlaubt.

Mit der Zeile 47 (android:gravity="top") geben wir an, dass der Text oben (im Bezug zum Elternelement) platziert werden soll.

4.2. strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="betrag_eingeben">Bitte den Betrag hier eingeben!</string>
    <string name="app_name">Währungsrechner</string>
    <string name="cmd_berechnen">Berechnen</string>
</resources>

Android: Erste App (Währungsrechner) – Teil 2

Android: Neues Android Projekt anlegen

Artikeldaten
Erste Version 0.1 (13.09.2011)
Aktuelle Version 0.3 (19.07.2012)
Eclipse Version 4.2 (Juno)
ADT Version 20.0.1
Android SDK Version 4.0.3 (API Level 15)

1. Kurzbeschreibung

Der erste Schritt zu der eigenen App ist ein neuer Android Projekt. Dieser Beitrag zeigt, wie dies unter Eclipse mit den Assistenten zu machen ist.

Wenn Sie noch keine Entwicklungsumgebung installiert haben, machen Sie das vor dem Weiterlesen dieses Beitrages. Wie das genau Schritt für Schritt geht, können Sie in dem Beitrag „Android: Eclipse installieren und einrichten“ nachlesen.

2. Eclipse Android Menüs

Android Toolbar

Beschreibung der wichtigsten Android Menüeinträge
Toolbar Menü Kontext-Menü Beschreibung
Android Toolbar - SDK Download MARKDOWN_HASHc89686a387d2b12b3c729ce35a0bcb5bMARKDOWN_HASH -> MARKDOWN_HASHf22326c49b75c89ac22553b9e6942c33MARKDOWN_HASH Herunterladen der Android SDKs und weiterer Bibliotheken (z.B.: Kompabilitätsbibliothek, Admob, Lizensing, …)
Android Toolbar - AVD Manger MARKDOWN_HASHc89686a387d2b12b3c729ce35a0bcb5bMARKDOWN_HASH -> MARKDOWN_HASH80c3f5c71459e344a0e2517e742d572cMARKDOWN_HASH Einrichten von virtuellen Android-Geräten
Android Toolbar - Lint MARKDOWN_HASHc89686a387d2b12b3c729ce35a0bcb5bMARKDOWN_HASH -> MARKDOWN_HASH922501417a36f5e64c98c36c2e443cf1MARKDOWN_HASH MARKDOWN_HASH7742577bc3ada9e8f1b2340fcf9a7901MARKDOWN_HASH -> MARKDOWN_HASH8c3003a24487dca13fc1331646ed7c1dMARKDOWN_HASH Testen des Projektes auf die häufigsten Fehler
Android Toolbar - Android Projekt MARKDOWN_HASH0b27918290ff5323bea1e3b78a9cf04eMARKDOWN_HASH -> MARKDOWN_HASH03c2e7e41ffc181a4e84080b4710e81eMARKDOWN_HASH -> MARKDOWN_HASH043a602bb076221d7fa261ea984237b5MARKDOWN_HASH MARKDOWN_HASH03c2e7e41ffc181a4e84080b4710e81eMARKDOWN_HASH -> MARKDOWN_HASH043a602bb076221d7fa261ea984237b5MARKDOWN_HASH Assistent für die Anlage eines neuen Android-Projektes
Android Toolbar - Android Test-Projekt MARKDOWN_HASH0b27918290ff5323bea1e3b78a9cf04eMARKDOWN_HASH -> MARKDOWN_HASH03c2e7e41ffc181a4e84080b4710e81eMARKDOWN_HASH -> MARKDOWN_HASH6311ae17c1ee52b36e68aaf4ad066387MARKDOWN_HASH -> MARKDOWN_HASHe84e30b9390cdb64db6db2c9ab87846dMARKDOWN_HASH -> MARKDOWN_HASH5a707c6c6072b97e97002eb7e9af00b0MARKDOWN_HASH MARKDOWN_HASH03c2e7e41ffc181a4e84080b4710e81eMARKDOWN_HASH -> MARKDOWN_HASH6311ae17c1ee52b36e68aaf4ad066387MARKDOWN_HASH -> MARKDOWN_HASHe84e30b9390cdb64db6db2c9ab87846dMARKDOWN_HASH -> MARKDOWN_HASH5a707c6c6072b97e97002eb7e9af00b0MARKDOWN_HASH Assistent für die Anlage eines Android Test Projektes
Android Toolbar - Android XML Ressource MARKDOWN_HASH0b27918290ff5323bea1e3b78a9cf04eMARKDOWN_HASH -> MARKDOWN_HASH03c2e7e41ffc181a4e84080b4710e81eMARKDOWN_HASH -> MARKDOWN_HASHd6b52b04e21d609a0d176258a6691e56MARKDOWN_HASH MARKDOWN_HASH7742577bc3ada9e8f1b2340fcf9a7901MARKDOWN_HASH -> MARKDOWN_HASH4559732c49e04479ccee974e363625c4MARKDOWN_HASH Assistent für die Anlage einer Ressource-Datei (z.B.: Layout, Menü, usw.)

3. Einrichten eines Testgerätes (Android Virtual Device – AVD)

Bevor wir mit dem Anlegen eines Projektes anfangen, legen wir zuerst ein Testgerät (unter Android Developer Tools werden diese „virtuelle Geräte“ genannt).

  1. Im Menü auf „Window“ -> „AVD Manager“ gehen.
  2. Der AVD-Manager zeigt nun alle bereits angelegten virtuellen Geräte (AVDs) und die darauf laufende Android-Version. In unserem Fall werden keine AVDs angezeigt.
  3. Klicken Sie auf „New“ um ein neues AVD anzulegen.
  4. Im AVD-Name empfehle ich immer mindestens die Android Version (oder API Level) und die verwendete Auflösung anzugeben, um bei der Auswahl später zu erleichtern (z.B.: A_403_HVGA für Android 4.0.3 mit HVGA Auflösung). Zusätzlich gebe ich bei einigen speziellen AVDs auch den Prozessortyp und die eingestellte Sprache mit an (z.B.: A_403_VGA_x86_DE für ein virtuelles Gerät mit Android 4.0.3,VGA Auflösung, in deutscher Sprache und basierend auf einen Intel x86 Image).
  5. Wählen Sie unter „Target“ die gewünschte Android-Version aus. Andere Android-Version können Sie mit dem „Android SDK Manager“ herunterladen. In unserem Fall wählen wir, da wir mit Android 4 arbeiten, „Android 4.0.3 - API Level 15„.
  6. Unter CPU/ABI können Sie bei einigen Android-Versionen zwischen den unterschiedlichen CPU-Typen auswählen. Momentan ist unter Android 4.0.3 ARM und x86 möglich.
  7. Unter SD-Card können Sie die Größe der virtuellen Speicherkarte wählen, falls eine solche in Ihrer App notwendig ist.
  8. Unter Snapshot sollten Sie den Hacken setzten. Damit wird das AVD nicht bei jedem Start komplett neu gestartet, sondern wacht praktisch aus dem Schlaf auf. Das erspart bei langsameren Rechnern zum Teil mehrere Minuten, bis ein AVD einsatzbereit ist.
  9. Unter Skin können Sie die Auflösung des AVD definieren. Je größer die Auflösung ist, desto träger füllt sich der Emulator. Meine Empfehlung für Entwicklungs-AVD ist HVGA (480×320). Diese Auflösung ist hoch genug, um vernünftig testen zu können, und klein genug, damit der Emulator einigermaßen flüssig läuft. Für andere Auflösungen können weitere AVDs angelegt werden, die dann aber nur zum abschließenden Test verwendet werden und somit die Entwicklung an sich nicht ausbremsen.
  10. Unter Hardware können Sie noch zusätzliche Angaben zur Hardware machen. Für den Anfang lassen wir diesen Bereich unverändert.
  11. Klicken Sie anschließend auf „Create AVD“ und schließen Sie den AVD Manager.

4. Neues Android-Projekt anlegen

Um ein neues Android-Projekt anzulegen, verfahren Sie wie folgt:

  1. Gehen Sie auf „File“ -> „New“ -> „Android Application Project„. Wenn dieser Punkt unter „New“ nicht angezeigt wird, erreichen Sie den Assistenten auch über „File“ -> „New“ -> „Other“ -> „Android“ -> „Android Application Project„.
  2. Im nun gestarteten Assistenten müssen Sie nun folgende Angaben tätigen:
    1. Application Name: Bezeichnung der App. Diese Bezeichnung erscheint als Titel der App und in Launcher auf Ihren Android-Gerät. (In unserem Fall ist es „Test App“.
    2. Paroject Name: Bezeichnung des Projektes, so wie es dann im Eclipse angezeigt wird. Die Projektbezeichnung muss nicht unbedingt gleich der App-Bezeichnung sein, ist aber übersichtlicher.
    3. Package Name: Das ist der eindeutige Bezeichner Ihrer App, der auch im Play-Store für die Identifizierung Ihrer App verwendet wird. Um dies so weit wie möglich zu gewährleisten, hat sich die umgekehrte Schreibweise der eigenen Internet-Domain eingebürgert (z.B.: de.meinedomain.android.appname). Der Package-Name muss weltweit eindeutig sein.
    4. Build SDK: Hier wählen Sie die SDK-Version, mit der Ihrer App kompiliert werden soll. Wählen Sie hier am besten den höchsten API Level, der momentan verfügbar ist, wenn keine anderen zwingenden Gründe dagegen sprechen.
    5. Minimum Required SDK: Hier wählen Sie die minimale SDK-Version, unter der Ihre App noch lauffähig ist. Für die Kompatibilität (wenn Build- und min.-Version sich nicht gleichen) müssen Sie dann selbst sorgen.
    6. Create custom launcher icon: Diese Option funktioniert momentan nicht (getestet unter Windows und OS X). Wenn diese aktiviert ist, wird das neue Projekt nicht erstellt. Vielleicht bessert Google den Fehler in einer der nächsten Versionen nach. Wenn diese Option gesetzt ist, kann man in dem nächsten Schritt einen eigenen Icon fürs Starten der App entwerfen (einfache Icons aus einen Bild oder Text). Für unsere Zwecke benötigen wir es nicht.
    7. Mark this project as a library: Diese Option bleibt auch ausgecheckt, da wir normale App entwickeln wollen und nicht eine Android-Bibliothek.
    8. Create Project in Worspace: Diese Option können Sie eingecheckt belassen. Nur wenn Sie Ihr Projekt an einen andren Ort speichern wollen, als im Arbeitsverzeichnis, wählen Sie hier ein anderes.
  3. Im nächsten Fenster des Assistenten können Sie nun aus der Vorlage einen Activity-Typ auswählen. Für den Einstieg reicht „BlankActivity„. Später, wenn man sich auch mit Fragmenten auskennt, kann die Vorlage „MasterDetailFlow“ benutzt werden.
  4. Im nächsten Fenster des Assistenten bestimmen Sie nun den Namen Ihrer ersten Activity (Bildschirmseite). Für das erste Mal belassen Sie alles, wie es ist.
  5. Klicken Sie auf „Finish„. Ihr erster Android Projekt ist somit angelegt.

5. Erster Start der App

Nach dem das Projekt angelegt wurde, kann dieser auch direkt in dem vorher angelegten AVD gestartet werden. Dazu gehen Sie wie folgt vor:

  1. Rufen Sie das Kontext-Menü auf dem Projekt-Knoten im Package-Explorer auf (rechte Maustaste).
  2. Gehen Sie auf „Run As“ -> „Android Application„.
  3. Ein passender AVD wird automatisch gestartet (das kann abhängig vom System auch einige Minuten dauern).
  4. In dem neu gestarteten AVD sehen Sie nun Ihre neu angelegte App.

Beenden Sie den AVD nicht, um die langen Startzeiten von diesem zu vermeiden. Wenn Sie das nächste Mal „Run As“ -> „Android Application“ aufrufen, wird die neue App Version auf AVD hochgeladen und gestartet. Neustart des AVD ist nicht notwendig.

Nach dem ersten Start über „Run As“ können Sie die App einfacher über Run-Button in der Toolbar (grüner Abspiel-Button), über das Menü „Run“ -> „Run“ oder Tastenkürzel „Strg + F11“ starten.

Wenn Sie selbst bestimmen möchten, in welchen AVD Ihre App starten soll, rufen Sie das Kontext-Menü des Projektes auf. Gehen Sie auf „Run As“ -> „Run Configuration“ und wählen Sie unter „Target„, dass das AVD nicht automatisch, sondern manuell bestimmt werden soll („Always prompt to pick device„).

6. Weiterführende Ressourcen

6.1. Interne Ressourcen

6.2. Screenshots

6.3.  Bücher