Android-Programmierung: Netzwerk
Willemers Informatik-Ecke
Die Netzwerkprogrammierung hat ein paar Besonderheiten.

Um Erlaubnis bitten

Damit ein Programm im Netzwerk arbeiten darf, muss in der Datei AndroidManifest.xml die Erlaubnis für INTERNET hinterlegt sein.
<uses-permission android:name="android.permission.INTERNET"/>
Dieser Eintrag muss außerhalb des application-Tags sein, am besten gleich zu Anfang der Datei.

Prüfe auf Netzwerkfähigkeit

Mit der folgenden Methode wird geprüft, ob das Programm auf das Netzwerk zugreifen kann.
public boolean isNetAvailable() {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVER);
    NetworkInfo ni = cm.getActiveNetworkInfo();
    return ni != null && ni.isConnectedOrConnecting();
}
Für diese Prüfung ist neben der INTERNET-Permission auch die Permission ACCESS_NETWORK_STATE erforderlich:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

HTTP-Client

HTTP-POST mit Thread

Das folgende Beispiel zeigt eine HTTP-POST-Sendung von Android aus. Damit der UI-Thread nicht blockiert, wird der Netzwerkverkehr in einen eigenen Thread ausgelagert. Um die Ergebnisse auf der Oberfläche darzustellen, wird runOnUiThread verwendet, da der Hintergrund-Thread selbst keinen Zugriff darauf hat.
public void postText(final String text) { // final, da vom Thread ausgelesen
    // Weil Netzwerkoperationen blockieren können, müssen sie in einen
    // anderen Thread als die Activity
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                // Parameter soll gepostet werden. Dazu muss er URL-Encoded werden,
                // damit Leerzeichen und Umlaute verschwinden.
                // feld= entspricht dem input einer HTML-Form
                String param = "feld="+ URLEncoder.encode(text, "UTF-8");

                URL url = new URL("http://www.willemer.de/echoString"); // URL ist ein Dummy! Bitte anpassen!
                HttpURLConnection connect = (HttpURLConnection) url.openConnection();
                connect.setDoOutput(true);
                connect.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                // Länge der Message: Achtung UTF-8 erzwingt getBytes
                connect.setFixedLengthStreamingMode(param.getBytes().length);

                OutputStreamWriter out = new OutputStreamWriter(connect.getOutputStream());
                out.write(param);
                out.flush();
                out.close();

                InputStream is = connect.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                StringBuilder sb = new StringBuilder();

                String zeile;
                while ((zeile = br.readLine())!= null) {
                    sb.append(zeile);
                    sb.append("\n");
                }
                // wird in anderem Runnable benötigt, also final
                final String antwort = sb.toString().trim();
                // Zugriff auf das TextView der Activity
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText(antwort);
                    }
                });
                // Aufräumen!
                is.close();
                connect.disconnect();
            } catch (UnsupportedEncodingException e) {
            } catch (MalformedURLException e) {
            } catch (IOException e) {
            }
        }
    }).start(); // starte im Background
}

Service

Für die Kommunikation wird ein eigener Service erstellt. Das wird über das Menü File|New|Service|Service erreicht. Als Namen vergeben wir NetzwerkService. Die Implementierung enthält einen Thread, der die Netzwerkaktion durchführt. Der Thread meldet sich nach getaner Arbeit bei der Activity zurück.
package de.willemer.phpclient;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

public class NetzwerkService extends Service {
    // private static final String url ="http://10.0.2.2/gast.php";
    private final IBinder netzwerkBinder = new NetzwerkBinder();

    public NetzwerkService() {
    }

    // Wir bauen eine eigene Binder-Klasse
    public class NetzwerkBinder extends Binder {
        public NetzwerkService getService() {
            return NetzwerkService.this;
        }
        public void senden(final Handler threadHandler, String msg) {
            Thread thread = new Thread() {
                @Override
                public void run()  {
                    long error = 0;
                    // error = dieEigentlicheSendeMethode();
                    Message msg = new Message();
                    Bundle bundle = new Bundle();
                    bundle.putLong("stauId", error);
                    msg.setData(bundle);
                    threadHandler.sendMessage(msg);
                }
            };
            thread.start();
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return netzwerkBinder;
    }
}