قالب و افزونه وردپرس

آموزش JSON Parsing در اندروید

منتشرشده توسط حامد قنبری در تاریخ

json به دلیل ساختار ساده و قابل فهمی که دارد می توان بعنوان جایگزینی خوبی برای xml برای ارتباط و داده پردازی با سرور باشد. از این رو در این جلسه آموزشی قصد داریم به آموزش کامل این موضوع بپردازیم. فلذا یادگیری این موضوع می تواند دست شما را برای نوشتن برنامه های پویا که نیازمند بروزرسانی مداوم اطلاعات است باز کند. قبل از شروع آموزش بهتر است در خصوص ساختار jsonتوضیحاتی داشته باشیم.

منبع :http://www.androidhive.info/2012/01/android-json-parsing-tutorial

به طور کلی گره JSON با قلاب و یا با یک پرانتز شروع خواهد شد. از این رو بین  بین [و { تفاوت آشکاری وجود دارد ، براکت ([) نشان دهنده شروع گره JSONArray می باشد در حالی کمانک ({) نشان دهنده JSONObject. بنابراین به منظور دسترسی به این گره ها  باید روش های متفاوتی را بکارببریم،

اگر گره JSON  با [  شروع می شود،  ما باید از روش  () getJSONArrayاستفاده کنیم. همانطور اگر  گره با { شروع می شود باید از روش  () getJSONObjectاستفاده کنید.

مثالی که  در زیر از  JSON آورده می شود نمونه بسیار خوبی برای آموزش ما از کاربرد json در اندروید خواهد بود . همانطور که بیان گردید ساختار  JSON بسیار ساده و گویاست است از این رو نیازی به توضیحات بیشتر در این پست نیست.   مثال ارائه شده به ما لیستی از تماس هایی که در آن هر گره شامل اطلاعات تماس مانند شماره نام، ایمیل، آدرس، جنس و تلفن می باشد ارائه می دهد که با توجه آن گره ها می توان اطلاعات بیشتری نیز بدان افزود.

قرار است که در این مثال اطلاعات json  را با ستفاده از  HTTP از آدرس اینترنتی مشخصی دریافت کنیم، افزون بر کلاس اصلی پروژه یعنی MainActivity  ، کلاس دیگری بانام HttpHandler در پروژه وجود دارد که اطلاعات را از url   تعیین شده  گرفته و  آن را به نوع string تبدیل می کند.   از این رو در کلاس اصلی  با اضافه کردن  asyncTask و با استفاده از  متد GetContacts  از طریق کلاس HttpHandlerبا  HTTP مورد نظر تماس پیدا کرده و  اطلاعات را به داخل اپلیکیشن فراخوانی(در کلاس HttpHandler )و در نهایت آنها را در طی مکانیزمی (Asynctask )  در لیست ویو نشان خواهیم داد  . مکانیزم اصلی Asynctask در کلاس اصلی به شرح زیر می باشد.

در متد ()onPreExecute کادر Progress bar قبل از دریافت پاسخ HTTP نشان داده شده خواهد شد.

در متد() onInBackground   اطلاعات از آدرس مشخص شده دریافت و تجزیه می شود، تا آماده استفاده آن در ویوها شود .

در روش onPostExecute () کادر پیشرفت محو شده و داده های گرفته شده بصورت لیست آرایه ای در نمای لیست ویو با استفاده از یک آداپتور نمایش داده خواهد شد.
همچنین توجه داشته باشید بسته به نوع گره ها از روش های  ()getJSONArray و getJSONObject ()در جای مناسب خود استفاده کنید.

فرمت و کد اصلی json  که آن را در سرور خود در قالب فایل php ایجاد می کنیم به شرح زیر می باشد. . البته شایان ذکر است که فایل php آن در سرور نویسنده سایت وجود دارد و در صورت نداشتن سرور می توانید از آدرس همان url سرور سایت بادر آدرس http://psrd.ir/fixurl/json.php استفاده کنید.

{
"contacts": [
    
    {
            "id": "1",
            "name": "hamedghanbari",
            "email": "hamedghanbari908@gmail.com",
            "address": "iran- maraghe",
            "gender" : "male",
            "phone": {
                "mobile": "+91 0000000000",
                "home": "00 000000",
                "office": "00 000000"
            }
    },
    {
            "id": "2",
            "name": "user",
            "email": "user@gmail.com",
            "address": "xx-xx-xxxx,x - street, x - country",
            "gender" : "male , female",
            "phone": {
                "mobile": "+91 0000000000",
                "home": "00 000000",
                "office": "00 000000"
            }
    }
]

}

اگر در داخل برنامه اکلیپس یا اندروید استودیو قرار دارید پروژه جدیدی را  ایجاد کنید

   اکلیپس :File ⇒ New Android ⇒ Application Project

اندروید استودیو :File ⇒ New  ⇒ New Project

اما اگر هنوز برنامه خود را باز نکرده اید یکی از برنامه های فوق را باز نموده و بعد از تعیین مشخصات(نامگذاری) ، تعیین حداقل sdk  و نوع اکتیویتی (blank  یا Empty) ، نام اکتیویتی ابتدایی و اصلی خود  را همان MainActivity قرار دهید. بعد از لود کامل برنامه ، در مسیر res ⇒layout لایه متناظر اکتیوتی اصلی یعنی activity_main را پیدا نمود و کدهای مندرج و پیش فرض آن را پاک کرده و کدهای xml  زیر را به آن اضافه کنید:

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context="info.androidhive.jsonparsing.MainActivity">

    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>

 

بعد از افزودن کدهای xml لایوت اصلی، که شامل یک لیست ویو است،به منظور افزودن آیتم های اصلی آن به لیست ویو، که قرار است اطلاعات دریافت شده در آن پردازش و  نمایش داده شود، لایوت xmlجدیدی را در قسمت  value ایجاد کرده و نام آن را list_item می گذاریم. طریقه ایجاد لایوت جدید نیز به این ترتیب می باشد . بر روی value  راست کلیک می کنیم از منوی ظاهر شده ، گزینه new  و زیر منوی آن Xml  و در نهایت گزینه Layou Xml File  را انتخاب می کنیم در پنچره ظاهر شده نام list_item  به آن می نهیم و دکمه ok  را می زنیم.

بعد از اضافه شدن لایوت جدید کدهای آن را به شرح زیر می نویسیم :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="@dimen/activity_horizontal_margin">

    <TextView
        android:id="@+id/name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="2dip"
        android:paddingTop="6dip"
        android:textColor="@color/colorPrimaryDark"
        android:textSize="16sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/email"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="2dip"
        android:textColor="@color/colorAccent" />

    <TextView
        android:id="@+id/mobile"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#5d5d5d"
        android:textStyle="bold" />
</LinearLayout>

 

 

حال نوبت نوشتن کدهای اصلی کلاس MainActivity می شود، که کدهای آن به شرح زیر می باشد.

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity {

    private String TAG = MainActivity.class.getSimpleName();

    private ProgressDialog pDialog;
    private ListView lv;

    // URL to get contacts JSON
    private static String url = "http://psrd.ir/fixurl/json.php";

    ArrayList<HashMap<String, String>> contactList;

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

        contactList = new ArrayList<>();

        lv = (ListView) findViewById(R.id.listview);

        new GetContacts().execute();
    }

    /**
     * Async task class to get json by making HTTP call
     */
    private class GetContacts extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Showing progress dialog
            pDialog = new ProgressDialog(MainActivity.this);
            pDialog.setMessage("Please wait...");
            pDialog.setCancelable(false);
            pDialog.show();

        }

        @Override
        protected Void doInBackground(Void... arg0) {
            HttpHandler sh = new HttpHandler();

            // Making a request to url and getting response
            String jsonStr = sh.makeServiceCall(url);

            Log.e(TAG, "Response from url: " + jsonStr);

            if (jsonStr != null) {
                try {
                    JSONObject jsonObj = new JSONObject(jsonStr);

                    // Getting JSON Array node
                    JSONArray contacts = jsonObj.getJSONArray("contacts");

                    // looping through All Contacts
                    for (int i = 0; i < contacts.length(); i++) {
                        JSONObject c = contacts.getJSONObject(i);

                        String id = c.getString("id");
                        String name = c.getString("name");
                        String email = c.getString("email");
                        String address = c.getString("address");
                        String gender = c.getString("gender");

                        // Phone node is JSON Object
                        JSONObject phone = c.getJSONObject("phone");
                        String mobile = phone.getString("mobile");
                        String home = phone.getString("home");
                        String office = phone.getString("office");

                        // tmp hash map for single contact
                        HashMap<String, String> contact = new HashMap<>();

                        // adding each child node to HashMap key => value
                        contact.put("id", id);
                        contact.put("name", name);
                        contact.put("email", email);
                        contact.put("mobile", mobile);

                        // adding contact to contact list
                        contactList.add(contact);
                    }
                } catch (final JSONException e) {
                    Log.e(TAG, "Json parsing error: " + e.getMessage());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),
                                    "Json parsing error: " + e.getMessage(),
                                    Toast.LENGTH_LONG)
                                    .show();
                        }
                    });

                }
            } else {
                Log.e(TAG, "Couldn't get json from server.");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),
          "Couldn't get json from server. Check LogCat for possible errors!",
                                Toast.LENGTH_LONG)
                                .show();
                    }
                });

            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // Dismiss the progress dialog
            if (pDialog.isShowing())
                pDialog.dismiss();
            /**
             * Updating parsed JSON data into ListView
             * */
            ListAdapter adapter = new SimpleAdapter(
                    MainActivity.this, contactList,
                    R.layout.list_item, new String[]{"name", "email",
                    "mobile"}, new int[]{R.id.name,
                    R.id.email, R.id.mobile});

            lv.setAdapter(adapter);
        }

    }
}

 

بعد از افزودن کدهای زیر به کلاس اصلی پروژه یعنی MainActivity کلاس جدیدی را ایجاد می کنیم . بدین منظور  بر روی پکیج پروژه راست کلیک کرده و از منوی new  گزینه class  را انتخاب می کنیم و نام آن راHttpHandler می گذاریم . و کدهای زیر به آن می افزاییم.

import android.util.Log;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;


public class HttpHandler {

    private static final String TAG = HttpHandler.class.getSimpleName();

    public HttpHandler() {
    }

    public String makeServiceCall(String reqUrl) {
        String response = null;
        try {
            URL url = new URL(reqUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            // read the response
            InputStream in = new BufferedInputStream(conn.getInputStream());
            response = convertStreamToString(in);
        } catch (MalformedURLException e) {
            Log.e(TAG, "MalformedURLException: " + e.getMessage());
        } catch (ProtocolException e) {
            Log.e(TAG, "ProtocolException: " + e.getMessage());
        } catch (IOException e) {
            Log.e(TAG, "IOException: " + e.getMessage());
        } catch (Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
        return response;
    }

    private String convertStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line).append('\n');
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}

 

 

 ودر نهایت فایل AndroidManifest.xml  که مربوط بهpremission یا همان مجوزهاست را باز نموده و مجوز زیر را بدین صورت به آن می افزاییم(دقت کنید که نام پکیج خود را در قسمت قرمز رنگ  که نام پکیج پروژه بنده است لحاظ فرمایید).

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.site.psrd.jsonparser">
<uses-permission android:name="android.permission.INTERNET">
</uses-permission>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

حال پروژه را اجرا کرده و از آن در آموزش هر چه بیشتر خود استفاده کنید. اگر مشکلی در اجرای کدها وجود دارد یا سوال مشخصی از نویسنده سایت دارید سوالات خود را در قسمت دیدگاه ها بیان کنید. موفق و موید باشید

کپی برداری از محتوای سایت psrd بدون ذکر منبع ممنوع بوده و پیگرد قانونی دارد. (تنها استفاده شخصی کاربران ، مجاز است) (کپی برداری توسط سایر وب سایت ها  غیرقانونی بوده و در صورت رویت به ستاد سازماندهی اطلاع داده خواهد شد.

 http://www.androidhive.info/2012/01/android-json-parsing-tutorial/ منبع اصلی مثال این مقاله