Android

Call api using Volley library Demo

http://askfortricks.com/2017/04/call-api-using-volley-library-demo/

Call rest API using Volley in Android

The very basic requirement in developing the Android application is “Api Integration” and fetch the details. For calling the Api we need the android networking library to interact with the web services and get the response from Api.

One such library is Volley which is developed by Google to handle Api calls.

Volley is an HTTP library that makes networking for Android apps easier and most importantly, faster. Volley is available on GitHub.

To know more about Volley, go here.

Our Post is divided into five parts, we will call https://www.themoviedb.org/

Its a collection of apis , for our demo we are fetching the list of popular movies from tmdb and display in recyclerview.

Pre Requisites:

We need to sign up and get the api_key before we can call any Api.

Dependencies

We  need to add below dependencies in app->build.gradle

dependencies {
    //recyclerview to show list
    implementation 'com.android.support:recyclerview-v7:27.1.1'
  
    //Gson
    implementation 'com.google.code.gson:gson:2.8.2'

    //Volley
    implementation 'com.android.volley:volley:1.1.0'
}

 

Structure for Volley Api request

WebApiRequest.java class is a common class to call APIs. We just have to create an instance of the class and call its appropriate constructor to initialize our Volley api call.

For future enhancement, we have added different parameters if we need to call the APIs with custom headers and parameters.


package com.askfortrciks.volleywithgsondemo.volley;
import com.android.volley.AuthFailureError;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.StringRequest;
import java.util.HashMap;
import java.util.Map;
public class WebApiRequest extends StringRequest {
private Map<String, String> headers = new HashMap<String, String>();
private Map<String, String> params = new HashMap<String, String>();
public WebApiRequest(int method, String url, Listener<String> listener,
ErrorListener errorListener, String token) {
super(method, url, listener, errorListener);
if (token != null) {
this.headers.put("Cookie", token);
}
}
public WebApiRequest(int method, String url,
Listener<String> listener, ErrorListener errorListener) {
super(method, url, listener, errorListener);
}
public WebApiRequest(int method, String url, Listener<String> listener, ErrorListener errorListener,
String token, Map<String, String> params) {
super(method, url, listener, errorListener);
if (token != null && params != null) {
this.headers.put("Cookie", token);
this.params = params;
}
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers;
}
/**
* To add headers in any api request in the form of
* key and value
* @param title
* @param content
*/
public void setHeader(String title, String content) {
headers.put(title, content);
}
/**
* To add parameters in the api request
* @return
* @throws AuthFailureError
*/
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
public void setParam(String title, String content) {
params.put(title, content);
}
}


public class WebServicesConstant {
//Main Host Url to access apis
public static final String BASE_URL_APPLICATION="https://api.themoviedb.org/3/";
//Image urls
public static final String BASE_URL_IMAGE_ORIGINAL="https://image.tmdb.org/t/p/original";
public static final String BASE_URL_IMAGE_W_500="https://image.tmdb.org/t/p/w500";
//api key (Its my personal) you have to crate your own to avoid suspension of your account
public static final String API_KEY="23fc7389372548c592b1f08cb8a0dffe";
//api connections
public static final String MOVIE="movie/";
public static final String TOP_RATED="top_rated";
}


package com.askfortrciks.volleywithgsondemo.volley;
import com.android.volley.AuthFailureError;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.StringRequest;
import java.util.HashMap;
import java.util.Map;
public class WebApiRequest extends StringRequest {
private Map<String, String> headers = new HashMap<String, String>();
private Map<String, String> params = new HashMap<String, String>();
public WebApiRequest(int method, String url, Listener<String> listener,
ErrorListener errorListener, String token) {
super(method, url, listener, errorListener);
if (token != null) {
this.headers.put("Cookie", token);
}
}
public WebApiRequest(int method, String url,
Listener<String> listener, ErrorListener errorListener) {
super(method, url, listener, errorListener);
}
public WebApiRequest(int method, String url, Listener<String> listener, ErrorListener errorListener,
String token, Map<String, String> params) {
super(method, url, listener, errorListener);
if (token != null && params != null) {
this.headers.put("Cookie", token);
this.params = params;
}
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers;
}
/**
* To add headers in any api request in the form of
* key and value
* @param title
* @param content
*/
public void setHeader(String title, String content) {
headers.put(title, content);
}
/**
* To add parameters in the api request
* @return
* @throws AuthFailureError
*/
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
public void setParam(String title, String content) {
params.put(title, content);
}
}


public class WebServicesConstant {
//Main Host Url to access apis
public static final String BASE_URL_APPLICATION="https://api.themoviedb.org/3/";
//Image urls
public static final String BASE_URL_IMAGE_ORIGINAL="https://image.tmdb.org/t/p/original";
public static final String BASE_URL_IMAGE_W_500="https://image.tmdb.org/t/p/w500";
//api key (Its my personal) you have to crate your own to avoid suspension of your account
public static final String API_KEY="23fc7389372548c592b1f08cb8a0dffe";
//api connections
public static final String MOVIE="movie/";
public static final String TOP_RATED="top_rated";
}

Top 10 free Android libraries for app development in android studio

Recyclerview to display List

Here we will call TOP_RATED  movie API in the call method mentioned in the MovieListingActivity.java to fetch the results.

The most important method is ReqSuccessListener which will handle the callback if API returns the results.

ReqErrorListener method will handle any server error if any in the response. If the server returned unexpected response then this method will handle it.


/**
* Success listener to handle the movie listing
* process after api returns the movie list
*
* @return
*/
private Response.Listener<String> ReqSuccessListener() {
return new Response.Listener<String>() {
public void onResponse(String response) {
Log.e("movie list_response", response);
try {
hideProgress();
pageNumber++;
MovieList movieListModel = (MovieList) Utils.jsonToPojo(response, MovieList.class);
if (movieListModel.getResults() != null &&
movieListModel.getResults().size() > 0) {
moviesRecyclerAdapter.addMovies(movieListModel.getResults());
} else {
Log.e(TAG, "list empty==");
}
} catch (Exception e) {
Log.e(TAG,"Exception=="+e.getLocalizedMessage());
}
}
};
}
/**
* To Handle the error
*
* @return
*/
private Response.ErrorListener ReqErrorListener() {
return new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
Log.e("volley error", "volley error");
Toast.makeText(MovieListingActivity.this, "" +
"Server Error..Please try again after sometime", Toast.LENGTH_SHORT).show();
}
};
}

 


<?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:id="@+id/rlMoviesList"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvMoviesList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>


package com.askfortrciks.volleywithgsondemo.activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.Volley;
import com.askfortrciks.volleywithgsondemo.R;
import com.askfortrciks.volleywithgsondemo.adapter.MoviesRecyclerAdapter;
import com.askfortrciks.volleywithgsondemo.model.MovieList;
import com.askfortrciks.volleywithgsondemo.utils.Utils;
import com.askfortrciks.volleywithgsondemo.volley.WebApiRequest;
import static com.askfortrciks.volleywithgsondemo.constant.WebServicesConstant.API_KEY;
import static com.askfortrciks.volleywithgsondemo.constant.WebServicesConstant.BASE_URL_APPLICATION;
import static com.askfortrciks.volleywithgsondemo.constant.WebServicesConstant.MOVIE;
import static com.askfortrciks.volleywithgsondemo.constant.WebServicesConstant.TOP_RATED;
public class MovieListingActivity extends AppCompatActivity {
public static final String TAG = "MovieListingActivity";
private RelativeLayout rlMoviesList;
private RecyclerView rvMoviesList;
private LinearLayoutManager linearLayoutManager;
private ProgressBar progressBar;
//For Load more functionality
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 2;
private int firstVisibleItem = 0;
private int visibleItemCount = 0;
private int totalItemCount = 0;
//current page number
private int pageNumber = 1;
//Adapter class for movie list recycler view
MoviesRecyclerAdapter moviesRecyclerAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movies_list);
initView();
callGetTopRatedMoviesApi();
}
private void initView() {
rlMoviesList = findViewById(R.id.rlMoviesList);
rvMoviesList = findViewById(R.id.rvMoviesList);
rvMoviesList.setHasFixedSize(true);
linearLayoutManager = new LinearLayoutManager(this);// new LinearLayoutManager()
rvMoviesList.setLayoutManager(linearLayoutManager);
rvMoviesList.clearOnScrollListeners(); //clear scrolllisteners
moviesRecyclerAdapter=new MoviesRecyclerAdapter(this);
rvMoviesList.setAdapter(moviesRecyclerAdapter);
/**
* For Adding Load more functionality
*
*/
rvMoviesList.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
visibleItemCount = recyclerView.getChildCount();
totalItemCount = linearLayoutManager.getItemCount();
firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount – visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
Log.i("InfiniteScrollListener", "End reached");
callGetTopRatedMoviesApi();
loading = true;
}
}
}
});
}
/**
* Display Progress bar
*/
private void showProgress() {
progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleLarge);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(100, 100);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
rlMoviesList.addView(progressBar, params);
progressBar.setVisibility(View.VISIBLE);
}
/**
* Hide Progress bar
*/
private void hideProgress() {
progressBar.setVisibility(View.GONE);
}
/**
* Call the api to fetch the TopRatedMovies list
*/
private void callGetTopRatedMoviesApi() {
/**
* Checking internet connection before api call.
* Very important always take care.
*/
if (!Utils.isNetworkAvailable(this)) {
Toast.makeText(this,
"No internet ..Please connect to internet and start app again",
Toast.LENGTH_SHORT).show();
return;
}
showProgress();
//constructing api url
String ws_url = BASE_URL_APPLICATION + MOVIE + TOP_RATED +
"?api_key=" + API_KEY + "&language=en-US&page=" + pageNumber;
//Using Volley to call api
WebApiRequest webApiRequest = new WebApiRequest(Request.Method.GET,
ws_url, ReqSuccessListener(), ReqErrorListener());
Volley.newRequestQueue(MovieListingActivity.this).add(webApiRequest);
}
/**
* Success listener to handle the movie listing
* process after api returns the movie list
*
* @return
*/
private Response.Listener<String> ReqSuccessListener() {
return new Response.Listener<String>() {
public void onResponse(String response) {
Log.e("movie list_response", response);
try {
hideProgress();
pageNumber++;
MovieList movieListModel = (MovieList) Utils.jsonToPojo(response, MovieList.class);
if (movieListModel.getResults() != null &&
movieListModel.getResults().size() > 0) {
moviesRecyclerAdapter.addMovies(movieListModel.getResults());
} else {
Log.e(TAG, "list empty==");
}
} catch (Exception e) {
Log.e(TAG,"Exception=="+e.getLocalizedMessage());
}
}
};
}
/**
* To Handle the error
*
* @return
*/
private Response.ErrorListener ReqErrorListener() {
return new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
Log.e("volley error", "volley error");
Toast.makeText(MovieListingActivity.this, "" +
"Server Error..Please try again after sometime", Toast.LENGTH_SHORT).show();
}
};
}
}

Calling Tmdb API


private void callGetTopRatedMoviesApi() {
/**
* Checking internet connection before api call.
* Very important always take care.
*/
if (!Utils.isNetworkAvailable(this)) {
Toast.makeText(this,
"No internet ..Please connect to internet and start app again",
Toast.LENGTH_SHORT).show();
return;
}
showProgress();
//constructing api url
String ws_url = BASE_URL_APPLICATION + MOVIE + TOP_RATED +
"?api_key=" + API_KEY + "&language=en-US&page=" + pageNumber;
//Using Volley to call api
WebApiRequest webApiRequest = new WebApiRequest(Request.Method.GET,
ws_url, ReqSuccessListener(), ReqErrorListener());
Volley.newRequestQueue(MovieListingActivity.this).add(webApiRequest);
}
/**
* Success listener to handle the movie listing
* process after api returns the movie list
*
* @return
*/
private Response.Listener<String> ReqSuccessListener() {
return new Response.Listener<String>() {
public void onResponse(String response) {
Log.e("movie list_response", response);
try {
hideProgress();
pageNumber++;
MovieList movieListModel = (MovieList) Utils.jsonToPojo(response, MovieList.class);
if (movieListModel.getResults() != null &&
movieListModel.getResults().size() > 0) {
moviesRecyclerAdapter.addMovies(movieListModel.getResults());
} else {
Log.e(TAG, "list empty==");
}
} catch (Exception e) {
Log.e(TAG,"Exception=="+e.getLocalizedMessage());
}
}
};
}
/**
* To Handle the error
*
* @return
*/
private Response.ErrorListener ReqErrorListener() {
return new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
Log.e("volley error", "volley error");
Toast.makeText(MovieListingActivity.this, "" +
"Server Error..Please try again after sometime", Toast.LENGTH_SHORT).show();
}
};
}

view raw

CallApi.java

hosted with ❤ by GitHub

Adding the load more or infinite scrollview to recyclerview.

We have attached a scroll listener as always we need to add endless scroll or infinite scroll to load the results. In web format, we call it paging based on the number of results. Say we need 20 results in one API call. And then again next 20 sequentially.

This can be used by you in any application or projects.


/**
* For Adding Load more functionality
*
*/
rvMoviesList.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
visibleItemCount = recyclerView.getChildCount();
totalItemCount = linearLayoutManager.getItemCount();
firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount – visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
Log.i("InfiniteScrollListener", "End reached");
callGetTopRatedMoviesApi();
loading = true;
}
}
}
});


/**
* For Adding Load more functionality
*
*/
rvMoviesList.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
visibleItemCount = recyclerView.getChildCount();
totalItemCount = linearLayoutManager.getItemCount();
firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount – visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
Log.i("InfiniteScrollListener", "End reached");
callGetTopRatedMoviesApi();
loading = true;
}
}
}
});

For Complete Demo of Volley using Gson find the source codes in below project.

https://github.com/askfortricks/VolleyWithGsonDemo

Feeling glad to receive your comment