Web-enabled apps - Hello App Inventor!: Android programming for kids and the rest of us (2015)

Hello App Inventor!: Android programming for kids and the rest of us (2015)

Chapter 12. Web-enabled apps

You’ve already seen that App Inventor lets you connect with other people using text messages (see chapter 6). In this chapter, we’ll look at other tools that let you send and receive information, this time using the internet. You’ll see how you can show pages from websites, read information from online sources, and store data in the cloud using the WebDB component.

You’ll need a data connection to use these features on your phone—so that means either a Wi-Fi connection or a phone network data connection. Most people pay (or have a monthly data allowance) for their phone’s data connection, so we suggest using Wi-Fi while you’re playing with these features—and if you’re using a data connection, please check with whoever pays the phone bill first. We’ve tried to use examples of websites and services that will be around for a while, but it’s always possible that a service will change or disappear. If that happens, let us know on the Manning online forum for this book.

You’ll start by looking at how each of the components works with some simple examples. We’ll also make suggestions about how you could use these features in the apps you’ve already created.

Browsing the web

App Inventor offers two options for viewing the World Wide Web:

1. WebViewer component—This option displays web pages in your app. The WebViewer uses a mini browser that is part of App Inventor. It doesn’t have lots of functions like you might be used to in Chrome, Firefox, Safari, or any of the many other browsers you can use. But it’s fine if all you want to do is browse and navigate some web pages.

2. ActivityStarter component—This option jumps out of your app and displays web pages in a web browser installed on your phone. Using ActivityStarter allows the user to view the web page in whichever app they choose, so they get all the functions they’re used to. It’s also possible for you to provide no choice of app and to specify exactly which app should be used—but if the user doesn’t have the app on their phone, it may cause an error (so we don’t recommend doing that). The user returns to your app by quitting the web browser app.

The advantage of the WebViewer component is that it’s simple and your app stays in control of the screen—the user isn’t going to get lost in other apps that are open. The advantage of the ActivityStarter component is that the user can choose the web browser app that they’re most used to—and it will have more features than the WebViewer, such as the ability to bookmark a web page.

Let’s take a look at the two options in practice.

Using WebViewer

To set up the components for a WebViewer test, follow these steps:

1. Set up a new app, and call it TestWebViewer.

2. Set Screen1.Title to “WebViewer Example” and Screen1.ScreenOrientation to Landscape.

3. Add a HorizontalArrangement with five buttons, as shown:

4. Add a WebViewer component from the Palette’s User Interface section.

5. Set WebViewer1’s properties as shown. In addition, set WebViewer1’s Width and Height properties to Automatic.

You’ve finished the basic user interface for a web browser. You could improve it by, for example, including a text box where the user could type their own web address (URL). But it’s unlikely that a user would choose to use the App Inventor WebViewer for casual browsing; it’s better suited to providing a specific link to a web page you direct the user to. For example, you could

· Provide additional information for a game you’ve made, such as help, hints, and tips

· Link to the Google Play Store, where you might have other games for sale

· Set up an online survey to find out what users think of an app (for example, using Google Docs or SurveyMonkey)

Learning Point: Uniform Resource Locator (URL)

The correct computer science name for a web address is a uniform resource locator or URL. A URL like http://www.manning.com/beer contains three elements:

· http:// stands for HyperText Transfer Protocol and means you’ll be viewing web pages with hypertext—or web pages with links.

· www.manning.com is the domain name—a unique address of a computer that you want to access (the .com tells you it’s a company).

· /beer/ is the pathname of the file you want to view, just like the directories on your computer at home.

When a URL ends in a filename like /instructions.html, that file is retrieved. If the address ends in a forward slash (/), the app looks for a file called index.html in that pathname.

If you preview the app, you’ll see the web page for this book appear on your screen—and you can navigate between pages by clicking hyperlinks. But the buttons you made don’t do anything yet. Add the code blocks for the buttons as shown next. As you can see, the WebViewer includes ready-made functions for browsing, which makes it easy to code the navigation buttons:

Here’s how the app looks on a phone. You can pinch with two fingers to zoom in and out of the web page:

There are a couple of limitations to the browsing experience:

· The buttons scroll with the web page—so if you want to use them, you have to scroll back to the top of the screen.

· If the user presses the phone’s Back button (rather than the Back button you’ve created), the app quits. There is a workaround for this in chapter 14—see the Zombie Alarm app.

It’s also possible to change the current web page in the blocks using the GoToUrl block. In the example, we’ve set the web page to the App Inventor home page by hard-coding the web address into a text block. You could just as easily include a text box in the app as an address bar and use whatever the user types into it as the input for WebViewer1.GoToUrl. Now let’s look at the more flexible ActivityStarter component.

Using ActivityStarter

To set up the components for an ActivityStarter test, follow these steps:

1. Set up a new app, and call it TestActivityStarter.

2. Set Screen1.Title to “ActivityStarter Web Browser Example”.

3. Add a Button, an ActivityStarter (from the Connectivity Palette group), and a Notifier (from the User Interface Palette group).

4. Set the ActivityStarter properties as shown next.

To activate the ActivityStarter, you use the block call ActivityStarter1.StartActivity. You could do that from the OpenBrowserButton.Click event, like this.

But you’re about to take the user out of your app and into their browser, so you add the Notifier to provide a warning and tell them how to return to your app once they’re finished. Here’s how the sequence will work:

From this sequence, you can work out that the Button.Click event opens the Notifier, and then the Notifier.AfterChoosing event triggers the ActivityStarter. Here are the blocks:

Your app should now launch a web browser successfully—give it a try. ActivityStarter is versatile and can launch other apps such as the camera, Google Maps, and even other apps you’ve written. Also, if you enter a URL to a specific resource related to an app, Android will present more options in the app list. For example, if you have the YouTube app installed and you use a YouTube URL, then you’ll have the option to view the video in your browser or YouTube app. There’s full documentation about how to do this on MIT’s App Inventor website here:http://mng.bz/0x89.

Using data from the web

WebViewer and ActivityStarter can help you access whole web pages, but what if you just want to extract some data from the web to use in your app? Maybe you want to know the temperature forecast at a location for a fashion app that gives you options for what to wear that day. Lots of web services out there provide this kind of data in machine-readable form that an app can use, as well as in human-readable web pages. For example, lots of weather sites provide web pages of weather forecasts and maps—but if you know how, you can access the data directly and use it in your own apps.

You can access this data using an application programming interface (API). You can think about it this way: when you request a web-page weather forecast, you’re asking for text, graphics, links, maps, and so on, all neatly packaged in a nice, easy-to-read format (you hope). When you request weather data via an API, you’re saying, “Just give me the data—I don’t want all that other fancy stuff! I want temperatures, wind speed, atmospheric pressure, cloud cover, and those kinds of things.” When you request data like this, we say that you’re making an API call. There are lists of publicly available APIs, such as that at www.programmableweb.com.

API keys

Most public APIs ask you to apply for a key to use the API—you provide an email and some other details, and you get a key (which is actually a code) sent back. You don’t have to do this for web-page browsing—so what’s the difference? When you request a web page, it’s sent to your machine, and then you spend some time reading it before you ask for the next page. This doesn’t put much strain on the web servers (the computers that hold the web pages). With APIs, you’re using a computer (smartphone) to request data—and computers can make lots of requests quickly. If your computer got stuck in a loop and made too many requests too quickly, the web server might crash. An API key limits the number of requests any one computer can make in a certain time, so you can’t crash the servers.

Weather Watch app

PURPOSE OF THIS APP

World Weather Online is a business that provides weather forecast information. You’re going to use their free local weather API to tell the user today’s weather forecast for any town or city.

APP RATING

ASSETS YOU’LL NEED

You’ll need to create a World Weather Account and request a key. We’ll tell you how.

WeatherWatch

Screen1 properties

Title: Weather Watch

Components

What do I rename it?

What does it do?

What properties do I set?

TextBox Palette group: User Interface

LocationTextBox

Where the user enters the location for the weather forecast

Hint: “Enter a location.”

Button

GetWeatherButton

Starts the API call

Text: “Click for weather”

Label

WeatherLabel

Displays the weather forecast description

Text: “Today the weather will be...”

Label

RainfallLabel

Displays the rainfall in mm

Text: “Rainfall –“

Label

FarenheitLabel

Displays the maximum and minimum temperatures in farenheit

Text: “Farenheit –“

Label

CelsiusLabel

Displays the maximum and minimum temperatures in celsius

Text: “Celsius –“

ListPicker

WeatherList-Picker

Helps you test the app by showing all the weather data in a single list

Text: “List of all weather data”

Label

WWOLabel

States an attribution to the World Weather Online service. This is a legal requirement

Text: “Powered by World Weather Online”

Web Palette group: Connectivity

Web1

A non-visible component that provides functions for accessing web pages and services

Default

1. Request an API key

First head to www.worldweatheronline.com and register for an account. Sign in, and request an API key for the Free Local Weather API. At the time of writing, you can do all this directly from www.worldweatheronline.com/free-weather-feed.aspx. The key will be a string of 24 characters. In the examples that follow, always make sure you’re using your key.

2. Work out the API call

World Weather Online lets you try out API calls from your browser using your key. This is really helpful for a beginner. Head to this page: https://developer.worldweatheronline.com/page/explorer-free.

A window opens where you can change lots of API options. There’s an explanation of each option on the right side of the page. Under the options, you can see the API call (which looks like a web address) and an example of the data that would be returned.

In the app, the user will set the location using a text box, but for now you’ll pick a city name to see how it works. We chose Orlando because it’s a unique city name (and it makes us think of summer holidays). After some experimentation, we figured out the best way to format the output so that App Inventor can handle the data easily (there are lots of other ways to do it). The table on the next page lists the parameters you need to set.

Parameter

Value

Explanation

Q

Orlando

The weather forecast location.

format

CSV

Comma-separated values. The data will be output as a long string of text with a comma between the data items. App Inventor has some handy blocks that can automatically turn this into a list.

num_of_days

1

Gives you a forecast just for today. Increasing the value gives you multiple forecasts (one for each day).

cc

No

When set to Yes, gives you the weather right now as well as the forecast. To keep things simple, set it to No.

show_comments

Yes for testing No for the app

Comments help explain the data, which is handy when you’re figuring out the API call. Later, when you’re ready to use the API call in App Inventor, you’ll set this to No to strip out the comments and simplify the data you receive.

If you enter these values and click the Try it! Button, you should see that the API call looks like this:

api.worldweatheronline.com/free/v1/weather.ashx?q=orlando&format=

CSV&num_of_days=1&cc=no&show_comments=yes&key= your key goes here

The only difference is that you’ll see your key at the end of the call. To use the API call, you’ll need to include the protocol (http://) at the beginning of the call. See the Learning Point “Uniform Resource Locator (URL).”

You can break the API into two parts:

· http://api.worldweatheronline.com/free/v1/weather.ashx—The protocol and domain

· q=orlando&format=CSV&num_of_days=1&cc=no&show_comments=yes&key= your key goes here —The API call or query that encodes the options you entered:

o /?q=orlando —A query that asks for the weather in Orlando.

o &format=CSV —The format of the results.

o &num_of_days=1 —One-day forecast, for today.

o &cc=no —Don’t send the current conditions weather data.

o &show_comments=yes —Show additional comments.

o &key= your key goes here —Your API key.

If you run the API in a web browser, here’s what you get:

You can see that there is lots of weather data. If you can work out how to get the data into App Inventor, you can select the parts you need and display them in an app. You’ll give the user a description of the weather (weatherDesc), the minimum and maximum temperatures in Celsius (tempMinC, tempMaxC) and Fahrenheit (tempMinF, tempMaxF), and the rainfall in mm (precipMM).

Now that you know the API call works and understand the data, it’s time to switch off the comments in the API call so App Inventor only has to deal with the data. Change &show_comments=no so the API call becomes

http://api.worldweatheronline.com/free/v1/weather.ashx?q=orlando&format=

CSV&num_of_days=1&cc=no&show_comments=no&key= your key goes here

If you put this address into your browser, you’ll just see the weather data, like this:

3. Setting up the screen

Switch to App Inventor, and start a new project called WeatherWatch. Here’s the screen layout:

You have a new, non-visible Web element in the layout. This is what makes the API call to the internet and triggers a Web.GotText event when the data arrives back at the phone. You can also see a label that gives credit to World Weather Online for providing the data. This is important, because you can’t just claim data as your own; it’s only fair and legal to say where it came from. API providers usually tell you in their terms and conditions what you need to do if you use their API. This usually includes the following:

· Keeping your key private —It’s OK to use it in an app, but don’t tell the user what it is.

· Limiting the number of API calls you make —World Weather Online asks that you don’t exceed 12,000 requests per day.

· Crediting the API provider —This generally means a text label, and sometimes a logo and web link.

When the user types a word and clicks GetWeatherButton, you make an API call string that follows the Orlando example. You can make the string using a standard Text join block. At first we tried this:

This worked fine for most locations, but if the location was “San Francisco” the app generated an error message. What’s the difference between “Orlando” and “San Francisco”? (The answer isn’t Mickey Mouse or the Golden Gate Bridge.) San Francisco has a space in the middle, and it turns out that API calls (and web pages) need space characters to be specially encoded. You could do this by hand, but App Inventor has a block that does it for you; just add a Web1.UriEncode block like so:

Now you can use the API call string above by setting Web1’s URL property—that’s the address the Web component will access. Carrying out the API call is a two-step process:

1. Use a function called Web.Get that asks the website at the URL for the data and then waits until something comes back.

2. When Web1 gets some data, it triggers a Web.GotText event. Then you can do something with the data you’ve received.

It’s important to understand that accessing the web has this built-in delay. You ask for something, wait, and then, when it arrives, do something—it’s a bit like waiting for a mailman to deliver a parcel before you can do a project. Here are the blocks to make the call:

The result of calling Web1.Get is a list of the data you saw in your browser. You’ll take this list and put it into a list variable called WeatherList. Then you can select the items you need. This looks complicated at first, but a little trial and error helps—that’s why you added theListPicker at the bottom of the screen, as an easy way to view the data that has been downloaded.

Here are the blocks that take the returned data and store it in an App Inventor list:

Run the app now:

1. Type a city (we typed orlando).

2. Click the Click for Weather button.

3. Click the List of All Weather Data button at the bottom of the screen.

You should see a list like this. Each line in the list is an item of weather data—it looks like it’s worked!

Now you just need to select the right elements from the list (description, temperatures, rainfall) and display them in the text labels. Here are the blocks to complete the app:

Taking it further

1. Display a weather icon: change the image depending on the maximum temperature and rainfall forecast.

2. Use the phone’s GPS coordinates (latitude and longitude) as the location for the forecast.

3. Display a different weather icon depending on the weather condition code. See the list here: www.worldweatheronline.com/feed/wwoConditionCodes.txt.

Storing and sharing data in the cloud with TinyWebDB

Your App Inventor apps are stored in the cloud, which means they’re saved on web servers that are connected to the internet. The advantage of this is that you can access them from any computer without worrying about saving them to flash drives. Of course, you can download them to your own computer, too—and that’s always a good idea, just in case those web servers fail. In addition to being able to access your apps and data from any computer or smartphone, cloud access also lets you share things with the world—a Facebook update can be seen by all your friends, for example.

In chapter 11, you saw how you can use the TinyDB component to store data on your phone so it’s available even after the user has quit the app and restarted it. App Inventor has an almost identical component called TinyWebDB that stores data in the same way—but to a web server in the cloud. You’ll use it to enhance the My Dream Recorder app so that you can store your most recent dream online—and your friends can read about it using an app called Dream Sharer.

Learning Point: Staying safe online

The examples you’ve seen so far involve getting information from the internet, but in this app you’ll be posting information to the internet. Before you do, there are two things you need to know about TinyWebDB:

· The information you send and receive over TinyWebDB needs a private tag, but don’t assume it’s secure. Don’t post personal details like names, addresses, telephone numbers, or passwords.

· Once you post an item online, you should assume it’s there forever as part of your digital footprint. So be nice, and don’t post anything you wouldn’t want your parents, teachers, or future boss to see!

Limitations of the TinyWebDB test service

For this next app, you’re going to use a test service for TinyWebDB that is provided by App Inventor. This is the default service for any new app, and it’s useful for testing, but it’s shared by all App Inventors and only has space for 1,000 entries. Once these are used up, it starts overwriting previous entries. That means if you store data on the service, it might not be there long. But once you’re happy that your app works, you can set up your very own TinyWebDB service that only you can use. For instructions on how to do this, head over to the App Inventor site and search for “Creating a custom TinyWebDB service”; at the time of writing, the pages were here (but this may change in the future): http://mng.bz/fo9Y.

Dream Sharer app

PURPOSE OF THIS APP

In the My Dream Recorder app, you stored your most recent dream text in your smartphone. The idea in this enhanced version is that your friends can also use My Dream Recorder, and then you can all use a new app called Dream Sharer to see everybody else’s dreams, too.

APP RATING

ASSETS YOU’LL NEED

None.

In the original version, you stored your dream text in TinyDB with a tag called Dream-description. That worked fine because you were the only person using it. But if you and all your friends use the same tag online, they will overwrite one another, and you’ll only ever be able to retrieve the most recently posted dream. To solve this, you’ll first make some modifications to the original My Dream Recorder app by letting each user invent their own username that will then be used to tag their dream:

1. Load the My_Dream_Recorder project (from chapter 11), and save the project as My_Dream_Recorder_Web.

2. Switch to Dreamscreen, and add the following objects:

Retrieving the username and dream

When the user opens the app and enters their password, you want to see if they have already used the My Dream Recorder app on this phone. If they have, you’ll retrieve their username so they need not enter it again. Then you’ll retrieve the last dream recorded against that username. WhenDreamscreen is initialized, do this:

1. Read the value of the TinyDB data tagged with StoredUserName, and store the result in a variable called username.

2. Change the Text property of UNTextBox to display the username.

3. Dreams are recorded with the username tag, so get the value of the TinyDB data tagged with the value of username, and display it in Dreamdescription.Text (just like you did in the original app—only the tag has changed).

This means if the user has used the app before, their previous username and dream are displayed. If they haven’t used the app, they see an empty username text box, and no dream is displayed. Here are the blocks:

Checking that a username has been entered

In the original app, when the user clicked DreamButton, the speech recognizer started up. In this new version, you’ll first check that a username has been retrieved or entered (because if there’s no username, you have nothing to tag the dream with). To do this, add an additional if ... else block that checks that the username variable isn’t empty:

The user can change the username at any time by clicking ChangeUNButton. The username variable is updated and stored with the TinyDB tag StoredUserName. The next time the user accesses the app, this username is automatically retrieved by the Dreamscreen.Initialize event.

The final changes to My Dream Recorder are as follows:

1. Change the tag for the stored dream so it can be retrieved using username.

2. Add a block to store the dream data to the cloud using TinyWebDB.

This means if the user records a dream, it’s both stored locally on their smartphone and uploaded to the TinyWebDB server (as long as their phone has an internet connection).

Dream Reader

As the final step, you need to create a simple app to read from the cloud the dream data that your friends have uploaded:

1. Set up a new app, and call it Dream Reader.

2. Set Screen1.Title to “Dream Reader”.

3. Add the following components:

As long as you know your friend’s username, you can retrieve the text of their dream from TinyWebDB. This is a two-step process, just like with the Weather Watch API:

1. Request the data using a call to TinyWebDB1.GetValue. The tag you’re searching for is the username that the user typed in UNTextBox.

2. You wait until some data comes back, and when it does, the TinyWebDB1.GotValue event fires. It holds the data retrieved in a local variable called valueFromWebDB. You can then do something useful with the data, like display it onscreen in the Dream-Label you created.

The two apps should now work together. Use My Dream Recorder to save your dreams to your phone and the web. Use Dream Reader to see your friends’ most recent dreams, once you’ve swapped usernames.

The idea behind this app could also be used to create your own instant-messaging app or even to make simple online games. You could also use TinyWebDB to create a shared online high-scores list for a game.

What did you learn?

In this chapter, you learned the following:

· How to display web pages using the WebViewer built-in browser or through other apps via the ActivityStarter

· The different parts of a uniform resource locator (URL), also called a web address

· That some websites let you access raw or unformatted data using an application program interface (API)

· How to process the results of an API call to extract just the data you need

· That getting data from the web is a two step process—1) request the data, 2) then wait until it’s returned—triggering a GotValue event

· How to store and retrieve data from the cloud (web servers) using TinyWebDB

Test your knowledge

1

What are the advantages and disadvantages of WebViewer versus ActivityStarter for accessing web pages?

2

Why do some websites ask you to apply for an API key before you can make an API call?

3

Here’s part of an API query from api.worldweatheronline.com. What data do you think it will return?

?q=Liverpool&format=json&date=today&key=1234567890

4

For what reasons might a user want to store the same data both locally on their phone and in the cloud on a web server?

5

Why is it a good idea to set up your own TinyWebDB service rather than use App Inventor’s test service?

Try it out

1

Create a webquest that takes users on a tour of websites about a single topic, such as Atlantis.

2

Create a quiz where the questions have hints that are linked to helpful websites.

3

Try using ActivityStarter to open different sorts of web-based applications like Youtube videos, Facebook, or Twitter.

4

Browse the list of public APIs on www.programmableweb.com. Apply for a key for an API that looks interesting, and then write an app to access the data.

5

Try writing a simple multiplayer text-based, two-player game using TinyWebDB, for example Hangman or Battleship.