Kurs Android (12)

Autor: Damian Chodorek • Opublikowany: 12 sierpnia 2015 • Ostatnia aktualizacja: 3 marca 2016 • Kategoria: android, kursy

Aplikacja korzystająca z Web Service’ów (usług internetowych). Część 2. Wysyłanie danych na serwer.

Integralną częścią tej lekcji, jest lekcja poprzednia, którą znajdziesz na tej stronie. Wspomniałem ostatnio, że metoda GET służy do pobierania danych z serwera. Jest to domyślna metoda przeglądarek. Po wejściu na stronę http://damianchodorek.com/wsexample/ zobaczysz przykładowe dane pobrane z serwera.

Co w przypadku, gdy chcesz wysłać dane na serwer? W tym celu należy skorzystać z metody POST protokołu HTTP. W naszym przykładzie dane wyślemy w formacie JSON. Typowo Web Service’y w odpowiedzi na wstawienie danych odsyłają wstawiony obiekt, z nadanym przez serwer id.

Metodą POST wysyłamy więc przykładowo obiekt, który serwer powinien umieścić w swojej bazie danych:

{
    "name" : "some name"
}

Po odebraniu obiektu, serwer wstawia go do bazy danych i wysyła swoją instancję obiektu:

{
    "id" : 1,
    "name" : "some name"
}

Właśnie w ten sposób zadziała nasza aplikacja.

Jak wstawić dane na serwer?

W przykładzie skorzystamy z aplikacji, którą stworzyliśmy w poprzedniej lekcji. Na początku zmodyfikujemy layout, tak aby użytkownik mógł wpisać jakieś przykładowe dane, które zostaną wysłane na serwer.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <EditText
        android:id="@+id/req_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:hint="Wpisz przykładowe imie, np. Jan" />

    <Button
        android:id="@+id/start_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="Start" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="Odpowiedź serwera:"
        android:textSize="20sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/response_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="id: "
        android:textSize="15sp" />

    <TextView
        android:id="@+id/response_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="name: "
        android:textSize="15sp" />

</LinearLayout>

Jak widzisz layout jest taki sam jak ostatnio, ale dodaliśmy element EditText. Aby wykonać wysłanie danych na serwer, a następnie odebrać odpowiedź od niego, zmodyfikujemy metodę doInBackground() klasy WebServiceHandler, którą stworzyliśmy ostatnio. Kod poniżej.

@Override
protected String doInBackground(String... urls) {

    try {
        // zakładamy, że jest tylko jeden URL
        URL url = new URL(urls[0]);
        HttpURLConnection connection = (HttpURLConnection) url
                .openConnection();
        connection.setReadTimeout(10000 /* milliseconds */);
        connection.setConnectTimeout(15000 /* milliseconds */);

        // zezwolenie na wysyłanie danych
        connection.setDoOutput(true);
        // ustawienie typu wysyłanych danych
        connection.setRequestProperty("Content-Type",
                "application/json");
        // ustawienie metody
        connection.setRequestMethod("POST");

        // stworzenie obiektu do wysłania
        JSONObject data = new JSONObject();
        data.put("name", ((EditText) findViewById(R.id.req_name))
                .getText().toString());

        // wysłanie obiektu
        BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(connection.getOutputStream(),
                        "UTF-8"));
        writer.write(data.toString());
        writer.close();
        
        //////////////////////////////////////////
        // na tym etapie obiekt został wysłany
        // i dostaliśmy odpowiedź serwera
        //////////////////////////////////////////

        // sprawdzenie kodu odpowiedzi, 200 = OK
        if (connection.getResponseCode() != 200) {
            throw new Exception("Bad Request");
        }

        // pobranie odpowiedzi serwera
        InputStream in = new BufferedInputStream(
                connection.getInputStream());

        // konwersja InputStream na String
        // wynik będzie przekazany do metody onPostExecute()
        return streamToString(in);

    } catch (Exception e) {
        // obsłuż wyjątek
        Log.d(MainActivity.class.getSimpleName(), e.toString());
        return null;
    }

}

Po dokonaniu zmian aplikacja powinna już zadziałać.

Na koniec podaję jeszcze skrypt PHP, który obsługuje żądania.

<?
switch($_SERVER['REQUEST_METHOD'])
{
    case 'GET': 
        echo 
            '{"id": '.rand(1, 100).',"name":"example_'.rand(1, 100).'"}';
        break;
    case 'POST':
        $data = file_get_contents('php://input');
        $json = json_decode($data);
        $name = $json->{'name'};
        
        if(isset($name) && $name!=''){
            http_response_code(200);
            echo 
                '{"id": '.rand(1, 100).',"name":"'.$name.'"}';
        }else
            // bad request
            http_response_code(400);
        break;
}

?>

część 13