Android DeveloperDeveloperFeatured

เขียนแอพ Android เรียก JSON Web service แสดงบน ListView

บทเรียนเบื้องต้นสำหรับผู้พัฒนาแอพพลิเคชัน Android กับการใช้งาน ListView แสดงข้อมูลจาก Web Service รูปแบบ JSON มาใช้งานสำหรับผู้เริ่มต้น บน Android Studio

เราจะทดสอบโปรเจ็คนี้โดยการเขียนภาษา PHP ร่วมกับ MySQL เพื่อ Echo ค่าของ PHP ออกมาเป็น JSON ครับ ให้เตรียมฐานข้อมูลโดยใช้ SQL Command ต่อไปนี้

CREATE TABLE IF NOT EXISTS 'movie' (
  'id' int(10) NOT NULL,
  'title' varchar(255) COLLATE utf8_bin DEFAULT NULL,
  'image' text COLLATE utf8_bin,
  'description' text COLLATE utf8_bin
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;

เป็น Table ที่ชื่อว่า “Movie” นั่นเองครับ ให้ใส่ข้อมูลลงไปสัก 2-3 Row ครับ

Screen Shot 2558-03-29 at 10.09.54 PM

รูปแบบของ Web Service ที่เราจะใช้ คือ JSON ซึ่งก็ไม่ต่างจาก XML แบบเก่าๆ หรอกครับ ลองเปรียบเทียบรูปแบบดูจะเห็นว่า JSON จะเขียนเรียกเป็น Key ง่ายกว่าแค่นั้นเอง

Screen Shot 2558-03-29 at 10.11.35 PM

ต่อมาเป็นคำสั่ง PHP สำหรับ Echo ค่าในตาราง MySQL ออกมาเป็น JSON ครับให้เขียนตามนี้

<?php
	$objConnect = mysql_connect("localhost","root","");
	$objDB = mysql_select_db("moviestore");
	mysql_query("SET NAMES UTF8");
	$SQLstring = "SELECT * FROM movie ORDER BY id ASC  ";

	$objQuery = mysql_query($SQLstring);
	$numRows = mysql_num_fields($objQuery);
	$resultArray = array();
	while($obResult = mysql_fetch_array($objQuery))
	{
		$arrCol = array();
		for($i=0;$i<$numRows;$i++)
		{
			$arrCol[mysql_field_name($objQuery,$i)] = $obResult[$i];
		}
		array_push($resultArray,$arrCol);
	}
	mysql_close($objConnect);
	header ('Content-type: text/html; charset=utf-8');
	echo json_encode($resultArray);
?>

ให้ทดสอบโดยการอัพโหลด ไฟล์นี้ไปบน Host ของเราแล้วลองเรียกดูเราจะเห็นว่า มันแสดงผลเป็น Key Value แบบ JSON เรียบร้อย

Screen Shot 2558-03-21 at 10.16.10 AM

หากใช้ Chrome ลอกโหลด Add-on ที่ชื่อ JSON View ดูครับ จะแสดงผลได้ดังภาพข้างบน

Screen Shot 2558-03-21 at 10.17.15 AM

https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc

เปิด Android Studio ขึ้นมาครับ แล้วนำ ListView มาวางบน Layout

Screen Shot 2558-03-21 at 10.19.51 AM

ให้เราสร้างไฟล์ Layout เพิ่มมาอีกไฟล์ชื่อว่า activity_colums.xml ครับ ไว้แสดงผลของ แถวที่จะปรากฏบน ListView หลังจากนั้นให้เปิดไฟล์ activity_main.xml ขึ้นมาใส่ code ดังนี้ครับ

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>

</RelativeLayout>

ตามด้วยเปิดไฟล์ acivity_column.xml ขึ้นมาครับ ใส่ code นี้ลงไป

<?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">


    <TextView
        android:id="@+id/articleID"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.2"
        android:text="ID"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textSize="20dp" />

    <TextView
        android:id="@+id/articleTitle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Name"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textSize="20dp" />

</LinearLayout>

ซึ่งจะมีค่า ID ที่ใช้งานอยู่ 2 ตัวคือ articleID ไว้เก็บ ID จาก JSON และ articleTitle ไว้เก็บค่า Title จาก JSON เช่นกันครับ

ต่อมาไปที่ โฟลเดอร์ Manifest หาไฟล์ AndroidManifest.xml ครับให้เราเพิ่ม Permission ในการต่ออินเทอร์เน็ตลงไป

Screen Shot 2558-03-21 at 10.47.10 AM

 

ใส่ลงไปตามภาพครับ ส่วนของ uses-permission

Screen Shot 2558-03-21 at 10.45.43 AM

เปิดไฟล์ MainActivity.java ขึ้นมา เพิ่ม import ส่วน Header File ดังนี้

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.StrictMode;
import android.annotation.SuppressLint;
import android.util.Log;
import android.widget.ListView;
import android.widget.SimpleAdapter;

เขียนคำสั่ง JSON กับ ListView เพิ่มเข้ามา ก่อนอื่นให้สร้างเมธอดฟังก์ชันมาใหม่ชื่อ getJSON();

public String getJSON(String url,List<NameValuePair> params) {
        StringBuilder str = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        try {
            httpPost.setEntity(new UrlEncodedFormEntity(params));
            HttpResponse response = client.execute(httpPost);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader_buffer = new BufferedReader
                (new InputStreamReader(content));

                String line;
                while ((line = reader_buffer.readLine()) != null) {
                    str.append(line);
                }
            } else {
                Log.e("Log", "Failed to download file..");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str.toString();
    }

เป็นการเรียก entity ของ key value มาเก็บไว้ในตัวแปรสำหรับแสดงค่า โดยใช้ HTTP Request มาใช้เรียก API ของ Webservices ผ่าน status_code ที่เราทราบกันดีว่า 200 คือโอเค

เสร็จแล้วก็เขียนฟังก์ชันเพิ่ม ใน onCreate();

@SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

        final ListView listViewMovies = (ListView)findViewById(R.id.listView1);
        String url = "http://lovedesigner.net/feed/json";

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        try {
            JSONArray data = new JSONArray(getJSON(url,params));

            final ArrayList<HashMap<String, String>> MyArrList = new ArrayList<HashMap<String, String>>();
            HashMap<String, String> map;

            for(int i = 0; i < data.length(); i++){
                JSONObject c = data.getJSONObject(i);

                map = new HashMap<String, String>();
                map.put("id", c.getString("id"));
                map.put("title", c.getString("title"));
                MyArrList.add(map);

            }


            SimpleAdapter simpleAdapterData;
            simpleAdapterData = new SimpleAdapter(MainActivity.this, MyArrList, R.layout.activity_column,
                    new String[] {"id", "title"}, new int[] {R.id.articleID, R.id.articleTitle});
            listViewMovies.setAdapter(simpleAdapterData);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

ภาพรวมของ Source code จะเป็นดังนี้ครับ

package com.daydev.webservices;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.StrictMode;
import android.annotation.SuppressLint;
import android.util.Log;
import android.widget.ListView;
import android.widget.SimpleAdapter;


public class MainActivity extends ActionBarActivity {
    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

        final ListView listViewMovies = (ListView)findViewById(R.id.listView1);
        String url = "http://lovedesigner.net/feed/json";

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        try {
            JSONArray data = new JSONArray(getJSON(url,params));

            final ArrayList<HashMap<String, String>> MyArrList = new ArrayList<HashMap<String, String>>();
            HashMap<String, String> map;

            for(int i = 0; i < data.length(); i++){
                JSONObject c = data.getJSONObject(i);

                map = new HashMap<String, String>();
                map.put("id", c.getString("id"));
                map.put("title", c.getString("title"));
                MyArrList.add(map);

            }


            SimpleAdapter simpleAdapterData;
            simpleAdapterData = new SimpleAdapter(MainActivity.this, MyArrList, R.layout.activity_column,
                    new String[] {"id", "title"}, new int[] {R.id.articleID, R.id.articleTitle});
            listViewMovies.setAdapter(simpleAdapterData);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public String getJSON(String url,List<NameValuePair> params) {
        StringBuilder str = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        try {
            httpPost.setEntity(new UrlEncodedFormEntity(params));
            HttpResponse response = client.execute(httpPost);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader_buffer = new BufferedReader
                (new InputStreamReader(content));

                String line;
                while ((line = reader_buffer.readLine()) != null) {
                    str.append(line);
                }
            } else {
                Log.e("Log", "Failed to download file..");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str.toString();
    }




    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

ทดสอบรันตัวโปรเจ็คของเราหน่อยดีกว่า

Screen Shot 2558-03-29 at 10.29.54 PM

เรียบร้อย เราสามารถใช้ JSON array ร่วมกับ Intent Activity ให้ส่งค่าเมื่อกด ListView ได้ต่อไปนะครับ ลองทดสอบทำดูครับ

บทเรียน Web Services ก็คงจบแค่นี้

Asst. Prof. Banyapon Poolsawas

อาจารย์ประจำสาขาวิชาการออกแบบเชิงโต้ตอบ และการพัฒนาเกม วิทยาลัยครีเอทีฟดีไซน์ & เอ็นเตอร์เทนเมนต์เทคโนโลยี มหาวิทยาลัยธุรกิจบัณฑิตย์ ผู้ก่อตั้ง บริษัท Daydev Co., Ltd, (เดย์เดฟ จำกัด)

Related Articles

Back to top button

Adblock Detected

เราตรวจพบว่าคุณใช้ Adblock บนบราวเซอร์ของคุณ,กรุณาปิดระบบ Adblock ก่อนเข้าอ่าน Content ของเรานะครับ, ถือว่าช่วยเหลือกัน