Activity & Intent

Objectives

The objective of this practical work is to discover how to link several Activitys using Intents.

We will continue to develop the project started last time.

In this lab, we will create a very basic interface to look up exchange rates: we will add a new button to last week’s Activity to launch a new Activity that displays exchange rates loaded from a service. (As a first step, we’re going to use a hard-coded JSON file in our application).

This is not necessarily the most elegant interface, but it will give us some experience with Activity and Intent. We will keep the interface from last time by adding a button to configure the rate. When the user types this button, we’ll switch to a new Activity to choose the currency and therefore automatically configure the rate.

This new CurrencyChooserActivity (or whatever) will have two columns of radio buttons: the source currency, and the target currency. Here is an example:

Simple layout: Currency Converter

To help you create this kind of layout, don’t forget :

  • A RadioButton is a subclass of Button.
  • A RadioButton must be in a RadioGroup.
  • A RadioGroup is a subclass of LinearLayout (vertical by default).
  • Feel free to consult the previous lab to remind yourself how to create rows and columns, buttons and text fields.

Create a new Activity

Add a new Activity to your project (e.g., with File -> New …). You can call it something like CurrencyChooserActivity. In its XML layout, create the interface for your chooser, in the spirit of the interface above.

Load the JSON

As a first step, we will hard-code the conversion rates directly into our application. Of course, these rates evolve, so we will later load them through the magic of the interwebs.

Add the rates as a resource

Download this file and put it as a raw resource in your project. To do this, you will need to create a new resource folder for this kind of data that the application will use. (This is the same general type of approach you would use to add other kinds of resources, such as images or sounds, to your application.)

Right-click on the res folder (in the project tree on the left) and choose New → Android resource directory. In the window that appears, change the resource type to raw, then press OK.

We now have a directory for raw resources where we can put files that will be put in our application when Android Studio compiles it. When the application is running, we can use the R magic class to refer to these files as R.raw.filename. All we have to do is put the file we downloaded in this folder.

Next, we will write a method that will look for this JSON file to load it and convert it into a JSONObject that we can use in our app. Create a method to load the JSON file. This code to create a string with the contents of a file you could be useful :

    InputStream inputStream = getResources().openRawResource(R.raw.rates_2017_11_02);
    StringBuilder stringBuilder = new StringBuilder();
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
        String line = null;
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line + "\n");
        }

        String jsonString = stringBuilder.toString();
        return new JSONObject(jsonString);
    } catch (IOException e) {
        System.err.println("Warning: could not read rates: " + e.getLocalizedMessage());
    } catch (JSONException e) {
        System.err.println("Warning: could not parse rates: " + e.getLocalizedMessage());
    }

    return null;

We will load this file when the CurrencyChooserActivity starts. What method did we see in class to do something when the activity launches?

Connect the two Activitys

Connect the buttons to the code to return from our Activity the exchange rate selected by the user. If rates is a JSONObject created from the above file, you could use rates.getJSONObject("rates").getDouble("GBP").

Load rates dynamically

The exchange rates are changing, so making them hard-coded is certainly not the right strategy. You could use a service like openexchangerates to load the updated rates, and you can do that if you want to create an account. But in this exercise, we will simulate this kind of service by loading the rates directly from the school’s local web server. This file will always be the same, but we won’t need a subscription to OpenExchangeRates (the source, by the way, of the file we use here).

Loading a web page versus a local file in Java is straightforward:

    URL exchangeRatesURL = new URL("https://.../rates.json");
    InputStream inputStream = exchageRatesURL.openStream();

Modify your code to load the JSON file from this URL instead of the hard-coded resource to see how easy it is. Or is it?

What do you notice?

In fact, any action over the internet is forbidden from the main thread.

Use Executor.

We will use Executor to handle this. To do this, simply create an Executor that will start loading JSON. Once loaded, the task should update the interface (e.g. by activating the convert (setEnabled(true)) button). See the course slides or the documentation on Executor.

Deliverables

Turn in your solution using the turn-in site by the end of the day on the date displayed. It will be noted on a bonus-malus scheme. (NB: “end of the day” means before I download the projects the next morning).