Android an Webservice: Hörst du mich?

Ein ‚Hallo Welt‘ habe ich in Android schon geschafft. (Erste Schritte mit Android). Nun habe ich mir gedacht (5 Monate später): Vielleicht sollte man das Thema nochmal aufgreifen. Zu meinem ersten Artikel kann ich nun folgendes ergänzen:
Auf einem 64 Bit System reicht Java Development Kit 7u2 x64 vollkommen aus um das Android SDK (r16) zu installieren. Die x86 Version des JDK wird also nicht benötigt.

Da ich seitdem auch nichts mehr gemacht habe musste ich bei diesem Projekt auch wieder ganz von Vorne beginnen. Gut, dass ich das Ganze in einem Blog-Eintrag festgehalten habe. So war das Grundgerüst in wenigen Minuten installiert. Gut. Das Android SDK hat dann schon noch ein wenig gebraucht, bis es alle Komponenten geladen und installiert hatte.

Ich hab‘ mir die Arbeit aber natürlich nicht gemacht ohne eine konkrete Idee zu haben was ich machen möchte. Schritt 1 für mich war aber erst mal noch ein wenig die Konzepte von Android zu studieren. Schritt 2 war dann: Was produktives.

Schritt 1 geht bei mir immer ganz schnell. Dieser wird einfach in Schritt 2 integriert. Daher legte ich gleich los. Ich habe doch diesen tollen WebService mit dem ich mir die Daten von Amazon abrufen kann. Die Amazon App ist ja schon nicht schlecht, aber wer auch gerne mal im Ausland einkauft steht dann im Laden fünf Minuten vor einem Artikel: Code scannen, Preis abfragen, Standort ändern, Code scannen, Preis abfragen, Standort ändern, Code scannen, … Daher meine Idee, dass ich meinen Webservice dafür nutze und mir dadurch die Preise aller Amazon Standorte hole. Soweit die Theorie …


Anmerkung: Mir geht’s am Anfang nur mal um die Funktionalität, wie ich die Maske schön aufbauen kann, werde ich mir dann später überlegen. Dafür ist ja der Code von der UI getrennt 😉

Zu Beginn mussten erst einmal ein paar Controls auf die Maske. Ein Eingabefeld. Ein Button um den Scanner aufzurufen und einen um die Query abzusetzen. Nichts leichter als das. ‚main.xml‘ öffnen und die entsprechenden Felder definieren.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
   <EditText
        android:id="@+id/txtEAN"
        android:inputType="text"
        android:layout_width="232dp"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" />
    <Button
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/btnStartScanner"
        android:layout_width="62dp"
        android:layout_height="40dp"
        android:layout_alignBaseline="@+id/txtEAN"
        android:layout_alignBottom="@+id/txtEAN"
        android:layout_alignParentRight="true"
        android:onClick="btnStartScanner"
        android:text="@string/startScanner" />
    <Button
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/bntStartQuery"
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/txtEAN"
        android:onClick="btnQueryWebservice"
        android:text="@string/startQuery" />
</RelativeLayout>

Das sieht schon mal ganz gut aus. Die Texte kommen aus der Ressource. Es wurden eindeutige IDs vergeben und auch die onClick Ereignisse wurden hier bereits zugewiesen.


Weiter geht’s zum nächsten Punkt: Wie spreche in den Barcodescanner an? Google macht es da einem nicht sehr schwer. Nach einer Minute wird einem eine Lösung präsentiert. An ein paar Stellen noch Fine-Tuning vornehmen. Perfekt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
final int ACTIVITY_REQUEST_SCANNER = 0;
 
public void btnStartScanner(View v) 
{
    Intent intent = new Intent("com.google.zxing.client.android.SCAN");
    intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
    startActivityForResult(intent, ACTIVITY_REQUEST_SCANNER);
}
 
public void onActivityResult(int requestCode, int resultCode, Intent intent) 
{
    if ((requestCode == ACTIVITY_REQUEST_SCANNER) && (resultCode == RESULT_OK))
    {
        String contents = intent.getStringExtra("SCAN_RESULT");
        String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
 
        EditText b = (EditText)findViewById(R.id.txtEAN);
        b.setText(contents);
    }
}

Zeile 1: Zuerst definiere ich mir eine Konstante für den ‚requestCode‘. Das ist zwar nicht zwingend notwendig, aber ich vermeide dadurch ‚Magic Numbers‘.

Zeile 3: Anschließend folgt schon das in der XML zugewiesene OnClick Ereignis. Intent für den Scanner definieren. Scan Mode festlegen, so dass wir EANs scannen können. Activity starten. Hierbei wird das Intent und unsere Konstante mitgegeben.

Zeile 10: Anschließend folgt das ‚onActivityResult‘ Event, mit dem man das Ergebnis auswerten kann. Ich prüfe hier ab, ob ein gültiges Resultat zurückgegeben wurde und ob der ‚requestCode‘ meiner Konstante entspricht. Ist das der Fall, so hole ich mir den Wert und zeige diesen in der Textbox an.


So macht programmieren Spaß, wenn alles so einfach geht. Jetzt nur noch schnelle die Webservice abfragen einbinden. Im Rausch der Euphorie fahre ich mit 200km/h gegen eine Wand. So einfach wie ich mir das dachte ist es dann wohl doch nicht. Jedoch hilft auch hier Google weiter. Damit man dem Webservice ansprechen kann ist eine kleine Komponente nötig: KSoap.

Kurze Info zur Installation: Aktuelle ‚jar‘ herunterladen. Im Eclipse ein Rechtsklick auf das Projekt -> ‚Properties‘. Dort beim ‚Java Build Path‘ auf den Reiter ‚Libraries‘ und ‚Add External Jars…‘ auswählen. Dann sucht man das heruntergeladene Paket und wählt dieses aus. Es sollte dann in etwa so aussehen:

Eclipse & KSoap2

Ich habe am Ende noch zwei Artikel zum Thema KSopa verlinkt. Mit Hilfe dieser Samples konnte ich mir folgende Code-Zeile erarbeiten.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public void btnQueryWebservice(View v) 
{
    EditText editField = (EditText)findViewById(R.id.txtEAN);
 
    String NAMESPACE = "http://webservices.project-medlan.de/";
    String METHOD_NAME = "NameDerMethode";
    String SOAP_ACTION = "http://webservices.project-medlan.de/NameDerMethode";
    String URL = "http://webservices.project-medlan.de/MeinWebservice.php";
 
    SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
    Request.addProperty("item", ""+editField.getText());
 
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.setOutputSoapObject(Request);
 
    AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
    try
    {
        androidHttpTransport.call(SOAP_ACTION, envelope);
        Object response = envelope.getResponse();
        String result = "";
        if (response instanceof SoapPrimitive)
        {
            result = ((SoapPrimitive)response).toString();
        }
        editField.setText(result);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

Hab‘ das Ganze ein wenig verkürzt und natürlich meine Produktivdaten überschrieben 😉
Der Anfang ist noch einfach. Wir holen uns die Eingabe aus der Textbox. Anschließend folgen die nötigen Definitionen für den WebService-Zugriff. Nachdem wir uns ein ‚Request‘ erstellt haben (Zeile 10) können wir diesem dann unsere nötigen Parameter mitteilen. Die weiteren Aufrufe wurden 1:1 aus dem Tutorial übernommen. SoapSerializationEnvelope & AndroidHttpTransport Objekte erstellen; die nötigen Parameter setzten; Webservice aufrufen (Zeile 19).
Danach muss nur noch das Ergebnis ausgewertet werden. Zum Test gebe ich das wieder in der Textbox aus.

Wer beim Lesen bis hierhergekommen ist und seinen Code entsprechend angepasst hat, wird nun feststellen: ‚Das geht nicht‘. Klar. Ein wichtiger Punkt fehlt nämlich noch. Eure App muss natürlich Zugriff auf das Internet haben! Die Manifest Datei öffnen und folgenden Eintrag ergänzen:

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

Wenn es jetzt noch nicht funktioniert, dann habt ihr entweder was falsch gemacht oder ihr habt das Internet auf eurem Telefon deaktiviert (Ihr lacht? Das hat mich fast eine Stunde gekostet, bis mir das aufgefallen ist)

Wie versprochen hier noch einige interessamte Links zu diesem Thema:

Barcode Scanner verwenden / Stackoverflow

KSoap2 für Android / Google Code

Basic KSoap Tutorial
Weiteres KSoap Tutorial (Russisch-Kenntnisse von Vorteil)

Ein Kommentar

  1. Wenn man eine aktuelle Version von KSoap2 für Android verwendet, dann wird man mit dieser Zeile Probleme bekommen:

    AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);

    AndroidHttpTransport wurde wohl als veraltet markiert und in den aktuellen Versionen entfernt.
    Die Zeile kann durch folgende ersetzt werden:

    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

    Folgender Import wird dann noch benötigt:

    import org.ksoap2.transport.HttpTransportSE;

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.