How to call API in android and retrieving data from a web server?

Asked 02-Apr-2018
Viewed 749 times

1

How to call API in android and retrieving data from a web server?


1 Answer


0

There are many ways to call API in our Android APP. Here we discuss how to use a web API from within our Android APP, to fetch data from the server. 

There are two major methods for fetching/retrieving data from web server, first is XML based & the second is JSON based. XML stands for ‘eXtensible Markup Language’. It is a replacement of HTML and designed to store and transport data. XML tags are not predefined. You must define your own tags. For example-

<university>

<student>
<name>James Gosling</name>
<age>20</age>
<occupation>Software Developer</occupation>
</student>
</university>

And the second way is JSON, JSON stands for JavaScript Object Notation. It is a lightweight data-interchange format and also exchanging the data on the web. It supports data structures like object and array. So it is easy to write and read data from JSON. For Example-

{“student”:[

 {“name”:”James Gosling”,”age”:20,”occupation”:”Software Developer” },
         {“name”:”Rasmus Ledrof”,”age”:21,”occupation”:”Programmer” }
]}

In this post, we have selected JSON format to retrieve data from a web server. 

First things are that you have to find a web API from which to fetch data. We have selected ‘http://maxapi.mindstick.com/api/question/gettags’ API. This is an excellent and powerful API from which we are retrieving data. The return information can be JSON format. Like most API’s you have to need an API key, which must have specified with every API query.

The Sample JSON is: 

Here is the sample of JSON that we are going to use.

{ 

   "IsSuccess":true,
   "Data":[
      {
         "Name":"current affair",
         "TotalPost":288,
         "UrlSlug":"current-affair",
         "Id":29349,
         "IsFavorite":false,
         "Rank":0
      },
      {
         "Name":"general knowledge",
         "TotalPost":260,
         "UrlSlug":"general-knowledge",
         "Id":29550,
         "IsFavorite":false,
         "Rank":0
      },
……………………………….
……………………………….
………………………………
 ],
   "Message":"",
   "TotalRecords":9958
}

Creating New Project:

So let’s start by creating a new android project. We’ll build a simple app which fetches the JSON data from URL, parses it and displays the Name & Total Post in a RecyclerView and also adding the pagination.

1. Create a new project in Android Studio from File ? New Project and fill out the required details.

2. As we are fetching the JSON by making HTTP calls, we need to add INTERNET permission in AndroidManifest.XML file. Open AndroidManifest.xml and add the following permission above the application tag. 

<uses-permission android:name="android.permission.INTERNET" /> 

3. Add Gradle dependencies which are required 

dependencies {
    …………………………..
    ………………………….
    compile 'com.android.support:cardview-v7:26.1.0'
    compile 'com.android.support:recyclerview-v7:26.1.0'
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.2.0'
    compile 'com.google.code.gson:gson:2.4'
    compile 'de.hdodenhof:circleimageview:1.2.1'
}

RecyclerView Classes:

RecyclerView is a more powerful, advanced & flexible version of ListView. Hence a RecyclerView is more customizable when compared to ListView and gives greater control to the users.

4. First, we create a required XML File.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:background="#F8F8FF"
    tools:context="com.example.msclient009.apicalling.MainActivity">
  <FrameLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical" />
    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="gone"
        />
  </FrameLayout>
</LinearLayout>

CardView :

Android CardView is a  UI component that shows information inside cards. This component is generally used to show Name & Total Post.

list_view_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:background="#b7b2b2"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="2dip">
    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_margin="2dp">
        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="10dp"
            android:text=""
            android:textSize="20dp"
            android:textStyle="bold" />
        <TextView
            android:id="@+id/textView2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:text=""
            android:layout_marginRight="20dp"
            android:layout_marginTop="10dp"
            android:textSize="20dp"
            android:textStyle="bold" />
    </android.support.v7.widget.CardView>
</RelativeLayout>

5. Create a different type of class which is used in our project.

 ApiBase.java(Contain setter & getter methods of Message, isSuccess & TotalRecords)

package com.example.msclient009.apicalling;
public abstract class ApiBase {
    public String getMessage() {
        return Message;
    }
    public void setMessage(String message) {
        Message = message;
    }
    public String Message;
    public Boolean getSuccess() {
        return IsSuccess;
    }
    public void setSuccess(Boolean success) {
        IsSuccess = success;
    }
    public Boolean IsSuccess;
    public long getTotalRecords() {
        return TotalRecords;
    }
    public void setTotalRecords(long totalRecords) {
        TotalRecords = totalRecords;
    }
    public long TotalRecords;
}

 Tag.java(Contain getter & setter methods of Name & TotalPost)

package com.example.msclient009.apicalling;
public class Tag {
    public long getTotalPost() {
        return TotalPost;
    }
    public void setTotalPost(long totalPost) {
        TotalPost = totalPost;
    }
    public long TotalPost;
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public String Name;
}

 ApiResponse.java (Contain setter & getter methods of Data)

package com.example.msclient009.apicalling;
import java.util.ArrayList;
public class ApiResponse <T> extends ApiBase {
    public ArrayList<T> getList() {
        return Data;
    }
    public void setList(ArrayList<T> list) {
        this.Data = list;
    }
    ArrayList<T> Data = new ArrayList<T>();
}

Retrofit :

Retrofit is a REST Client Library(Helper Library) used to create an HTTP request and also process the HTTP response from a REST API

CallAPI.java

package com.example.msclient009.apicalling;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface CallAPI {
    String BASE_URL = "http://maxapi.mindstick.com/api/question/";
    @GET("gettags")
    Call<ApiResponse<Tag>> getData(@Query("page") int page);
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(CallAPI.BASE_URL)
  //Here we are using the GsonConverterFactory to directly convert json data to object
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    CallAPI api = retrofit.create(CallAPI.class);
    }

MainActivity.java

package com.example.msclient009.apicalling;
import android.os.Parcelable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.util.ArrayList;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
    LinearLayoutManager layoutManager;
    RecyclerView recyclerView;
    private Parcelable recyclerViewState;
    boolean isLoading = false;
    int mPageIndex = 1;
    ProgressBar progressBar;
    MyAdapter myAdapter;
    ArrayList<Tag> arrayList=new ArrayList<Tag>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        getData(1);
    }
    private void getData(final int page) {
        progressBar.setVisibility(View.VISIBLE);
        isLoading=true;
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(CallAPI.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                 .build();
        CallAPI api = retrofit.create(CallAPI.class);
        Call<ApiResponse<Tag>> call = api.getData(page);
        call.enqueue(new Callback<ApiResponse<Tag>>() {
            @Override
            public void onResponse(Call<ApiResponse<Tag>> call, Response<ApiResponse<Tag>> response) {
                layoutManager = new LinearLayoutManager(getApplicationContext());
                recyclerView.setLayoutManager(layoutManager);
                ApiResponse<Tag> dataList = response.body();
                if(arrayList.size()<=0) {
                    myAdapter = new MyAdapter(dataList.getList());
                    arrayList = dataList.getList();
                }
                else
                {
                    myAdapter.notifyDataSetChanged();
                    arrayList.addAll(dataList.getList());
                }
                recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState); // Restore state
                recyclerView.setAdapter(myAdapter);
                progressBar.setVisibility(View.GONE);
                isLoading=false;
            }
            @Override
            public void onFailure(Call<ApiResponse<Tag>> call, Throwable t) {
                Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
/// Add Pagination
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                int lastvisibleitemposition = layoutManager.findLastVisibleItemPosition();
                if (lastvisibleitemposition == myAdapter.getItemCount() - 1 && !isLoading) {
                   // Refreshing data in RecyclerView and keeping its scroll position
                    recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();
                    getData(mPageIndex++);
                }
            }
        });
    }
}

MyAdapter.java

package com.example.msclient009.apicalling;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
        private List<Tag> values;
        private boolean isLoadingAdded = false;
        public class ViewHolder extends RecyclerView.ViewHolder {
        public TextView txtName;
        public TextView txtTotalPost;
        public View layout;
        public ViewHolder(View v) {
            super(v);
            layout = v;
            txtName = (TextView) v.findViewById(R.id.textView1);
            txtTotalPost = (TextView) v.findViewById(R.id.textView2);
        }
    }
    public void add(int position, Tag item) {
        values.add(position, item);
        notifyItemInserted(position);
    }
    public void remove(int position) {
        values.remove(position);
        notifyItemRemoved(position);
    }
    public MyAdapter(List<Tag> myDataset) {
        values = myDataset;
    }
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View v = inflater.inflate(R.layout.list_view_item, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }
    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        final Tag tag = values.get(position);
        holder.txtName.setText(tag.getName());
        holder.txtName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //remove(position);
            }
        });
        holder.txtTotalPost.setText(String.valueOf(tag.getTotalPost()));
    }
   @Override
    public int getItemCount() {
        return values.size();
    }
}

Output :

How to call API in android and retrieving data from a web server?