How to Build Live Train Status App in Android?
Last Updated :
24 Apr, 2025
Imagine you are traveling via Indian railways which is one of the biggest rail networks in the world. You want to get real-time updates for the train on which you are traveling so that you can plan accordingly. In this article, we will take a look at How to build a live train status checker application in Android. We will be using a method of web scraping to build this application to check live train status. A sample video is given below to get an idea about what we are going to do in this article.
Step-by-Step Implementation
Step 1 : Create a new android studio project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language.
Step 2: Add the below dependency in your build.gradle file
Below is the dependency for JSOUP which we will be using to scrap the data for our application. For adding this dependency navigate to the app > Gradle Scripts > build.gradle(app) and add the below dependency in the dependencies section.
implementation ("org.jsoup:jsoup:1.11.2")
implementation ("com.squareup.okhttp3:okhttp:4.9.1")
After adding this dependency sync your project and now move toward the AndroidManifest.xml part.
Step 3: Adding permissions to the internet in the AndroidManifest.xml file
Navigate to the app > AndroidManifest.xml and add the below code to it.
XML
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Step 4: Working with the activity_main.xml file
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for activity_main.xml file.
XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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">
<!-- on the below line creating an edit text
for getting train number -->
<EditText
android:id="@+id/idEdtTrainNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:hint="Enter Train Number"
android:inputType="phone"
android:maxLength="5"
android:textColor="@color/black"
android:textSize="18sp" />
<!-- on the below line creating a text view for
selecting the date for which we want train status -->
<TextView
android:id="@+id/idTVDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/idEdtTrainNumber"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:padding="5dp"
android:text="Select Date"
android:textColor="@color/black"
android:textSize="18sp" />
<!-- on the below line creating a progress bar
for displaying loader -->
<ProgressBar
android:id="@+id/idPBLoading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/idTVDate"
android:visibility="gone" />
<!-- on the below line creating a text view for
displaying current train status -->
<TextView
android:id="@+id/idTVTrainStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/idTVDate"
android:layout_centerHorizontal="true"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:padding="10dp"
android:text=""
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<!-- on the below line creating a button
to get the current train status -->
<Button
android:id="@+id/btnView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/idTVTrainStatus"
android:layout_centerHorizontal="true"
android:layout_marginBottom="25sp"
android:backgroundTint="#673AB7"
android:text="Get Live Train Status" />
</RelativeLayout>
Step 5: Working with MainActivity.kt file
Navigate to app>java>your app's package name>MainActivity.kt file. Add below code to it. Comments are added in the code to get to know in detail.
Kotlin
package com.droidcon.kotlinapplication
import android.app.DatePickerDialog
import android.os.Bundle
import kotlinx.coroutines.GlobalScope
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.ProgressBar
import okhttp3.OkHttpClient
import okhttp3.Request
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jsoup.Jsoup
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
class MainActivity : AppCompatActivity() {
// on the below line creating a variable
// for train status text view.
private lateinit var trainStatusTV: TextView
// on the below line creating a variable for
// button to get live train status.
private lateinit var getTrainStatusBtn: Button
// on the below line creating a variable for edit text
// for entering train number.
private lateinit var trainNumberEdt: EditText
// on the below line creating a variable for progress bar
// for displaying loading indicator.
private lateinit var loadingPB: ProgressBar
// on the below line creating a text view
// for displaying a date.
private lateinit var dateTV: TextView
// on the below line creating an integer
// variable for year, month as well as day.
private var mYear = 0
// on the below line creating an integer
// variable for year, month as well as day.
private var mMonth = 0
// on the below line creating an integer
// variable for year, month as well as day.
private var mDay = 0
private var formattedDate = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// on the below line initializing all the variables.
trainStatusTV = findViewById(R.id.idTVTrainStatus)
getTrainStatusBtn = findViewById(R.id.btnView)
trainNumberEdt = findViewById(R.id.idEdtTrainNumber)
loadingPB = findViewById(R.id.idPBLoading)
dateTV = findViewById(R.id.idTVDate)
// on the below line adding a click listener for our get train status button.
// on the below line adding a click listener for our get train status button.
getTrainStatusBtn.setOnClickListener(View.OnClickListener {
// on the below line checking if the train number edit text
// is not empty as well as date text view is not equal to select date.
if (!trainNumberEdt.getText().toString().isEmpty() && dateTV.getText()
.toString() != "Select Date"
) {
// on the below line we are calling our async task
// to make api call to get live train status.
checkTrainStatus(trainNumberEdt.getText().toString(), formattedDate)
} else {
// on the below line displaying a toast message
// to enter train number as well as date,
Toast.makeText(
this@MainActivity,
"Please enter the train number as well as date..",
Toast.LENGTH_SHORT
).show()
}
})
// on the below line adding a click listener for our date text view.
// on the below line calling a pick date method.
dateTV.setOnClickListener {
pickDate()
}
}
// on the below line creating a date picker
// method to pick the date.
private fun pickDate() {
// on the below line creating a variable for
// calendar and getting instance for the same.
val c = Calendar.getInstance()
// on the below line getting current
// date with day, month and year.
mYear = c[Calendar.YEAR]
mMonth = c[Calendar.MONTH]
mDay = c[Calendar.DAY_OF_MONTH]
// on the below line creating and initializing
// variable for date picker dialog.
val datePickerDialog = DatePickerDialog(
this,
{ view, year, monthOfYear, dayOfMonth -> // on the below line we are getting the date from date picker dialog.
val dateFormat = dayOfMonth.toString() + "-" + (monthOfYear + 1) + "-" + year
// on the below line we are specifying the input date
// format and output date format.
val inputDateFormat = SimpleDateFormat("dd-MM-yyyy")
val outputDateFormat = SimpleDateFormat("yyyyMMdd")
// on the below line parsing input date.
var inputDate: Date? = null
try {
// on the below line parsing the date.
inputDate = inputDateFormat.parse(dateFormat)
// Format the parsed date to the desired output format
val outputDateStr = outputDateFormat.format(inputDate)
// on the below line setting date in a variable.
formattedDate = outputDateStr
} catch (e: Exception) {
// on the below line handling exception while parsing the date.
e.printStackTrace()
}
// on the below line setting date to our text view.
dateTV.text = dayOfMonth.toString() + "-" + (monthOfYear + 1) + "-" + year
}, mYear, mMonth, mDay
)
// on the below line calling date picker dialog show method to display the dialog.
datePickerDialog.show()
}
// on the below line creating a method to check train status.
fun checkTrainStatus(trainNumber: String, date: String) {
// on the below line changing visibility for progress bar.
loadingPB.visibility = View.VISIBLE
// on the below line calling global scope.
GlobalScope.launch(Dispatchers.IO) {
// on the below line specifying try and catch block.
try {
// on the below line creating url for making call for web page.
val url = "https://runningstatus.in/status/$trainNumber-on-$date"
// on the below line creating a variable for http client and initializing it.
val client = OkHttpClient()
// on the below line creating and initializing variable for request.
val request = Request.Builder().url(url).build()
// on the below line making a new call.
val response = client.newCall(request).execute()
// on the below line getting the response.
val responseBody = response.body?.string()
// on the below line getting train status by parsing data to inside parse train status method.
val trainStatus = parseTrainStatus(responseBody)
// on the below line changing visibility for the progress bar and setting train status to our text view.
withContext(Dispatchers.Main) {
loadingPB.visibility = View.GONE
trainStatusTV.text = trainStatus
}
// on the below line handling the exception.
} catch (e: Exception) {
e.printStackTrace()
// on the below line handling error.
withContext(Dispatchers.Main) {
loadingPB.visibility = View.GONE
trainStatusTV.text = "Please enter a valid train number.."
}
}
}
}
// on the below line creating a method to parse the response.
private fun parseTrainStatus(responseBody: String?): String {
// on the below line creating and initializing variable for jsoup.
val document = Jsoup.parse(responseBody)
// on the below line getting first element for card header.
val cardHeaderElement = document.select("div.card-header").first()
// on the below line checking if card header element is not null.
if (cardHeaderElement != null) {
// on the below line removing small and a tag.
cardHeaderElement.select("small").remove()
cardHeaderElement.select("a").remove()
// on the below line returning the text result.
return cardHeaderElement.text()
} else {
// on the below line returning the error message.
return "Please enter a valid train number.."
}
}
}
Now run your application to see the output of the application.
Output:
Similar Reads
How to Build a Sensor App in Android?
Android mobile phones have sensors, so we can perform various functions like Controlling screen brightness, Monitoring acceleration along a single axis, Motion detection, etc. In this article, we will be building an application that will determine the intensity of light in the room with the help of
5 min read
How to Build a Simple Torch App in Android using Kotlin?
Torch Application is a very basic application that every beginner level android developer should definitely try to build while learning Android. In this article, we will be creating an application in which we will simply display a toggle button to switch on and switch off the torch. Note: If you are
4 min read
How to Build a Weather App in Android?
In this project, we will be building a weather application. This application will show the temperature of a location. To fetch weather information we will need an API. An API(Application Programming Interface) is a function that allows applications to interact and share data using various components
6 min read
How to Build a Simple Notes App in Android?
Notes app is used for making short text notes, updating when you need them, and trashing when you are done. It can be used for various functions as you can add your to-do list in this app, some important notes for future reference, etc. The app is very useful in some cases like when you want quick a
9 min read
How to Build a SOS Mobile Application in Android Studio?
The SOS applications are basically advanced emergency apps that can rescue you and/or your loved ones if you and/or they find themselves in a life-threatening emergency situation and need immediate assistance. When you need some personal assistance, you can actually turn on your phone and can call o
15+ min read
How to Build a ChatGPT Like App in Android using OpenAI API?
Chat GPT is nowadays one of the famous AI tools which are like a chatbot. This chatbot answers all the queries which are sent to it. In this article, we will be building a simple ChatGPT-like android application by integrating the OpenAI API(ChatGPT) where we can ask any question and get an appropri
5 min read
How to Build Live Cricket Score Application in Android?
There are many android applications which are available in the market which provide real-time cricket score updates easily at your fingertips. This application provides real-time updates for different cricket matches being played across the world. In this article, we will be building a simple applic
13 min read
How to Build a Simple Alarm Setter App in Android?
In this article, we are going to see how to build a much interesting app named Alarm Setter. Alarm plays a vital role in our day-to-day life. Nowadays alarm has become our wake-up assistant. Every mobile phone is associated with an alarm app. We will create this app using android studio. Android Stu
5 min read
How to Build a Pomodoro App in Android?
The Pomodoro Technique is a time management method developed by Francesco Cirillo in the late 1980s. The technique uses a timer to break down work into intervals, traditionally 25 minutes in length, separated by short breaks of 5 minutes. These intervals are known as "pomodoros". The method is based
4 min read
How to Build a Sticky Notes Application in Android Studio?
We as humans tend to forget some small but important things, and to resolve this we try to write those things up and paste them somewhere, we often have eyes on. And in this digital era, the things we are most likely to see are laptop, computer, or mobile phone screens. For this, we all have once us
11 min read