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 :