Weather reporting Android App
In this video it shows the steps and code to create your own weather reporting Android App.
It uses the API provided by Open Weather which is free for first 1000 calls. https://openweathermap.org/api
This App is also hosted on Programmer World’s Play store for reference: https://play.google.com/store/apps/developer?id=Programmer+World
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
Code:
package com.programmerworld.weatherapp;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
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.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
// Example: Loading cities dynamically (pseudo-code)
private List<String> cityList = new ArrayList<>();
private Spinner citySpinner;
private ListView listView;
private ArrayAdapter<String> adapter;
private List<String> weatherDataList = new ArrayList<>();
private final String API_KEY = "b6e94eO6072ba197b2caf95e5321beIe";
private final String BASE_URL = "https://api.openweathermap.org/data/2.5/forecast?";
@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);
citySpinner = findViewById(R.id.citySpinner);
listView = findViewById(R.id.listView);
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, weatherDataList);
listView.setAdapter(adapter);
updateCityList();
ArrayAdapter<String> dynamicAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, cityList);
dynamicAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
citySpinner.setAdapter(dynamicAdapter);
return insets;
});
}
private void updateCityList(){
// Indian Cities (IN)
cityList.add("Bangalore, IN");
cityList.add("Chennai, IN");
cityList.add("Delhi, IN");
cityList.add("Kolkata, IN");
cityList.add("Mumbai, IN");
// United Kingdom (GB)
cityList.add("London, GB");
// United States (US)
cityList.add("New York, US");
// United Arab Emirates (AE)
cityList.add("Dubai, AE");
// Argentina (AR)
cityList.add("Buenos Aires, AR");
// Armenia (AM)
cityList.add("Yerevan, AM");
// Australia (AU)
cityList.add("Brisbane, AU");
cityList.add("Melbourne, AU");
cityList.add("Perth, AU");
cityList.add("Sydney, AU");
// Azerbaijan (AZ)
cityList.add("Baku, AZ");
// Bahrain (BH)
cityList.add("Manama, BH");
// Belgium (BE)
cityList.add("Brussels, BE");
// Bangladesh (BD)
cityList.add("Dhaka, BD");
// Belarus (BY)
cityList.add("Minsk, BY");
// Bolivia (BO)
cityList.add("La Paz, BO");
// Bosnia and Herzegovina (BA)
cityList.add("Sarajevo, BA");
// Brazil (BR)
cityList.add("São Paulo, BR");
// Bulgaria (BG)
cityList.add("Sofia, BG");
// Canada (CA)
cityList.add("Montreal, CA");
cityList.add("Toronto, CA");
// Chile (CL)
cityList.add("Santiago, CL");
// China (CN)
cityList.add("Beijing, CN");
cityList.add("Shanghai, CN");
// Colombia (CO)
cityList.add("Bogotá, CO");
// Costa Rica (CR)
cityList.add("San Jose, CR");
// Cuba (CU)
cityList.add("Havana, CU");
// Czech Republic (CZ)
cityList.add("Prague, CZ");
// Denmark (DK)
cityList.add("Copenhagen, DK");
// Dominican Republic (DM)
cityList.add("Roseau, DM");
// Ecuador (EC)
cityList.add("Quito, EC");
// Egypt (EG)
cityList.add("Cairo, EG");
// Estonia (EE)
cityList.add("Tallinn, EE");
// Finland (FI)
cityList.add("Helsinki, FI");
// France (FR)
cityList.add("Lyon, FR");
cityList.add("Paris, FR");
// Germany (DE)
cityList.add("Berlin, DE");
cityList.add("Munich, DE");
// Ghana (GH)
cityList.add("Accra, GH");
// Greece (GR)
cityList.add("Athens, GR");
// Guatemala (GT)
cityList.add("Guatemala City, GT");
// Hong Kong (HK)
cityList.add("Hong Kong, HK");
// Hungary (HU)
cityList.add("Budapest, HU");
// Indonesia (ID)
cityList.add("Jakarta, ID");
// Iran (IR)
cityList.add("Tehran, IR");
// Ireland (IE)
cityList.add("Dublin, IE");
// Italy (IT)
cityList.add("Rome, IT");
// Japan (JP)
cityList.add("Tokyo, JP");
// Jordan (JO)
cityList.add("Amman, JO");
// Kenya (KE)
cityList.add("Nairobi, KE");
// Kuwait (KW)
cityList.add("Kuwait City, KW");
// Latvia (LV)
cityList.add("Riga, LV");
// Lithuania (LT)
cityList.add("Vilnius, LT");
// Malaysia (MY)
cityList.add("Kuala Lumpur, MY");
// Mexico (MX)
cityList.add("Mexico City, MX");
// Morocco (MA)
cityList.add("Casablanca, MA");
// Netherlands (NL)
cityList.add("Amsterdam, NL");
// New Zealand (NZ)
cityList.add("Auckland, NZ");
// Nigeria (NG)
cityList.add("Lagos, NG");
// Norway (NO)
cityList.add("Oslo, NO");
// Oman (OM)
cityList.add("Muscat, OM");
// Pakistan (PK)
cityList.add("Karachi, PK");
// Panama (PA)
cityList.add("Panama City, PA");
// Peru (PE)
cityList.add("Lima, PE");
// Philippines (PH)
cityList.add("Manila, PH");
// Poland (PL)
cityList.add("Warsaw, PL");
// Portugal (PT)
cityList.add("Lisbon, PT");
// Qatar (QA)
cityList.add("Doha, QA");
// Romania (RO)
cityList.add("Bucharest, RO");
// Russia (RU)
cityList.add("Moscow, RU");
// Saudi Arabia (SA)
cityList.add("Riyadh, SA");
// Singapore (SG)
cityList.add("Singapore, SG");
// Slovakia (SK)
cityList.add("Bratislava, SK");
// Slovenia (SI)
cityList.add("Ljubljana, SI");
// South Africa (ZA)
cityList.add("Cape Town, ZA");
cityList.add("Johannesburg, ZA");
// South Korea (KR)
cityList.add("Seoul, KR");
// Spain (ES)
cityList.add("Barcelona, ES");
cityList.add("Madrid, ES");
// Sweden (SE)
cityList.add("Stockholm, SE");
// Switzerland (CH)
cityList.add("Zurich, CH");
// Thailand (TH)
cityList.add("Bangkok, TH");
// Tunisia (TN)
cityList.add("Tunis, TN");
// Turkey (TR)
cityList.add("Istanbul, TR");
// Ukraine (UA)
cityList.add("Kyiv, UA");
// Uruguay (UY)
cityList.add("Montevideo, UY");
// Venezuela (VE)
cityList.add("Caracas, VE");
// Vietnam (VN)
cityList.add("Hanoi, VN");
cityList.add("Ho Chi Minh City, VN");
}
public void buttonGetWeatherUpdate(View view) {
// Get the selected city from the spinner
String selectedLocation = citySpinner.getSelectedItem().toString();
String selectedCity = selectedLocation.split(",")[0].trim();
String selectedCountry = selectedLocation.split(",")[1].trim();
// Call method to fetch weather data
getWeatherUpdate(selectedCity, selectedCountry);
}
private void getWeatherUpdate(String city, String country) {
OkHttpClient client = new OkHttpClient();
String url = BASE_URL + "q=" + city + "," + country + "&units=metric&appid=" + API_KEY;
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
final String responseData = response.body().string();
runOnUiThread(() -> parseJsonAndUpdateListView(responseData));
}
}
});
}
private void parseJsonAndUpdateListView(String jsonData) {
try {
JSONObject jsonObject = new JSONObject(jsonData);
JSONArray hourlyArray = jsonObject.getJSONArray("list");
weatherDataList.clear();
for (int i = 0; i < hourlyArray.length(); i++) {
JSONObject hourData = hourlyArray.getJSONObject(i);
String dateTime = hourData.getString("dt_txt");
JSONObject main = hourData.getJSONObject("main");
double temp = main.getDouble("temp");
JSONArray weather = hourData.getJSONArray("weather");
String description = weather.getJSONObject(0).getString("description");
String weatherInfo = "Time: " + dateTime + "\nTemperature: " + temp + "°C\nDescription: " + description;
weatherDataList.add(weatherInfo);
}
adapter.notifyDataSetChanged();
} catch (Exception e) {
e.printStackTrace();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Spinner
android:id="@+id/citySpinner"
android:layout_width="410dp"
android:layout_height="53dp"
android:layout_marginTop="32dp"
android:contentDescription="TODO"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="92dp"
android:onClick="buttonGetWeatherUpdate"
android:text="Get Weather"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ListView
android:id="@+id/listView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?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/weatherappicon"
android:label="@string/app_name"
android:roundIcon="@mipmap/weatherappicon_round"
android:supportsRtl="true"
android:theme="@style/Theme.WeatherApp"
tools:targetApi="31">
<activity
android:name=".MainActivity"
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.weatherapp"
compileSdk = 34
defaultConfig {
applicationId = "com.programmerworld.weatherapp"
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)
implementation("com.squareup.okhttp3:okhttp:4.9.3")
}
Screenshots: