arrow left
Back to Developer Education

    How To Consume Data From an API in Android

    How To Consume Data From an API in Android

    APIs allow applications to access a huge range of data. In numerous cases, developers usually connect their software to third party APIs. This move enables them to save a significant amount of time. In Android, tools such as Volley and Retrofit allow you to connect to APIs seamlessly. <!--more-->

    Introduction

    Android is among the most popular operating systems in the world. Statistics from Google show that more than a billion devices run Android. Therefore, the ability to utilize APIs in our applications helps us satisfy the needs of many users.

    One of the major factors that we should consider when using APIs is the number of requests. We should desist from making too many network operations. This is because it can increase battery drain and lead to poor user satisfaction. Also, API owners can bar applications that make too many requests.

    Goal

    This tutorial provides a guideline on how to make an API request based on the user's action. We will make a simple search app that sends a request to the OMDb movie API and receives data.

    Prerequisites

    To understand this tutorial, you must have a basic knowledge of Kotlin. Furthermore, you will need Android Studio installed on your computer.

    Step 1 - Getting started

    Launch Android Studio and create a new project with an empty activity, as shown below.

    New Project

    Give the project any name, and then click on the finish button. Kindly note that the creation of the project usually takes some considerable time. Therefore, you need to be patient.

    Step 2 - Installing dependencies

    The next step is to install volley and glide dependencies. We will use volley to handle network requests, while glide will help load images in the application.

    Add the following lines in the app level build.gradle file.

    Dependencies{
    implementation 'com.android.volley:volley:1.1.1'
    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
    }
    

    You then click on the Sync Now button to download and incorporate the above dependencies in the application.

    Step 3 - Reviewing the Movie API

    We will be sending and receiving data from the OMDb API for this tutorial. Before going further, it is essential to understand how to access the data, the site rules, and the data structure.

    Data access

    For us to access data, we need to create an account on the OMDb website. This process requires a valid email. You can sign up from here. Kindly note that this tutorial uses the free account option, which has a daily limit of 1,000 requests.

    After registration, an API key is sent to your email inbox.

    Site rules

    One needs to include an API key while making a request to the OMDb API. For instance, the correct link is shown below.

    val url = "http://www.omdbapi.com/?t=${input}&apikey=${your_key}"
    

    The input variable will allow us to search different movies in the OMDb API. The key is usually placed at the end of the url.

    Step 4 - Layout design

    The application will have a simple layout like the one shown below.

    App Layout

    We will use a LinearLayout to arrange different components on the screen. Note that the layout’s orientation is set to vertical. Here is the code for activity-main.xml.

    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView 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=".MainActivity">
    
      <LinearLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">
    
        <EditText
            android:id="@+id/userinput"
            android:layout_margin="10dp"
            android:padding="17dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
        <Button
            android:id="@+id/search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Search"
            android:backgroundTint="@color/colorAccent"/>
    
    
        <ImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
        <TextView
            android:id="@+id/name"
            android:layout_margin="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
        <TextView
            android:id="@+id/plot"
            android:layout_margin="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
    </LinearLayout>
    </ScrollView>
    

    In the above layout, we have assigned an ID to our components. We will use these unique values in the MainActivity.kt file.

    The EditText widget allows us to get the user’s input. When clicked, the search button will initiate a request to the OMDb API. The ImageView and TextViews will display the data returned from the server.

    Step 5 - Connecting to the API

    This tutorial shows how you to make simple API requests. Therefore, all our logic is in the MainActivity file rather than in a separate component such as a ViewModel. In case you want to learn more about the MVVM architecture in Android, you can read this article.

    We need to do the following things in the MainActivity.

    • Initiate a requestQueue.
    • Make an API request.
    • Parse data to UI components.

    A RequestQueue helps us manage HTTP requests. You can learn more about the RequestQueue from here.

    We initiate a requestQueue by adding the following lines immediately after setting a content view.

    setContentView(R.layout.activity_main)
    val appnetwork = BasicNetwork(HurlStack())
    val appcache = DiskBasedCache(cacheDir, 1024 * 1024) // 1MB cap
    requestQueue = RequestQueue(appcache, appnetwork).apply {
        start()
    }
    

    The appnetwork variable allows the application to use an HTTP client.

    The next step is to add a click listener to our search button. The user will make an API call by clicking this button.

    search.setOnClickListener {
        var input = userinput.text.toString()
        fetchData(input)
    }
    

    The input variable stores the user's search term. This value is then passed to the fetchData method as a parameter. Let’s create the fetchData method.

    fun fetchData( input: String){
        val url = "http://www.omdbapi.com/?t=${input}&apikey=cebd9b53"
        val jsonObjectRequest = JsonObjectRequest(Request.Method.GET, url, null,
            { response ->
             if(response.get("Response")=="False"){
                 name.text = "Incorrect detail"
             }else {
                 Glide.with(this).load(response.getString("Poster")).into(image)
                 plot.text = response.getString("Plot")
                 name.text = response.getString("Title")+"\n\n"+"Writer: "+response.getString("Writer")
             }
            },
            { error ->
                Log.d("vol",error.toString())
            }
        )
    
        requestQueue.add(jsonObjectRequest)
    }
    

    The fetchData function requires a string (user's input) as a parameter. This string is then joined to the url as =${input}. We are using a JsonObjectRequest because our application returns a single Movie object rather than a list. We use an if-else statement to handle different states in the jsonObjectRequest lambda function. If the request is successful, we extract the data and parse it to the components.

    Glide.with(this).load(response.getString("Poster")).into(image)
    plot.text = response.getString("Plot")
    name.text = response.getString("Title")+"\n\n"+"Writer: "+response.getString("Writer")
    

    The Glide library helps load the image to the ImageView.

    An error message is also logged in case the network request fails. This helps in the debugging process.

    { error ->
        Log.d("vol",error.toString())
    }
    

    Finally, the jsonObjectRequest is added to the requestQueue.

    requestQueue.add(jsonObjectRequest)
    

    Here is the code for the MainActivity.kt.

    import android.os.Bundle
    import android.util.Log
    import androidx.appcompat.app.AppCompatActivity
    import androidx.recyclerview.widget.DefaultItemAnimator
    import androidx.recyclerview.widget.LinearLayoutManager
    import androidx.recyclerview.widget.RecyclerView
    import com.android.volley.Request
    import com.android.volley.RequestQueue
    import com.android.volley.toolbox.BasicNetwork
    import com.android.volley.toolbox.DiskBasedCache
    import com.android.volley.toolbox.HurlStack
    import com.android.volley.toolbox.JsonObjectRequest
    import com.bumptech.glide.Glide
    import kotlinx.android.synthetic.main.activity_main.*
    
    
    class MainActivity : AppCompatActivity() {
        lateinit var requestQueue: RequestQueue
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            val appnetwork = BasicNetwork(HurlStack())
            val appcache = DiskBasedCache(cacheDir, 1024 * 1024) // 1MB cap
            requestQueue = RequestQueue(appcache, appnetwork).apply {
                start()
            }
    
    
            search.setOnClickListener {
                var input = userinput.text.toString()
                fetchData(input)
            }
    
    
        }
    
        fun fetchData( input: String){
            val url = "http://www.omdbapi.com/?t=${input}&apikey=cebd9b53"
            val jsonObjectRequest = JsonObjectRequest(Request.Method.GET, url, null,
                { response ->
                 if(response.get("Response")=="False"){
                     name.text = "Incorrect detail"
                 }else {
                     Glide.with(this).load(response.getString("Poster")).into(image)
                     plot.text = response.getString("Plot")
                     name.text = response.getString("Title")+"\n\n"+"Writer: "+response.getString("Writer")
                 }
                },
                { error ->
                    Log.d("vol",error.toString())
                }
            )
    
            requestQueue.add(jsonObjectRequest)
        }
    }
    

    Kindly note that before testing the application, we need to grant it access to the internet. We should also allow the application to use cleartext traffic. This step is essential, especially if the API source does not have an SSL certificate.

    To allow these permissions, open the manifest file. Add the following statement immediately after package="your-package-name">.

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

    In the same file, scroll to the application section and add android:usesCleartextTraffic="true".

    We can now compile and run the application on our phones.

    App Gif

    Conclusion

    From the above tutorial, we have learned:

    • How to review APIs.
    • How to modify urls.
    • How to make API requests.

    You can, therefore, use this knowledge to develop more complex applications.


    Peer Review Contributions by: Peter Kayere

    Published on: Feb 7, 2021
    Updated on: Jul 15, 2024
    CTA

    Start your journey with Cloudzilla

    With Cloudzilla, apps freely roam across a global cloud with unbeatable simplicity and cost efficiency