Calling an API on Android Studio

September 19, 2017
android api howto java

Introduction

In this post, I will explain how to call an API using Android Studio (Android app) as well as treating its return data. I’ll be focusing mostly on the technical part (like most of the posts I’ll publish here on my blog), however, and only for personal reasons, I will contextualize this scenario and tell you why I followed this solution, but it will be just a brief summary in case you want to know this little “adventure” of mine. If you are only interested in the technical solution please click here.

In one of my school projects¹, my team and I decided to create an Android application for the very first time. The project was basically a meal planner app where the user can create and manipulate recipes as well as organize his/her own weekly meal plan.

I’m printing here below a few screenshots to illustrate a little about the app. When these screenshots were taken the project was still in its initial state:

One of the requirements of the project was the use of an API to fetch food items inside USDA’s database (United States Department of Agriculture). I searched in a few technology forums trying to find some practical examples, but I didn’t have much success finding a satisfactory solution which matched with the scenario of this project. So I decided to look for any documentation on the Android website (developer’s section) and I found a relatively new solution (2013) using the Volley library. This is a good solution for low payloads HTTP requests, which are usually used to populate the UI, and this was the perfect solution I was looking for.

In the following chapters, I will explain in details how to make HTTP requests using Volley. So let’s go to the solution already!

If you’d like to check the project’s source code, please follow the GitHub link²

(¹) Langara College: Web and Mobile App Development - WMDD4980 Project 2

(²) The available source code of the project is only a demo of the app, for obvious reasons I won’t share the whole code of the app.

Contents

1. Know The API You Are Going to Use

Firstly, it is necessary to know the API you will use. In this case, it is the USDA’s database, you can find its documentation following this link.

Usually, an API requires an access key, so you will probably need to sign up on their website and justify the use of the API, but it should be something very simple.

It’s very important to know about the API’s inputs and outputs as well, so I enforce that checking its documentation is crucial for the correct use and avoiding possible crashes.

2. Hands On (coding)

2.1. Adding Volley & Internet Permission

To use Volley’s tools, we need to add its library first. The easiest way to do that is by adding the dependency inside the file build.gradle.

dependencies {
    ...
    compile 'com.android.volley:volley:1.0.0'
}

Next, it’s necessary to add internet permission to your app, so add the following code between the tag manifest, inside the file AndroidManifest.xml

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

2.2. Creating the Queue Object

Now we need to create the object which will manage the communication between the app and the API, so we create the RequestQueue object.

public class AddFoodItems extends AppCompatActivity {
    // creating que queue object
    private RequestQueue queue;
...

For our solution, we’ll make use of the Volley.newRequestQueue.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // initializing the queue object
        queue = Volley.newRequestQueue(this);
        ...
...

2.3. Creating The String Request

The StringRequest object represents the data to be sent (method and URL), as well as its treatment (logic) in case of success and error of the invoked API.

2.3.1. Setting The Success and Error Returns

In the case of this project, I decided to create a separate method that returns a StringRequest object, so that way I wasn’t “polluting” the event method a lot.

private StringRequest searchNameStringRequest(String nameSearch) {
    final String API = "&api_key=<<YOUR_API_KEY_HERE>>";
    final String NAME_SEARCH = "&q=";
    final String DATA_SOURCE = "&ds=Standard Reference";
    final String FOOD_GROUP = "&fg=";
    final String SORT = "&sort=r";
    final String MAX_ROWS = "&max=25";
    final String BEGINNING_ROW = "&offset=0";
    final String URL_PREFIX = "https://api.nal.usda.gov/ndb/search/?format=json";

    String url = URL_PREFIX + API + NAME_SEARCH + nameSearch + DATA_SOURCE + FOOD_GROUP + SORT + MAX_ROWS + BEGINNING_ROW;

    // 1st param => type of method (GET/PUT/POST/PATCH/etc)
    // 2nd param => complete url of the API
    // 3rd param => Response.Listener -> Success procedure
    // 4th param => Response.ErrorListener -> Error procedure
    return new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
                // 3rd param - method onResponse lays the code procedure of success return
                // SUCCESS
                @Override
                public void onResponse(String response) {
                    // try/catch block for returned JSON data
                    // see API's documentation for returned format
                    try {
                        JSONObject result = new JSONObject(response).getJSONObject("list");
                        int maxItems = result.getInt("end");
                        JSONArray resultList = result.getJSONArray("item");

                        ...

                    // catch for the JSON parsing error
                    } catch (JSONException e) {
                        Toast.makeText(AddFoodItems.this, e.getMessage(), Toast.LENGTH_LONG).show();
                    }
                } // public void onResponse(String response)
            }, // Response.Listener<String>()
            new Response.ErrorListener() {
                // 4th param - method onErrorResponse lays the code procedure of error return
                // ERROR
                @Override
                public void onErrorResponse(VolleyError error) {
                    // display a simple message on the screen
                    Toast.makeText(AddFoodItems.this, "Food source is not responding (USDA API)", Toast.LENGTH_LONG).show();
                }
            });
}

2.4. Calling The API

Now that we defined the rules and procedures to the API’s return, we just need to make the call of itself. The operation is as simple as adding the StringRequest to the queue.

// Click event of the button Search
public void btnSearchClickEventHandler(View view) {
    ...
    // cancelling all requests about this search if in queue
    queue.cancelAll(TAG_SEARCH_NAME);

    // first StringRequest: getting items searched
    StringRequest stringRequest = searchNameStringRequest(txtSearch.getText().toString());
    stringRequest.setTag(TAG_SEARCH_NAME);

    // executing the request (adding to queue)
    queue.add(stringRequest);
}

3. Conclusion

I found the usage of the Volley library very simple and easy to use. For a simple query like the example above, this solution performed at a good speed and it seems stable. If you need to make a simple request to retrieve light amounts of data, then this is probably a good way to call for the API you want.

You can also find some good explanations about the Volley library on YouTube here in this link.

4. Resources

[Android] Creating Custom Login Screen for AWS Mobile Hub

November 20, 2017
aws android howto login mobilehub

Creating and Hosting a Wordpress Site (Using AWS EC2 & RDS)

November 2, 2017
aws ec2 howto rds wordpress

Serving Dynamic Web Pages Using HapiJS

October 11, 2017
dynamic html hapijs howto nodejs