Introduction
In this article, I shall show you how to make a weather Android app using Open-Weather-Map API by geographic coordinates.
Prerequisites
  • Weather API Key
  • Newtonsoft.json Packages
  • AppCompat Android Library v7
  • Picasso Images Caching Library
Step1
First, we need to open Weather Map API key. Go to https://openweathermap.org create an account and get the API key.
Step2
Open Visual Studio and go to New Project-> Templates-> Visual C#-> Android-> Blank app. Give it a name, like WeatherApp.
Step3
Next, go to Solution Explorer-> Project Name-> References. Then, right-click to "Manage NuGet Packages" and search for JSON. Install the Newtonsoft.Json Packages.
Step4
Next, we need to add a component that is required for layout. Open Solution Explorer and go to Components -> Get More Components. In this way, you can move on Xamarin Components Store, then search for AppCompat and click "Add to App".
Step5
Next, we need to add a more component that is required for caching images from web. Open Solution Explorer and go to Components -> Get More Components. In this way, you can move on Xamarin Components Store, then search for Picasso and click "Add to App".
Step6
Next, go to Solution Explorer-> Project Name and right-click. Select Add -> New Item-> Class. Give it a name, like Common.cs and write the following code with appropriate namespaces.
(Class Name: Common)
Note

Please must change API_KEY of your common class.
  1. using System;
  2. using System.Text;
  3. namespace XamarinWeatherApp.Common {
  4. class Common {
  5. public static string API_KEY = "39a553a8c16c4d286e3acc2be7067c6e";
  6. public static string API_LINK = "https://api.openweathermap.org/data/2.5/weather";
  7. public static string APIRequest(string lat, string lng) {
  8. StringBuilder sb = new StringBuilder(API_LINK);
  9. sb.AppendFormat("?lat={0}&lon={1}&APPID={2}&units=metric", lat, lng, API_KEY);
  10. return sb.ToString();
  11. }
  12. public static DateTime UnixTimeStampToDateTime(double unixTimeStamp) {
  13. DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
  14. dt = dt.AddSeconds(unixTimeStamp).ToLocalTime();
  15. return dt;
  16. }
  17. public static string GetImage(string icon) {
  18. return $ "http://openweathermap.org/img/w/{icon}.png";
  19. }
  20. }
  21. }
Step7

Similarly, create another class named as OpenWeatherMap.cs and write the following code with appropriate namespaces.
(File Name - OpenWeatherMap)
  1. using System.Collections.Generic;
  2. namespace XamarinWeatherApp.Model {
  3. public class Coord {
  4. public double lon {
  5. get;
  6. set;
  7. }
  8. public double lat {
  9. get;
  10. set;
  11. }
  12. }
  13. public class Weather {
  14. public int id {
  15. get;
  16. set;
  17. }
  18. public string main {
  19. get;
  20. set;
  21. }
  22. public string description {
  23. get;
  24. set;
  25. }
  26. public string icon {
  27. get;
  28. set;
  29. }
  30. }
  31. public class Main {
  32. public double temp {
  33. get;
  34. set;
  35. }
  36. public double pressure {
  37. get;
  38. set;
  39. }
  40. public int humidity {
  41. get;
  42. set;
  43. }
  44. public double temp_min {
  45. get;
  46. set;
  47. }
  48. public double temp_max {
  49. get;
  50. set;
  51. }
  52. public double sea_level {
  53. get;
  54. set;
  55. }
  56. public double grnd_level {
  57. get;
  58. set;
  59. }
  60. }
  61. public class Wind {
  62. public double speed {
  63. get;
  64. set;
  65. }
  66. public double deg {
  67. get;
  68. set;
  69. }
  70. }
  71. public class Clouds {
  72. public int all {
  73. get;
  74. set;
  75. }
  76. }
  77. public class Sys {
  78. public double message {
  79. get;
  80. set;
  81. }
  82. public string country {
  83. get;
  84. set;
  85. }
  86. public int sunrise {
  87. get;
  88. set;
  89. }
  90. public int sunset {
  91. get;
  92. set;
  93. }
  94. }
  95. public class OpenWeatherMap {
  96. public Coord coord {
  97. get;
  98. set;
  99. }
  100. public List < Weather > weather {
  101. get;
  102. set;
  103. }
  104. public string @base {
  105. get;
  106. set;
  107. }
  108. public Main main {
  109. get;
  110. set;
  111. }
  112. public Wind wind {
  113. get;
  114. set;
  115. }
  116. public Clouds clouds {
  117. get;
  118. set;
  119. }
  120. public int dt {
  121. get;
  122. set;
  123. }
  124. public Sys sys {
  125. get;
  126. set;
  127. }
  128. public int id {
  129. get;
  130. set;
  131. }
  132. public string name {
  133. get;
  134. set;
  135. }
  136. public int cod {
  137. get;
  138. set;
  139. }
  140. }
  141. }
Step8
Next, create another class named as Helper.cs and write the following code with appropriate namespaces.
(File Name - Helper)
  1. using Java.IO;
  2. using Java.Net;
  3. using System;
  4. using System.Text;
  5. namespace XamarinWeatherApp.Helper {
  6. public class Helper {
  7. static String stream = null;
  8. public Helper() {}
  9. public String GetHTTPData(String urlString) {
  10. try {
  11. URL url = new URL(urlString);
  12. using(var urlConnection = (HttpURLConnection) url.OpenConnection()) {
  13. if (urlConnection.ResponseCode == HttpStatus.Ok) {
  14. BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.InputStream));
  15. StringBuilder sb = new StringBuilder();
  16. String line;
  17. while ((line = r.ReadLine()) != null) sb.Append(line);
  18. stream = sb.ToString();
  19. urlConnection.Disconnect();
  20. }
  21. }
  22. } catch (Exception ex) {
  23. System.Diagnostics.Debug.WriteLine(ex.Message);
  24. }
  25. return stream;
  26. }
  27. }
  28. }
Step9
Now, open Solution Explorer-> Project Name-> Resources-> Layout-> Main.axml. Open this main layout file and add the following code.
(File Name: Main.axml)
(Folder Name: Layout)
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
  3. <TextView android:id="@+id/txtCity" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:text="" android:textSize="36sp" android:gravity="center" />
  4. <TextView android:id="@+id/txtLastUpdate" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:textSize="16sp" android:gravity="center" />
  5. <ImageView android:id="@+id/imageView" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center" />
  6. <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/txtDescription" android:text="" android:textSize="30sp" android:gravity="center" />
  7. <TextView android:id="@+id/txtHumidity" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:textSize="30sp" android:gravity="center" />
  8. <TextView android:id="@+id/txtTime" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:textSize="36sp" android:gravity="center" />
  9. <TextView android:id="@+id/txtCelsius" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:textSize="80sp" android:gravity="center" />
  10. </LinearLayout>
Step10
Next, open Solution Explorer-> Project Name-> MainActivity. Open the main activity file and add the following code using appropriate namespaces.
Main Activity
  1. using Android.App;
  2. using Android.Widget;
  3. using Android.OS;
  4. using Android.Locations;
  5. using XamarinWeatherApp.Model;
  6. using Android.Runtime;
  7. using System;
  8. using Square.Picasso;
  9. using Newtonsoft.Json;
  10. using Android.Content;
  11. namespace XamarinWeatherApp {
  12. [Activity(Label = "WeatherApp", MainLauncher = true, Icon = "@drawable/icon", Theme = "@style/Theme.AppCompat.Light.NoActionBar")]
  13. public class MainActivity: Activity, ILocationListener {
  14. TextView txtCity, txtLastUpdate, txtDescription, txtHumidity, txtTime, txtCelsius;
  15. ImageView imgView;
  16. LocationManager locationManager;
  17. string provider;
  18. static double lat, lng;
  19. OpenWeatherMap openWeatherMap = new OpenWeatherMap();
  20. protected override void OnCreate(Bundle bundle) {
  21. base.OnCreate(bundle);
  22. // Set our view from the "main" layout resource
  23. SetContentView(Resource.Layout.Main);
  24. locationManager = (LocationManager) GetSystemService(Context.LocationService);
  25. provider = locationManager.GetBestProvider(new Criteria(), false);
  26. Location location = locationManager.GetLastKnownLocation(provider);
  27. if (location == null) System.Diagnostics.Debug.WriteLine("No Location");
  28. }
  29. protected override void OnResume() {
  30. base.OnResume();
  31. locationManager.RequestLocationUpdates(provider, 400, 1, this);
  32. }
  33. protected override void OnPause() {
  34. base.OnPause();
  35. locationManager.RemoveUpdates(this);
  36. }
  37. public void OnLocationChanged(Location location) {
  38. lat = Math.Round(location.Latitude, 4);
  39. lng = Math.Round(location.Longitude, 4);
  40. new GetWeather(this, openWeatherMap).Execute(Common.Common.APIRequest(lat.ToString(), lng.ToString()));
  41. }
  42. public void OnProviderDisabled(string provider) {}
  43. public void OnProviderEnabled(string provider) {}
  44. public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras) {}
  45. private class GetWeather: AsyncTask < string, Java.Lang.Void, string > {
  46. private ProgressDialog pd = new ProgressDialog(Application.Context);
  47. private MainActivity activity;
  48. OpenWeatherMap openWeatherMap;
  49. public GetWeather(MainActivity activity, OpenWeatherMap openWeatherMap) {
  50. this.activity = activity;
  51. this.openWeatherMap = openWeatherMap;
  52. }
  53. protected override void OnPreExecute() {
  54. base.OnPreExecute();
  55. pd.Window.SetType(Android.Views.WindowManagerTypes.SystemAlert);
  56. pd.SetTitle("Please wait....");
  57. pd.Show();
  58. }
  59. protected override string RunInBackground(params string[] @params) {
  60. string stream = null;
  61. string urlString = @params[0];
  62. Helper.Helper http = new Helper.Helper();
  63. //urlString = Common.Common.APIRequest(lat.ToString(), lng.ToString());
  64. stream = http.GetHTTPData(urlString);
  65. return stream;
  66. }
  67. protected override void OnPostExecute(string result) {
  68. base.OnPostExecute(result);
  69. if (result.Contains("Error: Not City Found")) {
  70. pd.Dismiss();
  71. return;
  72. }
  73. openWeatherMap = JsonConvert.DeserializeObject < OpenWeatherMap > (result);
  74. pd.Dismiss();
  75. //Controls
  76. activity.txtCity = activity.FindViewById < TextView > (Resource.Id.txtCity);
  77. activity.txtLastUpdate = activity.FindViewById < TextView > (Resource.Id.txtLastUpdate);
  78. activity.txtDescription = activity.FindViewById < TextView > (Resource.Id.txtDescription);
  79. activity.txtHumidity = activity.FindViewById < TextView > (Resource.Id.txtHumidity);
  80. activity.txtTime = activity.FindViewById < TextView > (Resource.Id.txtTime);
  81. activity.txtCelsius = activity.FindViewById < TextView > (Resource.Id.txtCelsius);
  82. activity.imgView = activity.FindViewById < ImageView > (Resource.Id.imageView);
  83. //Add Data
  84. activity.txtCity.Text = $ "{openWeatherMap.name},{openWeatherMap.sys.country}";
  85. activity.txtLastUpdate.Text = $ "Last Updated: {DateTime.Now.ToString("
  86. dd MMMM yyyy HH: mm ")}";
  87. activity.txtDescription.Text = $ "{openWeatherMap.weather[0].description}";
  88. activity.txtHumidity.Text = $ "Humidity: {openWeatherMap.main.humidity} %";
  89. activity.txtTime.Text = $ "{Common.Common.UnixTimeStampToDateTime(openWeatherMap.sys.sunrise).ToString("
  90. HH: mm ")}/{Common.Common.UnixTimeStampToDateTime(openWeatherMap.sys.sunset).ToString("
  91. HH: mm ")}";
  92. activity.txtCelsius.Text = $ "{openWeatherMap.main.temp} °C";
  93. if (!string.IsNullOrEmpty(openWeatherMap.weather[0].icon)) {
  94. Picasso.With(activity.ApplicationContext).Load(Common.Common.GetImage(openWeatherMap.weather[0].icon)).Into(activity.imgView);
  95. }
  96. }
  97. }
  98. }
  99. }
Step11
We need some permissions from device. Let's open Solution Explorer and go to Properties-> AndroidManifest and add the following code inside application tags.
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  2. <uses-permission android:name="android.permission.INTERNET" />
  3. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  4. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  5. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  6. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  7. <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
Finally, we have done our Weather app just rebuild and run the project. You will have the result like below.
Output