Exercise 14 - Weather Widget
Project name : E14 Weather Widget
Purpose
In this exercise you will made a weather forecast widget using Android Studio and Kotlin programming language. Application will load weather forecast data from the Open Weather Map. Loaded weather forecast data will be shown in Android device home screen.
Widgets are an essential aspect of home screen customization. You can imagine them as “at-a-glance” views of an app’s most important data and functionality that is accessible right from the user’s home screen. Users can move widgets across their home screen panels and, if supported, resize them to tailor the amount of information within a widget to their preference.
Weather Forecast
Create a free account to OpenWeatherMap and get a API key. Look and learn Current weather data API example calls and get familiar with the returned forecast JSON data. You can access current weather data for any location on Earth including over 200,000 cities.
Learn
Check Build a App Widget material from the Android Developer site and get the basic knowledge of the App Widgets.
Create a new project
- Start Android Studio and create a new project
- Choose your project template as a Empty Activity Views
- Name your project to E14 Weather Widget and include Kotlin support
- Select the newest available API
Add Widget to your project
Select New > Widget > App Widget and add a new Widget to your project
Click image to see it bigger!
Declare an App Widget in the Manifest
First, check how the WeatherAppWidget
class is declared inside Application
element in your application’s AndroidManifest.xml file.
1 2 3 4 5 6 7 8 9 10 |
|
The <receiver>
element requires the android:name
attribute, which specifies the AppWidgetProvider used by the App Widget. WeatherAppWidget class will be the widgets main class. The <intent-filter>
element must include an <action>
element with the android:name
attribute. This attribute specifies that the AppWidgetProvider accepts the APPWIDGET_UPDATE
broadcast. The <meta-data>
element specifies the AppWidgetProviderInfo resource and now weather_app_widget_info
will describe widgets metadata.
Add AppWidgetProviderInfo metadata
The AppWidgetProviderInfo defines the essential qualities of an App Widget. For example, its minimum layout dimensions, its initial layout resource, how often to update the App Widget, and (optionally) a configuration Activity to launch at create-time.
Check generated weather_app_widget_info.xml from your res/xml folder. Now it has a lot of "default" values inside and your can modify to your own purpose (graphics etc...).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Widget width will be now 3×1 squares in the home screen. It will use weather_app_widget
layout and it can be resized horizontally and vertically. Widget is now defined to be used only in a home screen.
You can also use a preview image which will be visible at the widgets menu and when a widget will be dragged to the home screen. There is also possibility to use a configuration activity, which will be launched automatically, when widget will be dropped to the home screen.
Create App Widget Layout
You must define an initial layout for your App Widget in XML and save it in the project’s res/layout/ folder. You can use Android UI designer to design your Widget. However, you must be aware that App Widget layouts are based on RemoteViews, which do not support every kind of layout or view widget. Check all of the available views and layouts from the Android Developer site: Creating the App Widget layout.
Tip
You can't use CoordinatorLayout
, which is default layout in Android Studio projects.
Modify file weather_app_widget.xml for displaying weather forecast. Use your own imagination to layout UI elements. Name your elements: cityTextView
, condTextView
, tempTextView
, timeTextView
and iconImageView
.
Use AppWidgetProvider class
WeatherAppWidget
The AppWidgetProvider
class extends from the BroadcastReceiver as a convenience class to handle the App Widget broadcasts. The AppWidgetProvider receives only the event broadcasts which are relevant to the App Widget, like updated, deleted, enabled, and disabled events. In this tutorial you will need onUpdate
and onReceive
functions.
Check generated a WeatherAppWidget
class, which extends from the AppWidgetProvider
class.
1 2 3 |
|
Add your API key and links to OpenWeather web site to WeatherAppWidget
class. Those will be used later, when a data will be loaded with Volley.
1 2 3 4 |
|
onUpdate function
The most important AppWidgetProvider callback is onUpdate()
because it is called, when each App Widget is added to a host (unless you use a configuration Activity). You will need to register all of your application user interaction events inside this function.
Check an onUpdate()
function which loops through each of the App Widget that belongs to this provider.
1 2 3 4 5 6 7 8 9 10 11 |
|
In this tutorial the MainActivity
will be opened, when the end user has clicked the cityTextView
text. You will need to use a PendingIntent to it. A Pending Intent specifies an action to take in the future. It lets you pass a future Intent to another application and allow that application to execute that Intent.
After that a weather forecast will be loaded with own made loadForecast
function.
Add below code to inside above widget’s loop.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Load Weather Forecast
Create loadWeatherForecast
function, which will be used to load weather forecast from the OpenWeather. You should look exercise 15, if you haven’t done it, to understand the loading and parsing JSON data.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
After that use Volley to load JSON data from the OpenWeather. Remember install Volley to your project.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Volley will call Response.Listener<JSONObject>
with JSON response data when a loading has finished successfully. You will need to parse JSON data to show it in the UI. You will need to check the structure of the loaded JSON from the OpenWeather API web site or exercise 15.
Use getJSONObject
function to get main object with temperature. Use getJSONArray
function to get weather array with main condition and weather icon.
1 2 3 |
|
Get city
, condition
, temperature
, time
and icon
url from the response data.
1 2 3 4 5 6 7 8 9 |
|
After that, set forecast text’s to textViews and load icon with Glide.
1 2 3 4 |
|
You will need to use AppWidgetTarget
class with Glide to get icon loaded to the home screen widget.
1 2 3 4 5 6 7 8 9 10 |
|
After that, you need to update widget to display a new content.
1 2 |
|
You can comment or delete template generated updateAppWidget
function, it will not be used.
Add Widget to home screen
Test and run the application in the emulator or the device. Close your application and press&hold finger in the home screen to activate device menu. Select Widgets and scroll down to find Weather App widget. After that, select Widget and drag & drop it to home screen. Select Widget from the home screen and resize it if needed.
You can launch the MainActivity by pressing a city name in the widget.
Tip
Yes, UI is very ugly right now. Try to modify it look Cool! - Be Innovative!
Refresh Weather Forecast
Icon
Add a new refresh vector asset to your project and widgets layout. You can follow this guide to add a new Vector Asset to your project: Add multi-density vector graphics.
Pending Indent
Add a new pending intent to your refresh image in onUpdate function. In other words, it can be used to refresh a new weather forecast.
1 2 3 4 5 6 7 8 |
|
Now a custom com.example.weatherwidget.REFRESH
action will be send to WeatherAppWidgetProvider
class with appWidgetId
data when user is pressing the refresh image in the widget.
Receive a custom message in Manifest
You need to edit project manifest intent filter add add com.example.weatherwidget.REFRESH
custom action.
1 2 3 4 5 6 7 8 |
|
onReceive
Above custom action can be determined in onReceive
function inside a WeatherAppWidgetProvider
class. Add a following onReceive
method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Now onReceive
function will be called, when a refresh image will be clicked on the home screen.
Note
OpenWeather will update weather forecast within a few minutes. Wait a few minutes and click a refresh image to get your weather forecast updated.
Test and push
Test your application in emulator, take screenshots and commit/push your project and screenshots back to JAMKIT/GitLab. Remember move your exercise/issue ticket from Doing to In Review in Issues Board and write your learning comments to issue comments.