Institute of Computer Science
  1. Courses
  2. 2022/23 fall
  3. Mobile Application Development (LTAT.06.021)
ET
Log in

Mobile Application Development 2022/23 fall

  • Main
  • Lectures
  • Labs
  • Homeworks & Assignments
  • Task submission
  • Extra Materials
  • Best Practices
  • Results
  • Quizes
  • Projects
    • Presentations & Report
    • Teams & Topics
    • Grading & Submission

Lab 8 - Invoking web services and parsing JSON, Cloud Messaging

Table of contents

  • Introduction - HTTP requests with Ion
  • Base Project
  • 1. Basic HTTP request
  • 2. Weather Service
    • 2.1 Getting the API key
    • 2.2 Making the request
    • 2.3 Handling the JSON response
  • 3. Firebase Cloud Messaging

Introduction - HTTP requests with Ion

In this lab we'll create an app which uses a HTTP client to access some web services. The data is returned by the server in a specific format, which the client has to parse before it can do something useful with it.

We will use the Ion library to make HTTP requests. Ion is a 3rd-party library which:

  • performs the requests in the background for you
  • provides some helper methods which map the HTTP response into different types: String, JsonObject, Bitmap, etc.
  • invokes code specified by a callback function once the response is received

Take a look at the Ion Github page to see examples of how requests are made.

Alternatives to Ion include Volley and OkHTTP. Android also has built-in capabilities for HTTP requests but they are generally more verbose to use.

0. Base project

Download and open the base Android Studio Project. The project has some simple UI definitions (2 activities) to speed up the lab for you.

1. Basic HTTP Request - List of Cities

The first task is to get a text file which lists cities along the coast of the Baltic Sea. The file is hosted on the UT network, at https://kodu.ut.ee/~jaks/baltic_sea/cities.txt

  1. Refer to the Ion documentation & examples and perform the request to load the above URL with Ion, using asString() as the return format.
    • To add Ion to your project: implementation 'com.koushikdutta.ion:ion:3.1.0'
  2. Split the response String into a list using \n character as the separator. You don't have to separate the city from the country name.
  3. Using the existing addToListView() method, add a Button for each individual city to your Apps UI
    • addToListView() sets up a click listener to a function openCity(..). Finish the implementation of openCity, and notice the comments under that

2. Getting Current Weather for a City using a JSON weather API

2.1A OpenWeatherMap API

  • We will use a Weather API service called OpenWeatherMap. Please sign up for the free version of the service https://home.openweathermap.org/users/sign_up .
  • When your account is created, navigate to the API Keys section of the webpage.
    • If necessary, generate an API Key
    • Note it down somewhere, we will need it to make requests to the API.

2.1B WeatherStack API

  • We will use a Weather API service called WeatherStack. Please sign up for the free version of the service https://weatherstack.com/signup/free .
  • When your account is created, you will see your personal API Access Key at the dashboard. Note it down somewhere, we will need it to make requests to WeatherStack.

2.2 HTTP GET request parameters

For simple HTTP GET requests, query parameters can be passed like so:

  • http://www.example.com?param1=foo&param2=bar , where a list of key-value pairs with format key=value are separated with a &, and the ? symbol separates the base URL from the parameters

In part 1, we did not use any request parameters. For the Weather Service, we will need to add our API key as a parameter, for example. To know the exact parameters and their names the web service expects, we should study their documentation.

  • For OpenWeatherMap documentation, focus on the "Current" sub-part of the API, find the documentation here.
  • WeatherStack API documentation can be found here. Focus on the "Current Weather" examples.
  • Study the API: find an example response JSON, identify which parameters are required
  • OpenWeatherMap notes:
    • We want to pass the city name for the location, not coordinates (locate the Geocoding-related sub-part of the examples)
    • Note how the appid and q parameters are expected to be passed to the request URL.
  • WeatherStack notes:
    • Note how the access_key and query parameters are expected to be passed to the request URL.
    • Note, free WeatherStack plan doesn't support HTTPS, only HTTP
  1. In onCreate of CityDetailsActivity, perform a request to fetch that city's current weather.
    • You can directly use the city name along with country in the same format you got it from part 1, no need to split it further.
    • Specify Ion to handle the result as a Json with asJsonObject(), instead of asString()

2.3 Parsing Json response

  • Now, we want to extract certain information from the result (temperature, wind information, weather descriptions (e.g. "Mist"), humidity etc). Ion uses the Gson library for working with the Json format.
    • You can parse with Gson by using MyJsonObject.get(<<memberName>>) and then calling asJsonObject, asJsonArray, asString, asLong, etc, based on the structure of the Json that has been returned.
  • Example: By knowing the response structure (study the example response of the API documentation), we can assemble code to extract temperature value as a float, like so (just generic exmaple):
<<myResponseJson>>.get("current").asJsonObject.get("temperature").asFloat
  • Update the UI (TextViews, etc) to display the weather of the city
  • The APIs also have an "icon" in the response. Try displaying the icon in an ImageView with Ion
    • Note: For OpenWeatherMap, you need to assemble the full URL: val iconurl = "https://openweathermap.org/img/w/" + iconcode + ".png"

3. Firebase Cloud Messaging

Firebase Cloud Messaging is a service which allows to send messages & notifications to your app from the internet, even if its not running. In addition to such downstream messages (from cloud to the mobile), it also supports upstream messages (client to cloud), which then may be further forward to other mobiles, and so forth.

  • Set up Firebase for your project. The process is very similar as we did for Firebase cloud storage.
    • Option A: The easy way of setting it up is to use Firebase Assistant within Android Studio (Tools -> Firebase -> Cloud Messaging ) - follow the steps there.
      • This adds the necessary dependencies and google-services.json file to your project automatically
    • Option B: Do it in the browser in Firebase Console
  • Before proceeding, make sure you have the correct google-services.json file in your project and the additional entries in the project-level build.gradle file, such as classpath 'com.google.gms:google-services:4.3.10'
  • Once you have the basic Firebase project set up and linked to you Android Studio project, add the Cloud Messaging dependency:
    • implementation 'com.google.firebase:firebase-messaging-ktx:22.0.0'

We can now follow the official firebase guide for getting started, but we will not be focusing on all steps.

3.1 Getting a registration token

This token uniquely identifies the Android device. In order to send push Notifications targeting specific clients (or groups of clients), we use this token as the identifier.

  • Start by acquiring the registration token, you only need to log the token, so you may simplify the code snippet provided in the example.
    • You can add the code to Activity onCreate().
    • Launch your app, you should be able to see the Token value being logged, mark it down.
  • Now close your application / put it in the background. We will try to send a notification to our app from FCM using the token.
    • Go to Firebase Console / Cloud Messaging, select ("Create your first campaign" (On old dashboard: "Send your first message").
    • Fill in a title (and description), then on the right you should see a button "Send Test Message).
    • In the modal window, enter your Token, then hit send
    • If you app was in the background, a notification should now appear. Clicking the notification takes you to your app.

Handling foreground messages

To handle messages while our app is running, we have to create a new Service that extends FirebaseMessagingService.

  • Create the Kotlin class which does this.
  • If you manually created the class (instead of Android Studio new Service wizard), add it to the manifest file.
  • Add an intent filter to the service definition in manifest
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
  • Override the services its' onMessageReceived method in the Kotlin file.
  • Try to log the message contents, using the token-based test message as we did above.
  • The Notification - related data can be obtained with remoteMessage.notification.XXXX
  • The extra key-value data attached to the notification can be obtained with remoteMessage.data
  • Try sending another message with extra attached data.
    • Note: In Firebase console, you can do it with New Campaign -> Notification.
    • Tip: If the messages don't seem to arrive, try using a fixed time value instead of "Now" for the Scheduling of the notification.

Troubleshooting

If you are getting an exception like java.lang.ClassNotFoundException: Didn't find class com.google.android.gms.security.ProviderInstaller" on path: DexPathList

try adding the following to your Activity onCreate(): Ion.getDefault(applicationContext).getConscryptMiddleware().enable(false)

Optional: Weather Service Units

Based on the supported query parameters, ( https://weatherstack.com/documentation ), see if you can update the query so that the user can choose the units (imperial vs metric)

  • Institute of Computer Science
  • Faculty of Science and Technology
  • University of Tartu
In case of technical problems or questions write to:

Contact the course organizers with the organizational and course content questions.
The proprietary copyrights of educational materials belong to the University of Tartu. The use of educational materials is permitted for the purposes and under the conditions provided for in the copyright law for the free use of a work. When using educational materials, the user is obligated to give credit to the author of the educational materials.
The use of educational materials for other purposes is allowed only with the prior written consent of the University of Tartu.
Terms of use for the Courses environment