<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>WebDucer techBlog &#187; Allgemein</title>
	<atom:link href="http://blog.webducer.de/category/allgemein/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.webducer.de</link>
	<description></description>
	<lastBuildDate>Sun, 22 Jan 2012 19:18:37 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Android: Einfache Perfomance-Optimierungen</title>
		<link>http://blog.webducer.de/2012/01/android-einfache-perfomance-optimierungen/</link>
		<comments>http://blog.webducer.de/2012/01/android-einfache-perfomance-optimierungen/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 19:16:46 +0000</pubDate>
		<dc:creator>WebDucer</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Optimierung]]></category>
		<category><![CDATA[Perfomance]]></category>

		<guid isPermaLink="false">http://blog.webducer.de/?p=289</guid>
		<description><![CDATA[Zugriff auf Klassenvariablen (Eigenschaften) sollte, wenn möglich (z.B. innerhalb der Klasse oder des Packages), direkt über die Klassenvariablen statt über die Getter und Setter-Methoden erfolgen. Performance-Steigerung liegt ca. beim Faktor 2-3.]]></description>
			<content:encoded><![CDATA[<ol>
<li>Zugriff auf Klassenvariablen (Eigenschaften) sollte, wenn möglich (z.B. innerhalb der Klasse oder des Packages), direkt über die Klassenvariablen statt über die Getter und Setter-Methoden erfolgen. Performance-Steigerung liegt ca. beim Faktor 2-3.</li>
<li>Bei Zusammenfügen von String-Ketten  sollte man den StringBulder, statt des „+“-Operators nutzen. Mit der Anzahl der Konkatenationen steigt der Performance-Verlust beim „+“-Operator exponentiell an, da jedes Mal ein neues Objekt erzeugt werden muss. Beim StringBuilder steigt die Rechenzeit dagegen nur linear an.</li>
<li>Es sollen unnötige Objekterzeugungen vermieden werden. So z.B.:</li>
<ol type="a">
<li>Objekterzeugung innerhalb der Schleifen vermeiden</li>
<li>Mehrfache Objekterzeugung von oft benutzen Objekten in der Klasse vemeiden (z.B.: <code>findViewById()</code>). Diese sollten am besten direkt als Klassenvariablen, und somit nur einmal, initialisiert werden.</li>
</ol>
<li>Schleifen optimieren. Satt:
<pre class="brush: java; gutter: true">for (int i = 0; i &lt; array.length; i++) { … }</pre>
<p>sollte</p>
<pre class="brush: java; gutter: true">int arrayLenght = array.length;
for (int i = 0; i &lt; arrayLength; i++) { … }</pre>
<p>verwendet werden.</li>
<li>Layoutoptimierung mit dem mitgelieferten Tool <strong><code>layoutopt</code></strong> durchführen.</li>
<li>Größere (mehr als 100 Elemente) Arrays sind deutlich perfomanter als ArrayList Objekte.</li>
<li>Einfache Klassen, sollten wenn möglich durch Arrays ersetzt werden, da dadurch die Objekterzeugung entfällt.</li>
<li>Wenn möglich, sollten <code>final</code> und <code>static</code> Zugriffsmodifizierer verwendet werden.</li>
<li>Die Schleifen, nach dem das gewünschte Ergebnis erreicht wurde, sollten durch <code>break</code> oder <code>continue</code> verlassen werden und nicht unnötig die restlichen Elemente durchlaufen.</li>
<li>Rechenintensive oder Zeitintensive Aufgaben (z.B.: Netzwerk und Dateizugriffe) sollten immer in ein eigenes Thread ausgelagert werden, damit der Benutzer weiterhin die Kontrolle über die App behält.</li>
<li>Beim WebServices und Netzwerkzugriffen sollte dem kompakteren <code>JSON</code>-Format immer der Vorzug vor dem <code>XML</code>-Format gewährt werden (kleinerer Overhead).</li>
<li>Benutzung des mitgelieferten Obfuscators <code>ProGuard</code>, um den kompilierten Code zu optimieren (Komprimierung von Code, weglassen unbenutzer Methoden / Eigenschaften / Klassen, kürzung der Bezeichner usw.).</li>
<li>Test der eigenen Algorithmen auf Perfomance und Test der Alternativen (Benchmarking).</li>
<li>Benutzung von <code>TraceView</code> (DDMS), um Flaschenhälse beim Speicher und Ausführungszeit zu finden.</li>
<li>Bei den SQL-Abfragen sollten nur die wirklich notwendige Daten abgefragt werden (nur benötigte Spalten und nur die benötigte Datenmenge, Zeilenanzahl).</li>
<li>Lint nutzen, um unbenutzte Resourcen und vorgeschlagene Optimierungen umzusetzen.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.webducer.de/2012/01/android-einfache-perfomance-optimierungen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android: Erste App (Währungsrechner) – Teil 2</title>
		<link>http://blog.webducer.de/2011/10/android-erste-app-wahrungsrechner-%e2%80%93-teil-2/</link>
		<comments>http://blog.webducer.de/2011/10/android-erste-app-wahrungsrechner-%e2%80%93-teil-2/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 19:11:37 +0000</pubDate>
		<dc:creator>WebDucer</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Workshop]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[App]]></category>
		<category><![CDATA[Goolge]]></category>
		<category><![CDATA[Rechner]]></category>
		<category><![CDATA[Währung]]></category>

		<guid isPermaLink="false">http://blog.webducer.de/?p=235</guid>
		<description><![CDATA[Unsere App ist bereits lauffähig. Aber es fehlt noch ein entscheidender Punkt, bevor wir uns der Programmlogig annehmen. Die beiden Auswahlboxen sind momentan ohne Inhalt und somit zwecklos. Das wollen wir natürlich ändern.]]></description>
			<content:encoded><![CDATA[<p>Den ersten Teil des Workshops finden Sie unter &#8220;<a title="Android: Erste App (Währungsrechner) – Teil 1" href="http://blog.webducer.de/2011/09/android-erste-app-wahrungsrechner-teil-1/">Android: Erste App (Währungsrechner) – Teil 1</a>&#8220;.</p>
<p>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.</p>
<p>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.
<a href='http://blog.webducer.de/2011/10/android-erste-app-wahrungsrechner-%e2%80%93-teil-2/android-tools-2/' title='Android Tools'><img width="150" height="150" src="http://blog.webducer.de/wp-content/uploads/2011/09/Android-Tools1-150x150.png" class="attachment-thumbnail" alt="Android Tools" title="Android Tools" /></a>
<a href='http://blog.webducer.de/2011/10/android-erste-app-wahrungsrechner-%e2%80%93-teil-2/ressource-file-2/' title='Ressource File'><img width="150" height="150" src="http://blog.webducer.de/wp-content/uploads/2011/09/Ressource-File1-150x150.png" class="attachment-thumbnail" alt="Ressource File" title="Ressource File" /></a>
<a href='http://blog.webducer.de/2011/10/android-erste-app-wahrungsrechner-%e2%80%93-teil-2/array-ressource-2/' title='Array Ressource'><img width="150" height="150" src="http://blog.webducer.de/wp-content/uploads/2011/09/Array-Ressource1-150x150.png" class="attachment-thumbnail" alt="Array Ressource" title="Array Ressource" /></a>
<a href='http://blog.webducer.de/2011/10/android-erste-app-wahrungsrechner-%e2%80%93-teil-2/spinner/' title='Spinner'><img width="150" height="150" src="http://blog.webducer.de/wp-content/uploads/2011/09/spinner-150x150.png" class="attachment-thumbnail" alt="Spinner" title="Spinner" /></a>
<a href='http://blog.webducer.de/2011/10/android-erste-app-wahrungsrechner-%e2%80%93-teil-2/localization-ressource/' title='Localization Ressource'><img width="150" height="150" src="http://blog.webducer.de/wp-content/uploads/2011/10/Localization-Ressource-150x150.png" class="attachment-thumbnail" alt="Localization Ressource" title="Localization Ressource" /></a>
<a href='http://blog.webducer.de/2011/10/android-erste-app-wahrungsrechner-%e2%80%93-teil-2/wahrungsapp/' title='Währungsapp'><img width="150" height="150" src="http://blog.webducer.de/wp-content/uploads/2011/10/Währungsapp-150x150.png" class="attachment-thumbnail" alt="Währungsapp" title="Währungsapp" /></a>
</p>
<p>Dafür befolgen Sie die folgenden Schritte:</p>
<ol>
<li>Klicken Sie mit der rechten Maustaste auf das Projekt in der Package-Explorer Ansicht.</li>
<li>Wählen Sie den Punkt &#8220;<strong><code>Android Tools</code></strong>&#8221; (ganz unten im Kontextmenü).</li>
<li>Wählen Sie im Untermenü &#8220;<strong><code>New Resource File ...</code></strong>&#8220;.</li>
<li>Geben Sie als File &#8220;<strong><code>arrays</code></strong>&#8221; ein.</li>
<li>Wählen Sie als Typ &#8220;<strong><code>Values</code></strong>&#8221; aus.</li>
<li>Klicken Sie auf &#8220;<strong><code>Finish</code></strong>&#8220;.</li>
</ol>
<p>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 &#8220;<strong><code>Add</code></strong>&#8221; Knopf ein neues StringArray (siehe Bilder) mit dem Namen &#8220;<strong><code>waehrung</code></strong>&#8220;, oder Sie geben die Werte direkt als XML-Code ein. Die XML-Darstellungen sehen Sie weiter unten.</p>
<h3>array.xml</h3>
<pre class="brush: xml; gutter: true">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
    &lt;string-array name="waehrung"&gt;
        &lt;item&gt;EUR - Euro&lt;/item&gt;
        &lt;item&gt;USD - Amerikanische Dollar&lt;/item&gt;
        &lt;item&gt;AUD - Australische Dollar&lt;/item&gt;
        &lt;item&gt;RUB - Russische Rubel&lt;/item&gt;
        &lt;item&gt;CUD - Kanadische Dollar&lt;/item&gt;
        &lt;item&gt;GBP - Englische Pfund&lt;/item&gt;
    &lt;/string-array&gt;
    &lt;string-array name="waehrung_kurs"&gt;
        &lt;item&gt;1&lt;/item&gt;
        &lt;item&gt;1.3795&lt;/item&gt;
        &lt;item&gt;1.3314&lt;/item&gt;
        &lt;item&gt;42.1941&lt;/item&gt;
        &lt;item&gt;1.3495&lt;/item&gt;
        &lt;item&gt;0.8738&lt;/item&gt;
    &lt;/string-array&gt;
&lt;/resources&gt;</pre>
<p>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.</p>
<p>Um die Auswahlliste an eine Auflistung zu binden, müssen wir nur in unseren Layout-Datei &#8220;main.xml&#8221; bei den beiden Auswahllisten (Spinner) folgende Zeile (Zeile Nr. 6) hinzufügen.</p>
<pre class="brush: xml; gutter: true">&lt;Spinner
	android:layout_height="wrap_content"
	android:layout_width="0dp"
	android:layout_weight="1"
	android:id="@+id/selWaehrungStart"
	android:entries="@array/waehrung"&gt;
&lt;/Spinner&gt;</pre>
<p>Wenn Sie jetzt die App starten, können Sie bereits die Ausgangs- und Zielwährung wählen (siehe Bild).</p>
<p>Nun können wir uns den Java-Quellcode widmen. Als Erstes sollte unser &#8220;<strong><code>Berechnen</code></strong>&#8221; 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.</p>
<p>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 <code>Methode findViewById(ID)</code>. Da die Methode die Basisklasse &#8220;View&#8221; zurückliefert, müssen wir den Rückgabewert noch auf das zu erwartende View (in unserem Fall Button) kasten (<code>Button cmdBerechnen = (Button)findViewById(R.id.cmdBerechnen);</code>). Wie an diesem Beispiel zu sehen ist, greifen wir auf die automatisch generierte &#8220;<code>R</code>&#8220;-Klasse, die uns die Referenzen auf unsere Ressourcen zur Verfügung stellt. Dabei sind folgende oft verwendete Referenzen wichtig:</p>
<ul>
<li><code>R.id</code> : Referenzen auf die Views der Layouts. Im Layout sind das die <code>android:id=""</code> Attribute</li>
<li><code>R.layout</code> : Referenzen auf die Layout-Dateien</li>
<li><code>R.string</code> : Referenzen auf unsere definierten Texte</li>
<li><code>R.array</code> : Referenzen auf unsere definierte Auflistungen</li>
<li><code>R.color</code> : Referenzen auf die Farben</li>
<li><code>R.drawable</code> : Referenzen auf die Bilder</li>
<li>und einige weitere. Weitere Infos dazu finden Sie unter: <a title="Resource Types | Android Developer" href="http://developer.android.com/guide/topics/resources/available-resources.html">developer.android.com</a></li>
</ul>
<p>Den Listener fügen Sie mit der folgen Zeile hinzu:</p>
<pre class="brush: java; gutter: true">cmdBerechnen.setOnClickListener(new OnClickListener() {
	public void onClick(View v) {
		kursBerechnen();
	}
});</pre>
<p>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.</p>
<h3>HauptActivity.java</h3>
<pre class="brush: java; gutter: true">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 &amp;&amp; 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 &amp;&amp; kursStartText != "" &amp;&amp; !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 &amp;&amp; kursEndeText != "" &amp;&amp; !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());
    	}
    }
}</pre>
<p>In der Zeile 21 wird durch den Aufruf der Methode <code>setContentView(R.layout.main);</code> wiesen wir unseren Activity <code>HauptActivity.java</code> ein Layout zu, den wir wieder über die generierte Klasse &#8220;<code>R</code>&#8221; ansprechen.</p>
<p>Der Aufruf unserer eigenen Methode <code>Init()</code> in der Zeile 23 setzt den Listener für unseren Berechnungs-Knopf. Nun wenden wir uns der eigentlichen Berechnung zu (Zeilen 75 bis 142).</p>
<p>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).</p>
<p>In der Zeile 87 erhalten wir durch den Aufruf der Methode <code>getText()</code> 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).</p>
<p>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.</p>
<p>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:</p>
<pre class="brush: text; gutter: true">EUR 125,00 = USD 172,44</pre>
<p>Damit wir auch eine Geschichte unserer Berechnungen erhalten, hängen wir in der Zeile 140 unser Ergebnis an den vorhandenen Text an.</p>
<p>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 <code>array.xml</code>-Datei in dem Werte-Array die Punkte durch die Kommas aus (erzeugt Fehler beim Konvertieren).</p>
<h2>Lokalisierung</h2>
<p>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.</p>
<p>In unserer App müssen die Daten aus der <code>strings.xml</code> und <code>arrays.xml</code> Dateien übersetzt werden. Dafür klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie <code>Android Tools</code> -&gt; <code>New Ressource File...</code> . Wie im Bild zu sehen ist, muss für neue Sprache nun unter &#8220;<code>Available Qualifiers</code>&#8221; &#8220;<code>Language</code>&#8221; auswählen und auf der rechten Seite den zweistelligen Ländercode eingeben (&#8220;<code>en</code>&#8221; 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 &#8220;<code>res/values-en</code>&#8220;.</p>
<h3>strings.xml</h3>
<pre class="brush: xml; gutter: true">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
	&lt;!-- Globale Strings --&gt;
	&lt;string name="app_name"&gt;Currency Calculator&lt;/string&gt;

	&lt;!-- View Texte --&gt;
    &lt;string name="betrag_eingeben"&gt;Please type the value to calculate!&lt;/string&gt;
    &lt;string name="cmd_berechnen"&gt;Calculate&lt;/string&gt;

    &lt;!-- Menü --&gt;
    &lt;string name="opt_loeschen"&gt;Clear Result List&lt;/string&gt;
    &lt;string name="opt_loeschen_kurz"&gt;Clear&lt;/string&gt;
    &lt;string name="opt_schliessen"&gt;Close App&lt;/string&gt;
    &lt;string name="opt_schliessen_kurz"&gt;Close&lt;/string&gt;

    &lt;!-- Fehlertexte --&gt;
    &lt;string name="err_betarg_format"&gt;The value has wrong format!&lt;/string&gt;
    &lt;string name="err_kurs_format"&gt;The currency value has wrong format!&lt;/string&gt;
&lt;/resources&gt;</pre>
<h3>arrays.xml</h3>
<pre class="brush: xml; gutter: true">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
    &lt;string-array name="waehrung"&gt;
        &lt;item&gt;EUR - Euro&lt;/item&gt;
        &lt;item&gt;USD - American Dollar&lt;/item&gt;
        &lt;item&gt;AUD - Australian Dollar&lt;/item&gt;
        &lt;item&gt;RUB - Russian Rubel&lt;/item&gt;
        &lt;item&gt;CUD - Canadian Dollar&lt;/item&gt;
        &lt;item&gt;GBP - Great Britain Pound&lt;/item&gt;
    &lt;/string-array&gt;
&lt;/resources&gt;</pre>
<h2>Menü</h2>
<p>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 &#8220;<code>res/menu</code>&#8220;.</p>
<h3>menu.xml</h3>
<pre class="brush: xml; gutter: true">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;menu
  xmlns:android="http://schemas.android.com/apk/res/android"&gt;
    &lt;item
    	android:title="@string/opt_loeschen"
    	android:titleCondensed="@string/opt_loeschen_kurz"
    	android:id="@+id/optLoeschen"
    	android:icon="@drawable/opt_clear" /&gt;
    &lt;item
    	android:title="@string/opt_schliessen"
    	android:titleCondensed="@string/opt_schliessen_kurz"
    	android:id="@+id/optSchliessen"
    	android:icon="@drawable/opt_close" /&gt;
&lt;/menu&gt;</pre>
<p>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 <code>onCreate</code>-Methode). Dafür dient die überschriebene Methode <code>onCreateOptionsMenu()</code>. Unter Optionsmenü versteht man unter Android das Menü, das durch das Betätigen der Menütaste erscheint.</p>
<p>Die Auswertung, welches der Menüpunkte nun ausgewählt wurde, erfolgt in der überschriebenen Methode <code>onOptionsItemSelected()</code>. Ü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 <code>this.finish()</code> (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).</p>
<p>Damit ist unsere App so weit funktionsfähig und einsatzbereit. Die Kurse können sehr einfach in der XML-Datei angepasst und erweitert werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webducer.de/2011/10/android-erste-app-wahrungsrechner-%e2%80%93-teil-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mehrere gleichnamige Zertifikate unter Thunderbird nutzen</title>
		<link>http://blog.webducer.de/2010/02/mehrere-gleichnamige-zertifikate-unter-thunderbird-nutzen/</link>
		<comments>http://blog.webducer.de/2010/02/mehrere-gleichnamige-zertifikate-unter-thunderbird-nutzen/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 21:50:52 +0000</pubDate>
		<dc:creator>WebDucer</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[certificate]]></category>
		<category><![CDATA[digital]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[Thunderbird]]></category>
		<category><![CDATA[trustcenter]]></category>
		<category><![CDATA[Zertifikat]]></category>

		<guid isPermaLink="false">http://blog.webducer.de/?p=81</guid>
		<description><![CDATA[Heute bin ich mit einem Problem gestoßen. Ich habe mir für meine zwei Haupt-Email-Adressen Zertifikate bei trustcenter.de bestellt.  Naturgemäß lauten beide auf meinen Namen. Theoretisch sollte es damit auch keine Probleme geben, da beide ja auf unterschiedliche Email-Adressen ausgestellt sind. Auf dem Mac unter Mail gab es auch keine Probleme. Beide Zertifikate wurden problemlos importiert [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_84" class="wp-caption alignleft" style="width: 310px"><a href="http://blog.webducer.de/wp-content/uploads/2010/02/Thunderbird1.png"><img class="size-medium wp-image-84" title="Zertifikatübersicht" src="http://blog.webducer.de/wp-content/uploads/2010/02/Thunderbird1-300x194.png" alt="Zertifikatübersicht" width="300" height="194" /></a><p class="wp-caption-text">Zertifikatübersicht</p></div>
<p>Heute bin ich mit einem Problem gestoßen. Ich habe mir für meine zwei Haupt-Email-Adressen Zertifikate bei trustcenter.de bestellt.  Naturgemäß lauten beide auf meinen Namen. Theoretisch sollte es damit auch keine Probleme geben, da beide ja auf unterschiedliche Email-Adressen ausgestellt sind.</p>
<p>Auf dem Mac unter Mail gab es auch keine Probleme. Beide Zertifikate wurden problemlos importiert und konnten zum Signieren und Verschlüsseln benutzt werden.</p>
<h1>Problem</h1>
<div id="attachment_85" class="wp-caption alignright" style="width: 310px"><a href="http://blog.webducer.de/wp-content/uploads/2010/02/Thunderbird2.png"><img class="size-medium wp-image-85" title="Zertifikatzuordnung" src="http://blog.webducer.de/wp-content/uploads/2010/02/Thunderbird2-300x137.png" alt="Zertifikatzuordnung" width="300" height="137" /></a><p class="wp-caption-text">Zertifikatzuordnung</p></div>
<p>Auf dem EeePC bin ich vor Kurzem von Windows Live-Mail auf Thunderbird 3.0 umgestiegen. Der Import verlief auch ohne Probleme und es wurden beide Zertifikate in der Übersicht angezeigt. Das Problem taucht auf, wenn man versucht die Zertifikate den einzelnen Email-Adressen zuzuweisen. In der Drop-Down-Liste erscheint nur ein einziges Zertifikat statt der beiden importierten.</p>
<p>Einzeln importiert funktionieren diese problemlos. Zusammen importiert, wird nur ein Zertifikat angezeigt.</p>
<p>Nach langer Recherche konnte die Ursache in der Bildung der Drop-Down-Liste von Thunderbird festgestellt werden. Zur Bildung der Liste werden bei Thunderbird nur Vor- und Nachnahme benutzt (CN), aber nicht die erweiterten Felder des Zertifikates. Viele andere Zertifikathersteller schreiben in die CN noch weitere Daten, sodass das beschriebene Problem meines Wissens nur bei trustcenter.de auftritt. Die Auszeichnung, wie trustcenter.de dies tut, entsprich der Empfehlung des Zertifikatstandards.</p>
<h1>Lösung</h1>
<div id="attachment_87" class="wp-caption alignleft" style="width: 310px"><a href="http://blog.webducer.de/wp-content/uploads/2010/02/Thunderbird3.png"><img class="size-medium wp-image-87" title="Allgeminer Name" src="http://blog.webducer.de/wp-content/uploads/2010/02/Thunderbird3-300x253.png" alt="Allgeminer Name" width="300" height="253" /></a><p class="wp-caption-text">Allgeminer Name</p></div>
<p>Um das Problem bei Thunderbird und trustcenter.de zu umschiffen, habe ich eins von meinen Zertifikaten gesperrt und ein neues beantragt. Dieses Mal aber in dem Feld Vorname nicht nur meinen Vornamen eingegeben, sondern &#8220;Herr &#8230;&#8221;.</p>
<p>Nach dem neuen Import hat Thunderbird nun beide Zertifikate richtig aufgelistet und ich konnte diese den jeweiligen Email-Adressen zuordnen.</p>
<div id="attachment_86" class="wp-caption alignright" style="width: 310px"><a href="http://blog.webducer.de/wp-content/uploads/2010/02/Thunderbird4.png"><img class="size-medium wp-image-86 " title="Alternativer Name" src="http://blog.webducer.de/wp-content/uploads/2010/02/Thunderbird4-300x93.png" alt="Alternativer Name" width="300" height="93" /></a><p class="wp-caption-text">Alternativer Name</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.webducer.de/2010/02/mehrere-gleichnamige-zertifikate-unter-thunderbird-nutzen/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

