Android

Android JSON Parsing Tutorial

JSON parsing is a key component in android application development. We can parse JSON data using different third party libraries like loopj, retrofit and volley. In this tutorial we will learn how to parse data from url into android using loopj. We will develop a complete android json parsing example by using a movies json file. We will be following json parsing get method and show output data in a custom listview.

Eample JSON data URL

JSON data can be accessed in many ways like storing a json file in raw folder or access from url. In this tutorial we will be following android json parsing from url. We are placing a JSON file named movies.json in our website and access that buy a url to parse.

we can access JSON data file from this url: http://tutorialscache.com/movies.json

{
    "status":true,
    "total_records":10,
    "movies": [
        {
            "id":1,
            "name":"Captain America (2011)",
            "image":"http://tutorialscache.com/wp-content/uploads/2019/04/captain-america.jpeg",
            "ratting":5.0
        },
        {
            "id":2,
            "name":"Apocalypto (2006)",
            "image":"http://tutorialscache.com/wp-content/uploads/2019/04/apocalypto.png",
            "ratting":4.5
        },
        {
            "id":3,
            "name":"300 (2006)",
            "image":"http://tutorialscache.com/wp-content/uploads/2019/04/300.png",
            "ratting":4.5
        },{
            "id":4,
            "name":"Spider Man (2002)",
            "image":"http://tutorialscache.com/wp-content/uploads/2019/04/spiderman.jpg",
            "ratting":5.0
        }
    ]
}

1. Create new Android Studio Project

Create new android studio project and choose empty activity.

Screen Shot 2019-04-10 at 10.00.43 AM
Screen Shot 2019-04-10 at 10.00.53 AM
Screen Shot 2019-04-10 at 1.38.31 PM

2. strings.xml

We have added few strings to make use in the application.

<resources>
    <string name="app_name">Awesome Movies</string>
    <string name="network_error">Network not connected</string>
    <string name="retry">Retry</string> 
    <string name="no_status_false">Invalid Response</string>
    <string name="no_movies">No Movies Found</string>
</resources>

2.1 colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#d11617</color>
    <color name="colorPrimaryDark">#B31718</color>
    <color name="colorAccent">#B31718</color>
    <color name="white">#FFFFFF</color>
</resources>

3. GlobalClass.java

Create a new class GlobalClass and extend with Application. This class instance will help us to access BASE URL and also gives us application instance. It also has a function named isNetowrk() which will help us to check internet connectivity.

package com.tutorialscache.android_json_parsing;

import android.app.Application;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;


public class GlobalClass extends Application {
    public static final String BASE_URL = "http://www.tutorialscache.com/";

    private static GlobalClass singleton;

    @Override
    public void onCreate() {
        super.onCreate();
        singleton = this;
    }

    public static GlobalClass getInstance() {
        return singleton;
    }

    public static boolean isNetowrk() {
        boolean haveConnectedWifi = false;
        boolean haveConnectedMobile = false;
        ConnectivityManager cm = (ConnectivityManager)singleton.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo[] netInfo = cm.getAllNetworkInfo();
        for (NetworkInfo ni : netInfo) {
            if (ni.getTypeName().equalsIgnoreCase("WIFI"))
                if (ni.isConnected())
                    haveConnectedWifi = true;
            if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
                if (ni.isConnected())
                    haveConnectedMobile = true;
        }
        return haveConnectedWifi || haveConnectedMobile;
    }
}

To launch GlobalClass at start of the application add application name in name attribute in <application> of Android.Manifest.xml

    <application
                android:name=".GlobalClass"

4. AndroidManifest.xml INTERNET Permissions & NETWORK STATE

We need to add INTERNET & NETWORK STATE Permissions into AndroidManifest.xml file to allow movies.json file from url and to check whether our app is connected with internet or not . These permissions are necessary because we can’t access urls without internet permissions. After adding permissions our AndroidManifest.xml will look like this.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tutorialscache.android_json_parsing">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <application
        android:name=".GlobalClass"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

5. Third party libraries Loopj & Picasso.

We will use loopj to access data from url and Picasso to load images from url in build.gradle (Module: app)

    implementation 'com.loopj.android:android-async-http:1.4.9'
    implementation 'com.squareup.picasso:picasso:2.5.2'

build.gradle(Module:app) complete code

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.tutorialscache.android_json_parsing"
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    implementation 'com.loopj.android:android-async-http:1.4.9'
    implementation 'com.squareup.picasso:picasso:2.5.2'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

6. WebReq.java

Create a new Application name WebReq and following code. WebReq class used to send request on server. It has GET Method to return JSON data from given url.

package com.tutorialscache.android_json_parsing;


import android.content.Context;
import android.util.Log;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.ResponseHandlerInterface;

public class WebReq {

    public static AsyncHttpClient client;

    static{
        //create object of loopj client
        //443 will save you from ssl exception
        client = new AsyncHttpClient(true,80,443);
    }

    // you can create post methods as well similar way
    public static void get(Context context, String url, RequestParams params, ResponseHandlerInterface responseHandler) {
        client.get(context, getAbsoluteUrl(url), params, responseHandler);
    }


    //concatenation of base url and file name
    private static String getAbsoluteUrl(String relativeUrl) {
        Log.d("response URL: ",GlobalClass.getInstance().BASE_URL + relativeUrl+" ");
        return GlobalClass.getInstance().BASE_URL + relativeUrl;
    }
}

7. activity_main.xml

Add ListView code in activity_main.xml file.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.tutorialscache.android_json_parsing.MainActivity">

    <ListView
        android:id="@+id/listView"
        android:scrollbars="none"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>
    <ProgressBar
        android:id="@+id/pBr"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/retryTv"
        android:visibility="gone"
        android:textColor="@color/colorPrimary"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/pBr"
        android:text="@string/retry"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

8. Gradient Image

We need to add a gradient image to make our listview attractive. Download image and place in drawable folder.

9. custom_row.xml

Create a new layout file named custom_row.xml and add following code.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:padding="0.1dp">

    <ImageView
        android:id="@+id/movieImg"
        android:scaleType="fitXY"
        android:layout_width="match_parent"
        android:layout_height="200dp" />
    <ImageView
        android:src="@drawable/gradient"
        android:scaleType="fitXY"
        android:layout_width="match_parent"
        android:layout_height="200dp" />
    <TextView
        android:id="@+id/movieNameTv"
        android:text="300 (2006)"
        android:textSize="25dp"
        android:textColor="@color/white"
        android:layout_alignParentBottom="true"
        android:padding="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <RatingBar
        android:id="@+id/movieRating"
        style="?android:attr/ratingBarStyleSmall"
        android:numStars="5"
        android:rating="5"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:paddingBottom="10dp"
        android:layout_marginRight="5dp"
        android:stepSize="0.1"
        android:layout_marginBottom="10dp"
        android:isIndicator="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

10. MoviesModel.java

Create a new class named MoviesModel.java and add following code. If you want to learn ho to create model, getters and setters go back to Custom ListView tutorial.

package com.tutorialscache.android_json_parsing;


import android.util.Log;

public class MoviesModel {
    //variables
    int id;
    String name,image;

    public double getRatting() {
        return ratting;
    }

    public void setRatting(double ratting) {
        this.ratting = ratting;
    }

    double ratting;

    //constructor
    public MoviesModel(int id,String name,String image, double ratting){
        this.setId(id);
        this.setName(name);
        this.setImage(image);
        this.setRatting(ratting);
    }

    //getters and setters

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    @Override
    public String toString() {
        Log.d("response MODEL: ","ID: "+this.getId()+" Movie Name: "+this.getName()+" Ratting: "+this.getRatting()+" ");
        return super.toString();

    }
}

11. MoviesJSONAdapter.java

create a new file and name it MoviesJSONAdapter. We will extend this class with BaseAdapter and implement its methods.

package com.tutorialscache.android_json_parsing;


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

import java.util.ArrayList;

public class MoviesJSONAdapter extends BaseAdapter {
    MoviesModel moviesModel;
    ArrayList<MoviesModel> moviesJsonData;
    LayoutInflater layoutInflater;
    Context context;

    public MoviesJSONAdapter(Context context, ArrayList<MoviesModel> moviesJsonData) {
        this.context=context;
        this.moviesJsonData=moviesJsonData;
        layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return moviesJsonData.size();
    }

    @Override
    public Object getItem(int position) {
        return moviesJsonData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return moviesJsonData.get(position).getId();
    }

    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {
        View convertView = view;
        if (convertView==null){
            convertView = layoutInflater.inflate(R.layout.custom_row,null);
            TextView movieNameTv = convertView.findViewById(R.id.movieNameTv);
            ImageView movieImg = convertView.findViewById(R.id.movieImg);
            RatingBar ratingBar = convertView.findViewById(R.id.movieRating);

            moviesModel = moviesJsonData.get(position);
            movieNameTv.setText(moviesModel.getName());

            //Picasso load image
            Picasso.with(context).load(moviesModel.getImage()).into(movieImg);

            //set ratting
            ratingBar.setRating((float) moviesModel.getRatting());
        }
        return convertView;
    }
}

12. MainActivity.java

package com.tutorialscache.android_json_parsing;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.ResponseHandlerInterface;

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

import java.util.ArrayList;

import cz.msebera.android.httpclient.Header;

public class MainActivity extends AppCompatActivity {
    ListView listView;
    TextView retryTv;
    MoviesJSONAdapter moviesJSONAdapter;
    ArrayList<MoviesModel> moviesJsonData;
    ProgressBar progressBar;
    Context context;

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

        initialize();

        if (GlobalClass.isNetowrk()){
            requestData();
            retryTv.setVisibility(View.GONE);
            progressBar.setVisibility(View.VISIBLE);
        }else {
            Toast.makeText(context,getString(R.string.network_error),Toast.LENGTH_SHORT).show();
            retryTv.setVisibility(View.VISIBLE);
            progressBar.setVisibility(View.INVISIBLE);

        }
    }



    private void initialize() {
        listView = findViewById(R.id.listView);
        retryTv = findViewById(R.id.retryTv);
        progressBar = findViewById(R.id.pBr);
        moviesJsonData=new ArrayList<>();
        moviesJSONAdapter = new MoviesJSONAdapter(context,moviesJsonData);
        listView.setAdapter(moviesJSONAdapter);
    }


    private void requestData() {

        RequestParams requestParams = new RequestParams();
        WebReq.get(context,"movies.json",requestParams,new MainActivity.ResponseHandler());
    }


    public class ResponseHandler extends JsonHttpResponseHandler {

        @Override
        public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
            // response failure
            super.onFailure(statusCode, headers, responseString, throwable);
        }

        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
            super.onSuccess(statusCode, headers, response);
            //clear all previous data if any
            moviesJsonData.clear();

            Log.d("response ",response.toString());
            //check status of the response
            try {
                if (response.getBoolean("status")){
                    // get movies array from response object
                    JSONArray movies = response.getJSONArray("movies");

                    //check whether movies array is not empty
                    if (movies.length()>0){

                        //loop through movies array and add into moviesJsonData
                        for (int i = 0; i < movies.length(); i++) {
                            //get each movie object
                            JSONObject movie = movies.getJSONObject(i);

                            //get each movie Object Data

                            MoviesModel moviesModel = new MoviesModel(movie.getInt("id"),movie.getString("name"),movie.getString("image"),movie.getDouble("ratting"));
                            moviesModel.toString();

                            //add object to moviesJsonData array
                            moviesJsonData.add(moviesModel);
                        }

                        //Now notify adapter with new data
                        moviesJSONAdapter.notifyDataSetChanged();
                    }else{
                        Toast.makeText(context,getString(R.string.no_movies),Toast.LENGTH_SHORT).show();
                        retryTv.setVisibility(View.VISIBLE);
                    }

                }else{
                    Toast.makeText(context,getString(R.string.no_status_false),Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFinish() {
            //hide progress bar
            progressBar.setVisibility(View.GONE);
            super.onFinish();
        }
    }
}

final_app

Write A Comment

Tutorials Cache