Currency Converter Android App
This video shows the steps and code to create your own currency conversion Android App.
It uses the APIs from https://www.exchangerate-api.com/. This provides free API for certain number of usage which is good enough to build any prototype and POCs.
The App demo shown in this video is also hosted on Play store at: https://play.google.com/store/apps/details?id=com.programmerworld.currencyconverter_programmerworld
Please try.
I hope you like this video. For any questions, suggestions or appreciation please contact us at: https://programmerworld.co/contact/ or email at: programmerworld1990@gmail.com
Source Code:
package com.programmerworld.currencyconverter_programmerworld;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainActivity extends AppCompatActivity {
// Populate the Spinner with a list of supported currencies
private String[] currencies = {
"USD - United States Dollar - United States",
"INR - Indian Rupee - India",
"EUR - Euro - European Union",
"AED - UAE Dirham - United Arab Emirates",
"AFN - Afghan Afghani - Afghanistan",
"ALL - Albanian Lek - Albania",
"AMD - Armenian Dram - Armenia",
"ANG - Netherlands Antillian Guilder - Netherlands Antilles",
"AOA - Angolan Kwanza - Angola",
"ARS - Argentine Peso - Argentina",
"AUD - Australian Dollar - Australia",
"AWG - Aruban Florin - Aruba",
"AZN - Azerbaijani Manat - Azerbaijan",
"BAM - Bosnia and Herzegovina Mark - Bosnia and Herzegovina",
"BBD - Barbados Dollar - Barbados",
"BDT - Bangladeshi Taka - Bangladesh",
"BGN - Bulgarian Lev - Bulgaria",
"BHD - Bahraini Dinar - Bahrain",
"BIF - Burundian Franc - Burundi",
"BMD - Bermudian Dollar - Bermuda",
"BND - Brunei Dollar - Brunei",
"BOB - Bolivian Boliviano - Bolivia",
"BRL - Brazilian Real - Brazil",
"BSD - Bahamian Dollar - Bahamas",
"BTN - Bhutanese Ngultrum - Bhutan",
"BWP - Botswana Pula - Botswana",
"BYN - Belarusian Ruble - Belarus",
"BZD - Belize Dollar - Belize",
"CAD - Canadian Dollar - Canada",
"CDF - Congolese Franc - Democratic Republic of the Congo",
"CHF - Swiss Franc - Switzerland",
"CLP - Chilean Peso - Chile",
"CNY - Chinese Renminbi - China",
"COP - Colombian Peso - Colombia",
"CRC - Costa Rican Colon - Costa Rica",
"CUP - Cuban Peso - Cuba",
"CVE - Cape Verdean Escudo - Cape Verde",
"CZK - Czech Koruna - Czech Republic",
"DJF - Djiboutian Franc - Djibouti",
"DKK - Danish Krone - Denmark",
"DOP - Dominican Peso - Dominican Republic",
"DZD - Algerian Dinar - Algeria",
"EGP - Egyptian Pound - Egypt",
"ERN - Eritrean Nakfa - Eritrea",
"ETB - Ethiopian Birr - Ethiopia",
"FJD - Fiji Dollar - Fiji",
"FKP - Falkland Islands Pound - Falkland Islands",
"FOK - Faroese Króna - Faroe Islands",
"GBP - Pound Sterling - United Kingdom",
"GEL - Georgian Lari - Georgia",
"GGP - Guernsey Pound - Guernsey",
"GHS - Ghanaian Cedi - Ghana",
"GIP - Gibraltar Pound - Gibraltar",
"GMD - Gambian Dalasi - The Gambia",
"GNF - Guinean Franc - Guinea",
"GTQ - Guatemalan Quetzal - Guatemala",
"GYD - Guyanese Dollar - Guyana",
"HKD - Hong Kong Dollar - Hong Kong",
"HNL - Honduran Lempira - Honduras",
"HRK - Croatian Kuna - Croatia",
"HTG - Haitian Gourde - Haiti",
"HUF - Hungarian Forint - Hungary",
"IDR - Indonesian Rupiah - Indonesia",
"ILS - Israeli New Shekel - Israel",
"IMP - Manx Pound - Isle of Man",
"IQD - Iraqi Dinar - Iraq",
"IRR - Iranian Rial - Iran",
"ISK - Icelandic Króna - Iceland",
"JEP - Jersey Pound - Jersey",
"JMD - Jamaican Dollar - Jamaica",
"JOD - Jordanian Dinar - Jordan",
"JPY - Japanese Yen - Japan",
"KES - Kenyan Shilling - Kenya",
"KGS - Kyrgyzstani Som - Kyrgyzstan",
"KHR - Cambodian Riel - Cambodia",
"KID - Kiribati Dollar - Kiribati",
"KMF - Comorian Franc - Comoros",
"KRW - South Korean Won - South Korea",
"KWD - Kuwaiti Dinar - Kuwait",
"KYD - Cayman Islands Dollar - Cayman Islands",
"KZT - Kazakhstani Tenge - Kazakhstan",
"LAK - Lao Kip - Laos",
"LBP - Lebanese Pound - Lebanon",
"LKR - Sri Lanka Rupee - Sri Lanka",
"LRD - Liberian Dollar - Liberia",
"LSL - Lesotho Loti - Lesotho",
"LYD - Libyan Dinar - Libya",
"MAD - Moroccan Dirham - Morocco",
"MDL - Moldovan Leu - Moldova",
"MGA - Malagasy Ariary - Madagascar",
"MKD - Macedonian Denar - North Macedonia",
"MMK - Burmese Kyat - Myanmar",
"MNT - Mongolian Tögrög - Mongolia",
"MOP - Macanese Pataca - Macau",
"MRU - Mauritanian Ouguiya - Mauritania",
"MUR - Mauritian Rupee - Mauritius",
"MVR - Maldivian Rufiyaa - Maldives",
"MWK - Malawian Kwacha - Malawi",
"MXN - Mexican Peso - Mexico",
"MYR - Malaysian Ringgit - Malaysia",
"MZN - Mozambican Metical - Mozambique",
"NAD - Namibian Dollar - Namibia",
"NGN - Nigerian Naira - Nigeria",
"NIO - Nicaraguan Córdoba - Nicaragua",
"NOK - Norwegian Krone - Norway",
"NPR - Nepalese Rupee - Nepal",
"NZD - New Zealand Dollar - New Zealand",
"OMR - Omani Rial - Oman",
"PAB - Panamanian Balboa - Panama",
"PEN - Peruvian Sol - Peru",
"PGK - Papua New Guinean Kina - Papua New Guinea",
"PHP - Philippine Peso - Philippines",
"PKR - Pakistani Rupee - Pakistan",
"PLN - Polish Z?oty - Poland",
"PYG - Paraguayan Guaraní - Paraguay",
"QAR - Qatari Riyal - Qatar",
"RON - Romanian Leu - Romania",
"RSD - Serbian Dinar - Serbia",
"RUB - Russian Ruble - Russia",
"RWF - Rwandan Franc - Rwanda",
"SAR - Saudi Riyal - Saudi Arabia",
"SBD - Solomon Islands Dollar - Solomon Islands",
"SCR - Seychellois Rupee - Seychelles",
"SDG - Sudanese Pound - Sudan",
"SEK - Swedish Krona - Sweden",
"SGD - Singapore Dollar - Singapore",
"SHP - Saint Helena Pound - Saint Helena",
"SLE - Sierra Leonean Leone - Sierra Leone",
"SOS - Somali Shilling - Somalia",
"SRD - Surinamese Dollar - Suriname",
"SSP - South Sudanese Pound - South Sudan",
"STN - São Tomé and Príncipe Dobra - São Tomé and Príncipe",
"SYP - Syrian Pound - Syria",
"SZL - Eswatini Lilangeni - Eswatini",
"THB - Thai Baht - Thailand",
"TJS - Tajikistani Somoni - Tajikistan",
"TMT - Turkmenistan Manat - Turkmenistan",
"TND - Tunisian Dinar - Tunisia",
"TOP - Tongan Pa?anga - Tonga",
"TRY - Turkish Lira - Turkey",
"TTD - Trinidad and Tobago Dollar - Trinidad and Tobago",
"TVD - Tuvaluan Dollar - Tuvalu",
"TWD - New Taiwan Dollar - Taiwan",
"TZS - Tanzanian Shilling - Tanzania",
"UAH - Ukrainian Hryvnia - Ukraine",
"UGX - Ugandan Shilling - Uganda",
"UYU - Uruguayan Peso - Uruguay",
"UZS - Uzbekistani So'm - Uzbekistan",
"VES - Venezuelan Bolívar Soberano - Venezuela",
"VND - Vietnamese ??ng - Vietnam",
"VUV - Vanuatu Vatu - Vanuatu",
"WST - Samoan T?l? - Samoa",
"XAF - Central African CFA Franc - CEMAC",
"XCD - East Caribbean Dollar - Organisation of Eastern Caribbean States",
"XDR - Special Drawing Rights - International Monetary Fund",
"XOF - West African CFA franc - CFA",
"XPF - CFP Franc - Collectivités d'Outre-Mer",
"YER - Yemeni Rial - Yemen",
"ZAR - South African Rand - South Africa",
"ZMW - Zambian Kwacha - Zambia",
"ZWL - Zimbabwean Dollar - Zimbabwe"
};
private EditText amountInput;
private Spinner currencySpinnerFrom;
private Spinner currencySpinnerTo;
private Button convertButton;
private TextView resultText;
private String API_URL = "https://v6.exchangerate-api.com/v6/d3a7d0b2b4c67bb7dIO1650/latest/USD"; // Replace with your API key
private String selectedCurrencyFrom = "USD"; // Default selection
private String selectedCurrencyTo = "USD"; // Default selection
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
amountInput = findViewById(R.id.amountInput);
currencySpinnerFrom = findViewById(R.id.currencySpinnerFrom);
currencySpinnerTo = findViewById(R.id.currencySpinnerTo);
convertButton = findViewById(R.id.convertButton);
resultText = findViewById(R.id.resultText);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, currencies);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
currencySpinnerFrom.setAdapter(adapter);
currencySpinnerTo.setAdapter(adapter);
currencySpinnerFrom.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selectedItem = (String) parent.getItemAtPosition(position);
selectedCurrencyFrom = selectedItem.split(" ")[0]; // Extract currency code (e.g., USD)
API_URL = API_URL.substring(0, API_URL.length() - 3) + selectedCurrencyFrom;
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing
}
});
currencySpinnerTo.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selectedItem = (String) parent.getItemAtPosition(position);
selectedCurrencyTo = selectedItem.split(" ")[0]; // Extract currency code (e.g., USD)
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing
}
});
convertButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String input = amountInput.getText().toString();
if (input.isEmpty()) {
Toast.makeText(MainActivity.this, "Please enter an amount", Toast.LENGTH_SHORT).show();
} else {
fetchConversionRate(Double.parseDouble(input));
}
}
});
amountInput.requestFocus();
return insets;
});
}
private void fetchConversionRate(double amount) {
// Create a single-threaded executor
ExecutorService executorService = Executors.newSingleThreadExecutor();
Handler mainHandler = new Handler(Looper.getMainLooper());
executorService.execute(() -> {
// Background thread work (e.g., network operation)
double conversionRate = fetchConversionRateFromAPI(amount); // Replace with your API call
// Post the result back to the main thread
mainHandler.post(() -> {
// Update the UI with the result
updateUIWithConversionRate(conversionRate);
});
});
}
private void updateUIWithConversionRate(Double convertedAmount) {
if (convertedAmount != null) {
resultText.setText("Converted Amount: " + selectedCurrencyTo +
" " + String.format("%.2f", convertedAmount));
} else {
Toast.makeText(MainActivity.this, "Error fetching conversion rate", Toast.LENGTH_SHORT).show();
}
}
private Double fetchConversionRateFromAPI(Double amounts) {
try {
URL url = new URL(API_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
reader.close();
JSONObject jsonObject = new JSONObject(result.toString());
double conversionRate = jsonObject.getJSONObject("conversion_rates").getDouble(selectedCurrencyTo); // Change target currency as needed
return amounts * conversionRate;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="80dp" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="From"
android:textSize="24sp" />
<Spinner
android:id="@+id/currencySpinnerFrom"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="To"
android:textSize="24sp" />
<Spinner
android:id="@+id/currencySpinnerTo"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp" />
<EditText
android:id="@+id/amountInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter amount"
android:inputType="numberDecimal"
android:padding="10dp"
android:text="1"
android:textSize="24sp" />
<Button
android:id="@+id/convertButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Convert" />
<TextView
android:id="@+id/resultText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textSize="24sp"
android:textStyle="bold" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/currencyconverter"
android:label="@string/app_name"
android:roundIcon="@mipmap/currencyconverter_round"
android:supportsRtl="true"
android:theme="@style/Theme.CurrencyConverterProgrammerWorld"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:windowSoftInputMode="stateVisible|adjustResize"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
plugins {
alias(libs.plugins.android.application)
}
android {
namespace = "com.programmerworld.currencyconverter_programmerworld"
compileSdk = 34
defaultConfig {
applicationId = "com.programmerworld.currencyconverter_programmerworld"
minSdk = 34
targetSdk = 34
versionCode = 1
versionName = "1.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}
dependencies {
implementation(libs.appcompat)
implementation(libs.material)
implementation(libs.activity)
implementation(libs.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
}
Screenshots:
Google Play Store link: https://play.google.com/store/apps/details?id=com.programmerworld.currencyconverter_programmerworld