Introduction

Reassessment 2 involves the creation of a client-server application. The client is an android app, whilst the server will be written in java. In this first part, you will be writing the android app, which, for now, will connect to a server that I have written. Later, in the second part, you will replace my server with your own. For students resitting, whose unit marks are to be capped at 40%, I would recommend working on the android client only, and skipping the second part.

When visiting places that you aren't quite so familiar with, it can sometimes be difficult to figure out how to get around via public transport. You are going to create an android app that can sense its location and find out the names and distance to the nearest railway stations, airports and ferry terminals. You will be working with the android geolocation API, and the standard java/android networking and JSON parsing libraries.

I have found a list of the location of various types of mass transit stations and ports around the world [1]. The locations in this list aren't quite as accurate as those in the official government lists in the UK [2], but the locations in the government statistics are expressed in British National Grid format, rather than the international latitude/longitude format used by GPS devices, and android.

The Web Service

Although you will be replacing the web service in the second part of Reassessment 2 you will, for now, be using a web service that I have made available to you. The web service is hosted on a virtual machine I rent in an American data centre, to ensure it will be accessible for you from off campus.

The web service is accessible using the URL http://zebedee.kriswelsh.com:8080/stations and expects three parameters as part of the URL query string. The parameters are as follows:

  • latitude The latitude of the location to search using.
  • Longitude The longitude of the location to search using.
  • T ype Either "station", airport, port, or all. Controls the type of search performed

For example, to find the railway stations closest to my office, the following URL would be used: http://zebedee.kriswelsh.com:8080/stations?latitude=53.472&longitude=-2.244&type=station

Figure 1: JSON data returned by web service: see image.

The web service returns the information on the five nearest results in a JSON format: an array of objects, each of which has a number of properties, including a sub- object for the location. All of the data is returned as a String, even the numbers.

Many locations do not include an altitude

Figure 1, left, illustrates the format of the data for a railway station and an airport. The data has been formatted using a JSON pretty printer for readability.

The timezone is specified as an offset in hours from UTC, the altitude is in feet, and the daylight savings time is encoded as E/A/S/O/Z/N (None) or U (Unknown).

Some properties, specifically the "iata" and icao properties, are applicable only to airports, so be sure to structure your parsing code in such a way that it can handle results of any type, or even a list of mixed station types.

You should try a few different searches, by manipulating the latitude/longitude/type parameters given to the web service, to get a feel for how it works before starting implementation.

Geolocation Functionality

Your app needs to track the device's location, so that when the user clicks the search button the app will know what latitude and longitude to supply to the server. Use the android Location service and the LocationListener interface to have your app receive updates every time the device's GPS chip informs the phone of a new location.

Be sure to avoid performing the search automatically after a location update. Network requests are both battery and data-intensive, and GPS chips on real devices can supply updates once every few seconds.

Networking

Your app will need to contact the web service when the user presses the search button. It will need to create the correct URL, using the device's current location (i.e. the latitude and longitude stored in the variables from your geolocation code) and the user's specified search type, contact the server, and parse the received JSON data.

If you have not (or have not yet) implemented threading, you will need to include the following code snippet in your activity's onCreate() method. The code prevents android from throwing an exception if you attempt to perform a networking operation in the application's main thread.

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder( ) .permitAll().build();
StrictMode.setThreadPolicy(policy);

Try to avoid situations where UI events can "orphan" the network request, which is relatively expensive in computational and battery power.

Displaying Results

Your app will need some simple way to allow users to specify what type of transport to search for, as well as some way of displaying results. Most students will choose to use RadioButtons, and either a ListView or a TableLayout. You will need to remember to clear the list/table when the user presses the search button, and as well as the information returned by the web service, your app should display the distance to each of the results.

The web service does not calculate the distance from the device to the retrieved stations/ports, Figure 1: Code Snippet to Disable Android Thread Checking and you will see a detailed explanation as to why in the second part of the assessment. So, to display the distance to a station you'll need to use the static Location.distanceBetween() method. Remember to round the result to the nearest meter.

Code Quality

Although your android app will require less code than you wrote for Assessment 1, the code itself may be quite complex. Thus, you will need to give some consideration to the best way to architect the code. What should be put in which method? How best to lay out the code so that it is readable, maintainable and understandable to someone unfamiliar with the codebase? How best to help a later reader with comments? You should write sensible and easy to understand code, which is commented with JavaDoc comments.

Mapping

The app would be considerably more useful if it displayed the nearby stations/ports to the user on a MapBox map. Ideally, the map should be zoomed to an appropriate level so that all five stations displayed to the user fit on screen simultaneously, whilst showing as much map detail as possible. The strongest solutions will use a custom map marker and name the station in the associated info window when clicking the marker. This section is intended to offer some additional challenge, going a little beyond what was covered in lectures.

Threading

The StrictMode workaround mentioned in the networking section is an ugly hack, and is not meant for use in production code. The correct way to handle networking in android is to use a background thread to perform the request, and to perform the UI updates back in the app's main thread. The AsyncTask class makes this more convenient. Modify your networking code to use an AsyncTask, and remove the StrictMode workaround.

Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.