Sie sind auf Seite 1von 89

Creating Apps

with App Inventor for Android

draft 1, 1/2010

Creating Apps with App Inventor for Android draft 1, 1/2010 David Wolber NOTE: This text is

David Wolber

NOTE: This text is under construction-- use at your own risk.

Table of Contents

Chapter 1: Introduction

4

Getting Started: Downloading Some Apps

6

Chapter 2: Building and Deploying an App with App Inventor

7

Introduction

7

Building the User Interface

7

Programming the App's Behavior

9

Instant Testing of the App

12

Download the App to Your Phone

12

Chapter 3: An App Is

15

A

App is a Recipe

15

An App is a Set of Event-Handlers

15

An App Consists of Event-Handlers That Can Ask Questions and Branch

17

An App Consists of Event-Handlers That Can Ask Questions, Branch, and Repeat

18

An App Consists of Event-Handlers That Can Ask Questions, Branch, Repeat, and Talk to Web Services

19

An App Consists of Event-Handlers That Can Ask Questions, Branch, Repeat, Talk to Web Services, and Remember Things

20

Chapter 4: Components, Properties, Events, and Functions

22

Components

22

Properties

23

Events

25

Functions

25

Summary

27

Problems

28

Chapter 5: Animation

29

Animated Objects

29

Timer Events

29

Moving an Object Periodically

30

Ball/Image Sprite Events

32

Reacting to Touch and the Ball Reaching an Edge

33

Variables

34

Randomness

37

Problems

38

Chapter 6: Conditional Blocks

38

If

and Ifelse Blocks

39

Sample: Calling a random friend from a set of

41

Summary

44

Problems

45

Chapter 6: Lists

45

Making a List

45

Selecting an Item

46

Using Length of List

47

Iterating Through a List: For Each

50

Getting Started

53

Example: Quiz App Version 1

53

Iteration 1: Questions and the Next

54

Iteration 2: Processing Answers

58

Summary

58

Problems

58

Chapter 8: Iteration

61

Computing the Sum of the First Three Numbers

62

Computing the Sum of the first N Numbers

64

A

Bug in the Program

65

Problems

66

Chapter 9: Web Services, APIs and Mashing Data

67

Mashups

71

Tweeting Big Stock Swings To Twitter

72

RSS

73

Creating Mashups

73

Twitter API

76

An App Inventor Twitter Client for Android

77

Problems

78

Chapter 10: Persistent Data

79

TinyWebDB

81

A

Quiz with Multiple Questions

84

Programming the Behavior of the "Teacher" Application

85

Processing the Entry of New Question-Answer Pairs

87

Summary

88

Problems

88

Appendix A: Setting Up

0

Chapter 1: Introduction

Programming is like magic to most people, and only a small percentage of humans ever try it. This is unfortunate, as there are many very creative people that don't even dream of applying their creativity, at least directly, to building software. Most people consider the apps they use on their computers and phones as beyond their control-- they are stuck with being consumers, and not producers, or even "customizers", of software. The software we now use would certainly be better if the tools for building it were accessible to more people.

There has been progress. The web started out as read-only-- only web masters could create web pages and most of us just "consumed" the information out there. With blogs, wikis, social networks, and Twitter, the web has now become a read-write web, and most everybody is now "part of the conversation".

However, there is still a large chasm in terms of producers and consumers:

though many now blog and create web pages, there are still few who know how to create apps-- software that displays information dynamically and can respond to user input and other events. Just as there is a digital divide, there is also a programmer divide that limits people's control over the devices they use.

Can this divide be breached? Can ordinary people be taught to program their computers and their phones? There are reasons to believe they can. Young people today are incredibly computer literate compared to the previous generations. They don't fear computing-- it is part of their lives from an early age. And they use computing hours upon hours a day. Thus, they are extremely motivated to have useful software and to be able to customize it for their own personal use.

Google is very interested in this question, and to explore it they have designed a new visual programming language, App Inventor, designed to allow people to program their phones. Here is Google's vision:

Mobile applications are triggering a fundamental shift in the way people experience computing and use mobile phones. Ten years ago, people "went to the computer" to perform tasks and access the Internet, and they used a cell phone only to make calls. Today, smartphones let us carry computing with us, have become central to servicing our

communication and information needs, and have made the web part of all that we do. Ten years ago, people's use of computing was largely dissociated from real life. With the ubiquity of social networking, online and offline life are becoming fused. (Our) exploration is motivated by the vision that open mobile platforms like Android can bring some of that same change to introductory Computer Science, to make it more about people and their interactions with others and with the world around them. It's a vision where young people—and everyone—can engage the world of mobile services and applications as creators, not just consumers. Through this work, we hope to do the following:

• Make mobile application development accessible to anyone.

• Enhance introductory learning experiences in computing through the vehicle of Android’s open platform.

• Encourage a community of faculty and students to share material and ideas for teaching and exploring.

From Google Research Blog:

The App Inventor visual language makes developing Android apps considerably easier than with a traditional programming language. With App Inventor, everything you can do is visible, and you program by piecing together blocks representing phone functionality and data. It is similar to the Mindstorms blocks language for programming Lego robots, and the Scratch language for creating web animations, but you program your phone instead.

The key from a learning perspective is motivation: people are significantly more motivated to learn programming and computer concepts because they are building something fun that they can use in their every day life. In teaching App Inventor, I've been amazed at how hard students have worked-- their motivation level has been significantly higher even any beginning course I've ever taught. My belief is that they are more motivated because they are building "real" software-- software that can benefit their everyday lives.

This book steps you through the process of building Android apps using App Inventor. We'll begin with some simple apps-- an app that speaks what you type, and an app that moves a ball around the screen. But rather quickly we'll progress to more complicated apps and you'll be building games, educational software, Twitter clients, and maybe even the next killer app for the Android platform!

Getting Started: Downloading Some Apps

The Market The Android Market has thousands of apps, many of which are free to download. You can search for specific keywords to find an app, and you can read a blurb about the app and see reviews of it before downloading. Before embarking on our journey to learn programming, definitely download some apps and become acquainted with how Android apps look and behave.

Barcode Scanner There are two specific apps that we'll use in the programming lessons. The first is a barcode scanner. This is required because when you build an app, App Inventor creates a barcode for the app. With an Android barcode scaner, you can scan the barcode in order to install the new app on your phone. Very cool!

One popular barcode scanner is from ZXing. If you go to the Market and search for it, you'll find it. Just step through the installation instructions and you'll have a barcode scanner. For fun, try scanning the ISBN barcodes of some books to see what the scanner does with them.

Text To Speech The first sample app we'll create will speak the words the user types. For this, you need to have Text to Speech (TTS) library code on your phone. With TTS, your apps can speak words that have been typed in or sent as a text to your phone. You can download a TTS app named TTS Service Extended at the Android Market.

Once you've downloaded it, open the app and click on menu to choose a Default Engine. If you don't choose an engine, the app won't work (there's no default setting unfortunately). You can also change the default language and speech rate.

Once you've installed it, test it by clicking on the App to start it, then clicking menu and choosing "Listen to a preview". Then try changing to a different language to see what happens.

Chapter 2: Building and Deploying an App with App Inventor

This chapter describes App Inventor and steps through the task of creating, testing, and deploying a mobile app.

Introduction

Programming in App Inventor is a two-step process: you first design the user interface for the app-- how it will look, then you design how the application will behave.

These two tasks are performed in separate windows. The first window is the Component Designer. You use it to choose and place the buttons, text boxes, images, and other components that will appear on the phone when your app is run. The second window is the Blocks Editor. You use it to define the behavior of your app-- how it should respond to events such as the user pressing a button.

Building the User Interface

We'll start with a simple example: an application that let's the user enter some words, then speaks the words when the user clicks a button. Though simple, this application illustrates the basics of App Inventor and the basic structure of a mobile app.

To build the application, first open the component designer:

The left side palette has all the components that can potentially be added to an

The left side palette has all the components that can potentially be added to an application. The left-middle panel is the surface representing the way the phone's screen will appear when the application runs. The programmer drags from the left to the left-middle to specify the components of a particular application.

For the sample app, you'll need three components: a TextBox where the user can enter the words she wants spoken, a button for the user to click, and a TextToSpeech component that will do the work of actually speaking the words.

The TextBox and the Button are part of the Basic palette, which is open in the snapshot above. There are a number of other component palettes. The TextToSpeech component is found in palette named Other Stuff.

The TextToSpeech component is a "non-visible" component, meaning it won't appear on the phone's screen when the app runs. You can think of it as a little man deep within the phone who will speak out the words the user types, but will stay hidden from view.

As a component is dragged into an app, it's name appears in the middle- right list of components. By default each component is given a name that includes its type and a number (e.g., 'TextBox1'). You can select a component to change its name and modify its properties. The name is

important because when you begin programming the behavior of the app, in the Blocks Editor, you'll need to refer to particular components by name.

The component designer is used only to specify the way the application will look (it's presentation). If you download the app we've developed thus far, it will look fine but nothing will happen when the user types text and clicks on the "Speak It" button.

Programming the App's Behavior

Click on the Open Blocks Editor button in the Designer menu to begin programming the behavior of the application.

menu to begin programming the behavior of the application. If you were writing a traditional computer

If you were writing a traditional computer program, you would type code using a programming language like Python or Java at this point. With App Inventor, you program the app's behavior by configuring pre-defined blocks.

The Blocks Editor provides you with two palettes from which you can drag blocks, the Built-in pallete and the My Blocks palette. The Built-In palette, shown in the picture above, provides general programming blocks you'll need to specify the behavior and logic of the app. We'll explore these later.

The My Blocks palette:

app. We'll explore these later. The My Blocks palette: has blocks representing the components of your

has blocks representing the components of your particular application, the ones you added in the Component Designer. This example shows four components: Screen1, which represents the entire screen of the app, SpeakItButton, TextBox1, and TextToSpeech1. Each of these components

has a drawer containing function and property blocks for the component. There is also a My Definitions component for custom variables and functions you define.

When you click on a component, say the SpeakItButton, you can see all of the events and functions associated with it:

When you click on a component, say the SpeakItButton, you can see all of the events

Each component's drawer contains blocks associated with the component, including events, properties, and functions.

The pink blocks at the top represent events that can occur which are related to the component. As the snapshot shows, a button component like SpeakItButton has three associated events: when the user clicks it, when the user touches it or in some other manner gives it focus (Got Focus), and when it loses focus (LostFocus).

For the simple 'type in some words and click to speak them' example, you'll first choose the SpeakItButton.Click event and drag it into the program block area:

event and drag it into the program block area: This event-block can be read as, "when

This event-block can be read as, "when the user clicks on SpeakItButton, do

" Until you drag in some operations and place them within this event

block, nothing will happen when the app runs and the user clicks the button.

In this case, the application should respond to the click by getting the text the end-user has entered and giving it to the TextToSpeech component. If you click on the TextToSpeech1 component's drawer, you'll see it has a number of operations including one named "Speak".

a number of operations including one named "Speak". This block will cause the phone to speak

This block will cause the phone to speak a message. It has one argument (slot) named message. Whatever you plug into that slot will be spoken. For this app, you want the message to be the text that was entered by the user in the textbox named TextBox1. That is, you must envision that the user has typed in some words in the text box and then clicked on the SpeakIt button.

You can access the words entered by user by opening the TextBox1 drawer and finding its "Text" property. This "Text" property is a memory cell within the component whose job is to store what the user types. With this property, you can complete the behavior:

TextBox1.Text -- what the user has typed -- is hooked in as the "message" of

TextBox1.Text -- what the user has typed -- is hooked in as the "message" of the function TextToSpeech1.Speak. Both of these blocks are placed within the SpeakItButton.Click block.

In programming, we call such a when-do block, along with the operations inside it, an event-handler. In this sample, the event handler has only one operation (block), but in general an event can invoke many operations.

The event-handler reads as "When SpeakItButton is clicked, TextToSpeech1 should speak the message that is the text entered by the end-user in

TextBox1.

Instant Testing of the App

You can instantly test the apps you create, as you're creating them! If you have an Android phone, just plug it in to your computer using a USB port. Then in the Blocks Editor, select "Connect to Phone". Within 30 seconds or so, you should see your app running on the phone.

If you don't have a phone, you can test most apps using an Android emulator. For instructions on installing and running an emulator, see http://www.appinventor.org/android-emulator.

Download the App to Your Phone

Instant testing is great for development, but when you unplug the phone the app isn't really downloaded on the phone. Thus, when you complete a version of your app that you want to really use or share, you need to download it to the phone. One way to download an app is by scanning a barcode.

Back in the Component Designer, select Package For Phone | Show Barcode:

way to download an app is by scanning a barcode. Back in the Component Designer, select

After a minute, a barcode will appear on the screen:

After a minute, a barcode will appear on the screen: You'll need a barcode scanner on

You'll need a barcode scanner on your phone-- you can download the ZXing Barcode scanner from the Android Marketplace if you don't have one. Once you have it, start it up and place the barcode scanner's window so that the barcode on your computer appears within it. When the phone reads the barcode, it will step you through downloading and installing your app to the phone.

When you run the application, it will look like this:

When you, the end-user, enter some words and press "Speak It", the words will be

When you, the end-user, enter some words and press "Speak It", the words will be spoken.

Chapter 3: An App Is

This chapter is conceptual: we examine the structure of an app, beginning with the analogy that an app is like a recipe. You will learn about event- handlers, conditionals, and repeat loops, and be ready to delve into some more complicated Android programming.

A App is a Recipe

The simplest computer programs are like recipes: the app specifies the computer instructions that should be performed: do A then B then C:

instructions that should be performed: do A then B then C: An App is a Set

An App is a Set of Event-Handlers

Mobile and web apps don't really fit the recipe paradigm, as they have graphical user interfaces (GUIs) with which the user interacts. Such apps are better described as a set of event-handlers, with multiple recipes that are only performed in response to some event.

are better described as a set of event-handlers, with multiple recipes that are only performed in

Events are often user initiated: the user clicking a button or choosing an item from a drop-down list. The "recipe" performed in response can be one or more of the functions that the computer or phone is capable of performing. The event and the functions executed in response to it are together an event-handler.

Most apps will have many event-handlers: In Chapter 2, we described an application which could be described with a single event-handler:

which could be described with a single event-handler: The app responded only to the SpeakItbutton.Click event,

The app responded only to the SpeakItbutton.Click event, and it responded by getting the text from the component TextBox1 (the text the user had entered) and calling the TextToSpeech.Speak function with that text.

App Inventor is a language based on the event-handler paradigm. Conceptually, nothing happens except in response to an event. You'll never drag in function blocks into the app area without hooking them into an event's "when-do" block. For instance, you wouldn't want blocks like:

block. For instance, you wouldn't want blocks like: floating in the block editor outside of an

floating in the block editor outside of an event-handler.

Okay, you're saying, I get the event-handler paradigm, but aren't there actions that should be performed when an app runs, without waiting for an event?

The answer is 'yes'. For instance, a Twitter client for Android might need to contact the Twitter web service to get the user's information as soon as the app begins. With App Inventor, these fit into the event-handler paradigm through the use of the Screen.Initialize block. If you want to do X when an app starts, you can plug X onto the Screen.Initialize block. For instance, you could have an app welcome the user on startup:

There is also a special Timer component that allows you to trigger responses when a

There is also a special Timer component that allows you to trigger responses when a certain amount of time passes. So an app with a moving object is characterized as an app with a timer event where the response to the event is to move the object.

Events types include user-initiated events like button clicks, initialization events, timer events, and external events such as the phone receiving a text or information from a web service like Twitter arriving to the phone.

The job of the app programmer, then, is to put together blocks that say how the phone should respond to all pertinent events.

An App Consists of Event-Handlers That Can Ask Questions and Branch

Many responses to events are not linear recipes, but contain branches and loops. The app is allowed to ask questions -- to query the data within it-- and determine its course based on the answers. We say that such apps have conditional branches:

answers. We say that such apps have conditional branches: Here, when the event occurs, we perform

Here, when the event occurs, we perform operation A, then only perform B1 if some condition is true. If the condition is false, we instead perform B2. Once either of the branches completes, the app proceeds back on the main

branch (C).

Conditions are questions such as "has the score reached 100?" or "did the text I just received come from Joe". Such examples are simple; in general, you can code any complex logic with nested conditionals and various comparative operators.

To check conditions in App Inventor, you'll use "if-then" blocks and "if-then- else" blocks:

"if-then" blocks and "if-then- else" blocks: You can insert any type of condition in the test

You can insert any type of condition in the test slot. If its true, the blocks within the then-do are executed (B1 in the previous diagram). If it is false, the blocks within the else-do are executed (B2 in the previous diagram).

An App Consists of Event-Handlers That Can Ask Questions, Branch, and Repeat

Besides asking questions and branching based on the answer, you can also branch up in a app so as to repeat some operations multiple times. Such an up-branch is called a loop and can be characterized with the following diagram:

some operations multiple times. Such an up-branch is called a loop and can be characterized with

The operation A is executed, then a condition is checked. If it is true, B is executed. Each time B is executed, the app jumps back up and checks the condition again. This loop is repeated until the condition becomes false.

App Inventor provides two "repeat" blocks, the while-do and the foreach.

two "repeat" blocks, the while-do and the foreach. With the while-do, the condition is put into

With the while-do, the condition is put into the test slot, and the operations to repeat are put in the do slot.

The foreach is specifically for repeating operations on a list of data.

An example of an app that uses a repeat is one that texts a list of phone numbers. The condition in such an app is "am I at the end of the list of numbers?" and the operation is sending the message to the current person in the list.

An App Consists of Event-Handlers That Can Ask Questions, Branch, Repeat, and Talk to Web Services

Some apps use only the information within the device they are running on, whether that device be a phone or a computer. But many apps communicate with the outside world by sending requests to web services.

Twitter is an example of a web service that an App Inventor app can talk

Twitter is an example of a web service that an App Inventor app can talk to You'll write apps that communicate with Twitter both to gather data to display on the phone, and to update your Twitter status. Apps that talk to more than one web service are called mashups, and we'll explore those as well.

Web services like Twitter provide an application programmer interface (API), which is the protocol for how a program communicates with the service. We'll discuss web services and APIs extensively in Chapter 6.

An App Consists of Event-Handlers That Can Ask Questions, Branch, Repeat, Talk to Web Services, and Remember Things

When you use apps, you expect them to remember things for you, such as the contacts you enter into your contact manager app. Such memory that lives even after an app is closed is called persistent data and is stored in some type of a database:

App Inventor provides persistent memory in two ways. The TinyDB component allows you to store

App Inventor provides persistent memory in two ways. The TinyDB component allows you to store data persistently directly on the phone. The TinyWebDB component allows you to store data on the web, and thus share the data with other phones and apps. We'll explore the use of both of these database components and build apps such as a quiz application that lets the teacher create and maintain the list of questions.

Summary

A programmer must view an app both from an end-user perspective and

from the inside-out. With App Inventor, you'll design how an app looks and then you'll design its behavior-- the set of event-handlers that lead an app to behave as you want. You'll build these event-handlers by assembling and

configuring blocks representing events, operations, conditional branches,

repeat loops, web service operations, and database operations, then testing your constructions by actually running the app on your phone. After writing

a few programs, the mapping between the internal view of an app and its

physical manifestation will become clear. When that happens, you will be a

programmer!

Chapter 4: Components, Properties, Events, and Functions

In this chapter, you'll learn about components and modifying their properties, as well as more on programming the event-handlers of an application. You'll begin with a simple app that just draws a circle when a button is clicked, then progress to an app for painting pictures on your phone.

Components

The items that appear on the phone when an app is running-- text, input boxes, list boxes, graphics, drawing canvases, etc.-- are called components. There are also non-visible components representing things like motion sensors and the Twitter web service.

The components that you can add to an App Inventor app are organized into palettes that run along the left side of the designer:

The "Basic" palette has the most common components. Button, Label, and TextBox are probably the

The "Basic" palette has the most common components. Button, Label, and TextBox are probably the most popular: the label component is for text the user can't modify, the TextBox is used to get input from the end- user. The Checkbox and ListPicker are for allowing the user to choose between options. The canvas and image are used for graphical apps like paint programs and games. The Clock if for timer events while TinyWebDB is for storing data in a database.

The other palettes have more application- specific components: Media is for playing sounds and movies; Animation provides an image sprite that can move around a canvas. Social provides components for making phone calls, texts, and accessing Twitter; Sensors provide components for sensing the location and movement of the phone; Screen arangement components are for beautifying the user interface.

Other stuff and Not ready for prime time have assorted components: highlights include the TextToSpeech component, the TinyWebDB component for storing data in a web database, and ActivityStarter for launching any Android app from your app.

Properties

All components have a name and properties-- the information that defines the component. The name is how the component is referenced in the Blocks Editor-- thus it is important to name the component well with a specific name (and often with a suffix that identifies its type, e.g., Button).

A visual component has properties such as width, height, and background image, any text associated with it, and whether it is enabled or not.

The snapshot to the left shows the properties for the SpeakItButton. In the snapshot, the

The snapshot to the left shows the properties for the SpeakItButton. In the snapshot, the button component is selected in the Components pane, so it's properties appear in the Properties window.

A Button component has some properties common to many components. Its Text property appears on the button, and its BackGround Color or Image appears on the button as well.

Another common component is the Canvas. It defines a screen sub-area on which the user can draw, paint, and manipulate images. Like the Button component, Canvas has a Width property. Often, the width of a canvas will be set to "Fill parent

which means the canvas should span the width of its parent, which is the screen itself. A height of 400 pixels will take most of the phone's screen.

"

Because canvas components allow users to paint on them, they have a PaintColor property. This property specifies the color of any end-user painting that might occur.

It is important to note that component properties can be set in the Component Designer and in the behavior editor. In the designer, you are setting the initial value of a property-- when the app starts, the properties are set with these initial values. In the behavior editor, you can specify changes to properties that should occur in response to an event. You'll do this by adding a block to set a property within some event handler. For example, if you wanted to change the canvas PaintColor when a user clicked a button, you could have an event-hanlder like the following:

button, you could have an event-hanlder like the following: Events Besides having properties that define its

Events

Besides having properties that define its state, each component also has a set of events that the component can respond to. A component's events only appear in the Behavior editor, at the top of the component's drawer.

User actions like a button click are the most common type of event. But there are other types as well:

• Timer events-- The passing of time can trigger an event.

• Sensor events-- a change in phone location can trigger a location change event. The phone has an accelerometer which triggers motion events.

• Phone events-- when a call or text come in it can trigger an event.

• Communication events-- when your app requests data from a web service, an event will be triggered when that data is received.

Functions

Besides having properties and events that it responds to, a component also has functions that can be applied to it. All components have functions to change and get the value of each of it's properties. Above, we showed how a set function could be used to set the value of the PaintColor property of a canvas.

Most components also have other functions associated with them. For instance, the Canvas component, besides it property set-get functions, also has the following: DrawCircle, DrawLine, DrawPoint, and Clear.

If, in response to a button click, you wanted to draw a circle on the canvas, you'd specify it by dragging in the DrawCircle function and placing it in the Button.Click event handler:

function and placing it in the Button.Click event handler: As you can see from the DrawCircle

As you can see from the DrawCircle block, the function has three open slots labeled x, y, and r. These slots are called parameters (they're also known as arguments). A parameter is a piece of information that the function needs to do its job. If you told a child to draw a circle on the paper, the child might ask you: where on the paper and how big? This is the information that is needed to DrawCircle, and in App Inventor the where of a circle is specified with x and y coordinates, and the size with the radius r, all measured in screen pixels (the size of one tiny dot on the screen).

If you left the x, y, and r slots empty, your app would not work-- parameters (slots) must be filled in. So After dragging the DrawCircle operation onto the program area, the programmer must specify actual values for the parameters. Above the blocks, there is a mini-palette of programming components. In this case, you would click on the one labeled Math and chooses a "123" block that represents a number. The number block can then be placed into the slot for x with a number, say 20, entered instead of the "123". Similar blocks can then be added for y and r:

"123". Similar blocks can then be added for y and r: The x and y coordinates

The x and y coordinates are in relation to the top-left of the screen, with x larger as you go right, and y larger as you go down:

x=0,y=0

x=300,y=0

x=1,y=1

.

.

.

x=300,y=300

Now since pixels are very small, there are actually hundreds of pixels running across the width and the height of the phone. So if you ran this app and clicked on the button, a circle would be drawn at x=20,y=20, which is near the top-left corner:

be drawn at x=20,y=20, which is near the top-left corner: Summary This chapter described the basic-building

Summary

This chapter described the basic-building blocks of an app. Apps consist of components, both visual and non-visual. Each component has properties that track of the current state of the component, things such as its width and height. Each component also has a set of events and functions associated with its dynamic behavior. Events are user actions and other actions that the component responds to, e.g., a button responds to a user clicking it. Functions are things that can happen to a component and often change its state. For instance, the DrawCircle function modifies the state of a canvas component by drawing a circle on it. DrawCircle, like most functions, has parameters associated with it. When invoking a function on a component, the programmer must specify these parameters so that the function knows how to do its job (e.g., how big to draw the circle).

Problems

1. Program an application that draws a circle in the center of a canvas when

a button is clicked.

2. SaveAs your DrawCircle app into another app and name it CanvasFun.

Modify the program so that:

• The canvas has an image as a background. You can set this in the component designer.

• The user can click on a second button to draw a green circle at 40,40. Note that you'll need to set the PaintColor property of the canvas in the Click event handlers of both buttons.

• The user can click on a third button to clear the canvas. You'll need to use the Canvas.clear block.

3. Program the PaintPot painting app from Google:

Chapter 5: Animation

In this chapter, you'll learn how to write a simple animated game and be introduced to timer events, randomness, and global variables.

Animated Objects

App Inventor has two types of animated objects: a Ball and an ImageSprite. A Ball has a restricted appearance, while an ImageSprite is any image you load.

Timer Events

Many of the events that occur in a mobile phone app are end-user initiated, e.g., the user clicks a button. There are other types of events as well, including the Timer event, which is triggered not by the user but by the passing of time.

To add a timer event, you first add a Clock component to the application in the Component Designer. Think of the Clock component as a tiny alarm clock inside your app. You drag it in from the Basic palette, and it is automatically placed in the 'non-visible component' area, as its not something that will appear on screen.

One important property of the Clock component is its interval. The interval is in milliseconds

One important property of the Clock component is its interval. The interval is in milliseconds (1/1000 of a second). If you set the interval to 1000, then a timer event will be triggered every second.

Moving an Object Periodically

To illustrate use of the timer, let's consider the most fundamental animation:

moving an object across the screen at a consistent pace. Specifically, we'll develop an app in which the the ball move horizontally across the screen at 10 pixels a second.

In the Component Designer, drag in a canvas onto the screen, then a ball onto the canvas. The canvas is in the basic palette, while the Ball is in the Animation palette (along with the Image Sprite). A canvas is required for any animation: you cannot add a ball or image sprite directly on the screen.

After defining the components, open the Blocks Editor, then open the Clock1 drawer within My Blocks. Drag in a Clock1.Timer event to specify the activity that should occur on each timer interval:

Since the interval for the Clock1 component is set to 1000 milliseconds, the blocks we

Since the interval for the Clock1 component is set to 1000 milliseconds, the blocks we put into the Clock1.Timer event will be repeated every second.

In our case, we want to move the ball across the screen 10 pixels every second. So we'll open up the palette for Ball1, and drag in a Ball1.MoveTo operation:

palette for Ball1 , and drag in a Ball1.MoveTo operation: MoveTo moves the ball to a

MoveTo moves the ball to a specific place on the canvas, specified with the x and y parameters. How can this operation be used to move the ball right 10 pixels?

Well, another way to characterize, "move the ball right 10 pixels' is, "change the ball's x property so that it is 10 more than what it was, and keep its y coordinate the same." To do this, we'll need to make use of a built-in + block from the Math drawer:

need to make use of a built-in + block from the Math drawer: The + block

The + block has two slots for its operands. We want to add 10 to Ball1's X property, so we open Ball1's drawer and drag in the X property, then open the Math drawer and drag in a number block, entering 10 as the number. We then slot in the Ball1.X and number 10 into the + block, and the whole + block into the x parameter of the MoveTo block. Finally, to keep the Y property the same, we drag in a Ball1.Y block and place it into the y slot of the MoveTo block. Here's the resulting event-handler:

we drag in a Ball1.Y block and place it into the y slot of the MoveTo

The blocks read, "On every timer interval, change the x property of the ball to 10 more than it was and leave the y value the same". Because the interval of Clock1 is set to 1000 milliseconds (one second), the ball will move right ten pixels a second.

Using this same scheme, any type of motion is possible. Can you write an app that moves the ball vertically? from bottom to top? Diagonally? All of these can be programmed by setting the initial location of the ball in the component designer, then correctly setting the parameters of the MoveTo.

Ball/Image Sprite Events

Both Ball and ImageSprite have a number of events that they respond to:

ImageSprite have a number of events that they respond to: Touched is triggered when the user

Touched is triggered when the user touches an object on the screen. If the user then drags his finger along the screen, a sequence of Dragged events are triggered. Dragged is the key event of paint programs.

EdgeReached is triggered when an object reaches the edge of its enclosing canvas. Say the canvas has a width of 400 and a height of 300. Then EdgeReached is triggered when 1) the object's X property is less than 1 or more than 400, or 2) the object's Y property is less than 1 or more than

300.

CollidedWith is triggered when when an object runs into another. The parameter other1 tells you which other object is involved. NoLongerCollidingWith is triggered when two objects that were touching are

no longer in contact.

Reacting to Touch and the Ball Reaching an Edge

To illustrate some of the Ball/Image events, consider an app which 1) moves the ball to the center of the screen when the user touches it, and 2) moves the ball to the left-side of the canvas when it reaches an edge.

The first event-handler reacts to the Touched event. Since we want the ball to move to the center of the canvas on the touch, we'll need to use the Canvas.Width property as well as a division block from the Math drawer:

property as well as a division block from the Math drawer: The x parameter of the

The x parameter of the MoveTo is set to 1/2 of the canvas's width. We leave the y parameter (the vertical location) the same.

The second event-handler reacts to the EdgeReached event. For this event- handler, we just set the x parameter of MoveTo to 1:

event- handler, we just set the x parameter of MoveTo to 1: With these event-handlers, the

With these event-handlers, the ball will move across the screen until it reaches the right-side, at which time it will appear again on the left. If the user touches the ball, it will move to the middle of the screen.

Variables

In programming, the term variable refers to a named memory cell. It is a place in the phone's memory where you can store a specific data item. These memory cells can be accessed by an app, but they are not directly visible to the end-user of the app.

We've already considered one type of variable-- the properties of a component. As we've seen, these variables have names of the form:

component.property

For instance, in the last chapter we worked with the PaintColor property of the Canvas component, Canvas.PaintColor. This is just a memory cell with a color in it. When the canvas draws something, it checks that memory cell to see what color to draw.

In App Inventor, you can also define variables that are not associated to a particular component. Such variables are called global variables. For instance, in many games, you'll need to keep track of the score, so you'll define a global variable named "score". Later, we'll also discuss global variables which are not single numbers but lists of data, and that allow you to remember things like the questions of a quiz.

You define new variables by dragging out a "def variable" from the Definition drawer of the Built-In palette:

from the Definition drawer of the Built-In palette: After dragging in the block, you should rename

After dragging in the block, you should rename the variable (its default name is "variable"). To rename it, click on the word variable and type the new name.

You should also initialize the variable. If its a text or number, just click on the red ? block, choose text or number, and specify the particular value. For

a

variable to track the score of a game, you'd name it "score" and connect a

number to it with an initial setting of 0:

to track the score of a game, you'd name it "score" and connect a number to

The result of these blocks is to set up a new memory cell within the phone's memory, and put a 0 in it.

Phone's memory

score

0
0

When you define a variable, App Inventor adds blocks for looking at (getting) and modifying (setting) its value in the My Definitions drawer of My Blocks:

its value in the My Definitions drawer of My Blocks : The first block, labeled "global

The first block, labeled "global score" allows an app to access the value of a variable. For instance, you could display the score in a Label Component with:

you could display the score in a Label Component with: If there was a 0 in

If there was a 0 in the hidden memory cell of score, 0 would be displayed to the end-user in the label component named ScoreLabel.

The block labeled "set global score to" changes the value in the memory cell. For instance, the following:

The block labeled "set global score to" changes the value in the memory cell. For instance,

would change the value in score to one more than it's current value. If it was 0, it would change to 1, 1 to 2, and so on.

In programming, such blocks are called assignment statements, which can be confusing for beginning programmers. The key is that the right-side of the block sequence is evaluated first. The app will first evaluate the expression on the right side by grabbing the value of score and adding one to it. The result is then placed back into the variable score (due to the set global score block).

With a variable score, we can extend the ball animation app above so each time the end-user touches the ball, five points are added to the score.

touches the ball, five points are added to the score. Each time the ball is touched,

Each time the ball is touched, the app moves the ball to the middle of the screen, then adds one to the variable score.

Unfortunately, score is a variable, so it is hidden from the user of the app unless you display it in a label or other user interface component. So go back to the Component Designer and add a ScoreLabel to the interface. Then modify the Ball1.Touched event-handler to update the ScoreLabel:

Randomness Computers can generate random numbers, typically using the computer's real-time clock to seed the

Randomness

Computers can generate random numbers, typically using the computer's real-time clock to seed the generation of the numbers. Such random number generation is essential to many games. For instance, the game Mastermind generates a random sequence of colors for every game. The game WhacAMole moves the mole to random spots on the screen.

App Inventor provides a number of blocks for adding randomness to an application. They appear in the Math drawer of the built-in palette:

They appear in the Math drawer of the built-in palette: To write an application that displays

To write an application that displays a number between one and ten, you could use the random-integer block:

palette: To write an application that displays a number between one and ten, you could use

The random-fraction block returns a decimal number between 0 and 1. Say you wanted to modify the ball animation so that when the ball reaches the right edge, it jumps to a random column on the canvas, instead of the first column. To implement this, you'd multiply a random-fraction block with the width of the canvas:

a random-fraction block with the width of the canvas: If the canvas was 400 pixels wide,

If the canvas was 400 pixels wide, and the random-fraction function happened to return 0.5, the ball would jump to the middle. If the random- fraction function returned .1, the ball would jump to 40 pixels from the left edge.

Problems

Write the following programs and document them on your portfolio:

1. Program a ball animation "BallAnimation" application such that:

• The ball moves diagonally from top-left to bottom-right of the canvas

at a rate of 20 pixels per second.

• When the ball reaches an edge, it appears again in the top-left of the canvas.

• When the user touches the ball, it is sent to the middle of the canvas.

2. SaveAs BallAnimation into "BallAnimationScore" and:

• Modify the application so that it keeps score of the number of times the end-user touches the ball. Use a global variable to do it.

• Modify the application so that when the ball reaches the edge, it jumps to a random column and row on the canvas.

3. Create the game WhacAMole, following the Google tutorial at

http://sites.google.com/site/appinventorhelp/tutorials/whackamole. Call yours WhackAnX where X is someone you'd like to whack (use their image).

Chapter 6: Conditional Blocks

This chapter discusses apps that branch to execute different functions based on some condition.

Most interesting apps consist of event-handlers that are not linear recipes, but contain conditional branches and repeat loops. We discussed the for- each repeat block in chapter 6 and how an app can continually branch up in the code to execute some functions over an entire list of data. Such code might be described as "perform this function n times, where n is the number of items in the list".

We can also define event-handlers that perform a function 0 or 1 time, based on some boolean condition. Such event-handlers can be described with the following flow chart:

can be described with the following flow chart: Here, when the event occurs, we execute operation

Here, when the event occurs, we execute operation A, then only execute action B1 if some condition is true. If the condition is false, we execute B2.

Conditions are questions such as "has the score reached 100?" or "is a random number 1 or 2". Such examples are simple; in general, you can code any complex logic with nested if-else conditions and various logical operators.

If and Ifelse Blocks

Control blocks allow you to put conditional branches and loops into the event-handlers of your App Studio program. You'll find such blocks in the Control drawer of the built-in palette:

Let's first look at an simple example where we set the text of a label

Let's first look at an simple example where we set the text of a label to "You win" when a score reaches 100.

The first thing we do is to drag an if-then-do block into the program area. Then we build a condition to plug into the "test" slot.

Conditions are boolean, meaning they return a result of true or false. They generally test the value of properties and variables using the following logical operators:

and variables using the following logical operators: These operators can be found in the Math and

These operators can be found in the Math and Logic drawers.

For our sample, we'll drag in an = block:

Logic drawers. For our sample, we'll drag in an = block: The condition we want to

The condition we want to check is "is the variable score equal to 100". Assuming we've already defined the variable score, we can find a block for it in the My Program drawer of My Blocks. We use a number for the 100. We stick those two items into the slots of the =, and the whole = block into the slot of the if-then-do:

=, and the whole = block into the slot of the if-then-do: If the test evaluates

If the test evaluates as true, we want to tell the end-user they've won:

Note that if the test is false (score not equal to 100), the action within

Note that if the test is false (score not equal to 100), the action within the if- then block doesn't happen. In fact, nothing happens. If you want a false test to trigger an action, you can use an if-then-else block.

Sample: Calling a random friend from a set of friends.

Suppose you wanted an application you could use when you were bored-- you press a button and a random friend is called. You could use a random- integer block to randomize the selection, then an if-then-else block to set the phone number to one of the choices:

block to set the phone number to one of the choices: In the above sample, we

In the above sample, we use a global variable RandomNum to hold the random number returned from the random-integer function. This number will be 1 or 2 based on the from and to arguments given.

After setting randomNum to either 1 or 2, we compare it to the number 1 in the ifelse test. If the randomly generated number is 1, we set the phone number to 3779199. If it is not 1, the ifelse test is false, so the else-do blocks are executed and the PhoneNumber is set to 3594787.

If we wanted to choose between more than two numbers, we'd place an if- then or if-then else within else clause of the first if-else:

or if-then else within else clause of the first if-else: If the first test is true,

If the first test is true, the first then-do branch will be executed. If it is false, then the else branch is executed, which immediately runs another test. So if the first test is false, and the second true, the second then-do is executed. If both tests are false, the else-do branch at the bottom is executed, and the third number (2423428) is called.

Note that this modification only works because we also modified the to parameter of the random integer so that a number between 1 and 3 is generated.

When one control construct is placed within another, we say it is nested. We'd say that the event-handler above has a "nested if-else". By using multiple levels of nested if-else blocks we can write app behaviors that choose between n choices, instead of just two or three.

Sample: Mastermind

Mastermind is a great thinking game. There are many on-line versions of it, including the one at http://www.irt.org/games/js/mind/. The game (app) generates a "secret code" of four colors. The player then continually tries to guess the code, receiving feedback on each of the guesses. The feedback tells the player how many colors are in the right position (exact matches) and how many are the right color but in the wrong position (partial matches).

Let's build an Android version of this app. In the process, will make use of some of the conditional (if-else) and iterative (foreach) blocks we've been discussing.

Iteration 1: Toggling through colors It's always a good idea to start with something simple, then build on complexity. We'll start with some simple functionality. Let the user choose between three colors by clicking a button. On each click, the button should change to the next color in the sequence, and when it reaches the third (last) color it should change color to the first color in the sequence.

First, we create the components for this initial iteration. We are only going to program one color, but we'll add two color buttons now, as well as a Guess button and a feedback label.

buttons now, as well as a Guess button and a feedback label. Next, we open the

Next, we open the blocks editor to code the toggling behavior. We'll first program the behavior for the first color button (ColorButton1). We'll assume that the button has an initial background color of blue, and that clicking the first time should change it to Cyan, clicking a second time should change it to Green, and a third time back to Blue. The user should be able to continue this sequence forever to choose their color.

When Color1Button is clicked, we check the background color of the button and compare it

When Color1Button is clicked, we check the background color of the button and compare it to Blue. If it is Blue, we set it to Cyan. If its not Blue, the outer else-do is executed. This causes a second check, and the background color is compared to Cyan. If it is Cyan, the color is set to Green. If it is not Cyan, the inner else-do is executed, and it is set to Blue.

Note that if the first test, Color1Button.BackgroundColor = Blue, is true, the background color is set to Cyan and the even-handler ends-- the else-do and the inner test, Color1Button.BackgroundColor = Cyan, is never checked. So Blue will change to Cyan.

On the next click, the first test will be false, the second test will be true, and the color will change to Green.

On the third click, the first test will be false, the second will also be false, so the inner else-do will be executed, changing the color to Blue. On the fourth click we'll be back to where we started, and the first test will be true.

Summary

Conditional blocks allow for the specification of complex behaviors and decision-making in an app. This chapter provided some examples of conditional behavior, including nested conditions that allow for choosing between multiple alternatives. In the next chapter, we'll examine even more complex behaviors and continue with the Mastermind sample.

Problems

Complete the following and document on your portfolio:

1. SaveAs your ball animation program into BallGame. Modify the program

so that it reports a win when the player has touched the ball 3 times.

2. Write a callRandomFriend which randomly calls one of your friends when

you run the application. Put at least three numbers into the randomizer and use an if-else and a nested if-else.

Chapter 6: Lists

This chapter describes how to work with lists of data in an App Inventor application.

Thus far, in working with variables, we've worked with scalar data, that is, atomic data like a single number or text entry.

Many applications deal with lists of data. For instance, we might want to keep track of the list of monsters in a game or a list of friend's phone numbers. A list is a variable, but instead of representing a single memory cell, it represents an array of cells:

PhoneNumberList

3219872 4153297878 4592371

App Inventor provides blocks for creating lists, adding elements to lists, selecting a particular item from a list, and applying operations to an entire list.

Making a List

A list is created in the blocks editor using a variable block and a make a list block. Suppose, for instance, that you're writing an app to text a list of friends with one click. We'd create the phone numbers list in the following manner:

1. From the Built-In palette, drag a "define variable" block into the program

area and change the name from "variable" to "phoneNumbers".

2. From the Lists palette, drag a "make a list" block in and latch it to the

variable. This tells App Inventor that the variable will store a list of data as

opposed to a single scalar. 3. Since the elements of our list are phone numbers, drag in some text blocks, enter the desired numbers, and connect them to the "item" slots in

the make a list block. Note that a new "item" slot open up each time you add

a new element to the list.

Your blocks should look something like this:

to the list. Your blocks should look something like this: Note that this definition block can

Note that this definition block can float by itself in the block editor, just like when you defined numbers or text variables. It does not need to be hooked into an event handler.

With the blocks above, you've defined a hidden variable named "phone

numbers" which is of type "list" and which has two elements, each of which

is of type text. Now we'll show how you can write event-handling blocks that

use this new list variable.

Selecting an Item

You can access particular items in a list using an index. If a list has five items, you can access the items with indices 1,2,3,4, and 5. With traditional programming, you'd write code such as:

phonenumbers[2]

to access the second item in a list. With App Inventor, you use the select list item block:

With App Inventor, you use the select list item block: With select list item, you plug

With select list item, you plug in the list you want to choose from in the first slot, and the index you want in the second slot. The blocks above say to select the second element of the list phoneNumbers. The return value of select list item for this sample would be "3334444" as that is the second

element of phonenumbers.

Text Random Using a List

You are new ready to create a more elegant version of the text random friend app. Recall that in that application, you used the random integer function to get a random number, then used if-else blocks so that if the random number was 1, the first friend was called, if it was 2, another friend, and so on.

Using a list, you can eliminate the if-else blocks and use the random integer as an index into the list. Here are the blocks:

integer as an index into the list. Here are the blocks: The blocks get a random

The blocks get a random number between 1 and 2, as the list has only two items. It then calls select list item with the random number (1 or 2) as the index. The selected phone number is set as the texting object's phone number, and the message "miss you" is sent to it. If you run this app multiple times, it should text the two numbers with equal likelihood.

Using Length of List

One reason the above solution is more elegant is that you don't have to change the event-handler much in order to make the app work for a different set of phone numbers. With the old if-else solution, we'd have to add another if-else block if we wanted a new phone number added. For the new solution, we can just add an element to the make a list block, e.g.,

There is another detail that must be taken care of, however. When you get the

There is another detail that must be taken care of, however. When you get the random integer, the blocks specifically request a number between 1 and 2, so the new third element will never be chosen.

A simple solution is to change the "to" parameter of the random block from 2 to 3. However, this introduces a dependency-- you must always change that parameter when you change the size of the list. As programmers are notorious for forgetting things, it's better to avoid such dependencies. You do not want to introduce bugs when making a change in an app.

The better solution is to make the event-handling code more general. Instead of putting a fixed upper limit in the random call, you can specify that the upper limit for the call to random should be the size of the list: if there are n items in the list, get a random number between 1 and n. Fortunately, App Inventor provides a list operation to help: length of list. Here is the modified program:

to help: length of list. Here is the modified program: The change is near the right:

The change is near the right: the "to" parameter to random integer is no longer a fixed number. Instead, it is the result of the function "length of list".

This solution is maintainable-- the programmer can make the app work for more or less numbers by simply modifying the entries into "make a list". It will also work for apps that have dynamic lists, i.e., apps in which the user (not the programmer) is allowed to add or remove numbers from the list. This is important given that, generally speaking, you want to write apps for

others, not just for yourself!

Toggling through colors using a list. In the previous chapter on conditional statements, you programmed a button that sequenced through color choices when it was clicked. For the purposes of comparison, let's write it using a list of colors instead of a nested if-else. The advantage with this alternative solution is that our code will work even if we change the colors or number of colors that should appear.

The first step is to define a list variable for the colors:

The first step is to define a list variable for the colors: Along with the colors

Along with the colors list, you need to keep track of the current color. For this, you'll define another variable to use as an index. An index is a position in a list. Since you'll start with the first color, initialize it to 1:

you'll start with the first color, initialize it to 1: Now you're ready to code the

Now you're ready to code the click event for ChooseColorButton. On the click, first add one to the currentColor. The call select list item using the colorIndex as the index:

The call select list item using the colorIndex as the index: As is, the app will

As is, the app will begin with a blue button background. The first time the button is clicked, colorIndex will change to 2, and the button background will be changed to Cyan. The next click will change colorIndex to 3 and the color

to Green. What happens on the next click?

If you thought, "error", you are correct. colorIndex will become 4 and then

the app will try to select the 4th item in the list, but the list only has 3 items.

To fix this, use an if-then block to handle the case when the last color in the list is reached:

handle the case when the last color in the list is reached: The event-handler here and

The event-handler here and the corresponding one you created in the Conditionals chapter both cause the same behavior, just in different ways.

The first uses a nested if-else to choose the next color, while the latter uses

a list and an index variable to choose the next color.

The advantage of the latter method is that the list of entries can be modified and the app will still work. As most apps work with dynamically changing data, this is a very important difference.

Iterating Through a List: For Each

Now suppose we wanted another button for the app and that when the user clicked it, the text would be sent to all the numbers in the list, not just a random one.

A brute force method for such an event-handler would look like:

With this method, the blocks to set the phone number and send the message are

With this method, the blocks to set the phone number and send the message are copied 3 times. For three numbers, this isn't too awful, but what if we wanted to text 100 or 1000 numbers? The program would be quite large. Furthermore, the programmer would have to add three blocks in order to add a new phone number to the one's called.

Fortunately, we can use our "phonenumbers" list and a special block "for each" that allows us to apply some operations to all elements of a list. Here is the more elegant solution:

all elements of a list. Here is the more elegant solution: This code says that "for

This code says that "for each phone number 'pnum' in the list 'phonenumbers', set the text object's phone number to pnum and send out the text message".

The foreach block can be found in the control drawer, the same place where the if-else is. When you drag a foreach block into the program area, you

must specify the list that will be processed as the "in list" parameter at the bottom of the for-each block. In this case, the list is the global "phonenumbers".

At the top of the foreach block, you can also provide a name for the placeholder variable. Often, you'll name it "item", as this variable represents an item in the list. In this case, we named it "pnum" as it represents one of the phone numbers in the list.

The foreach block is one method of iterating in a program. To iterate means to repeat some operations over and over. The blocks that are slotted into the foreach block's "belly" will be repeated for each item in the list. In this sample, the blocks that are repeated are:

the list. In this sample, the blocks that are repeated are: We say that those blocks

We say that those blocks are subordinate to or within the foreach block. We say that the program "loops" back up when it reaches the bottom block within the for-each.

The app executes in the following manner: when the TextAllButton is clicked and the event-handler called, the first operation executed is the "set Texting1.Message to" block, which sets the message to "miss you". This block is only executed once.

The for-each block is then entered. The variable pnum is set to the first number in the list phonenumbers ("3594787"), and the blocks within the foreach are executed for the first time. The Texting1 object's PhoneNumber property is set to pnum ("3594787"), and the message is sent.

Because we are within a foreach, the app "loops" back up to the top of the foreach and puts the next item in the list ("3779199") into pnum. The two operations within the foreach are repeated, so the text is sent to "3779199". The app then loops back up again and sets pnum to the last item in the list ("8143549"). The operations are repeated a third time causing the third text to be sent.

This time, when the app loops back up, it realized there are no more items to process. The app "pops out of the loop" and continues on after the foreach block. In this case there are no blocks below it, so the event-handler ends.

This solution is maintainable because it will work even if new numbers are added to the phonenumber list-- the foreach will process however many items are in the list.

Getting Started

QuizMe is a trivia game about baseball, but you can use it as a template to build quizzes on any topic. With QuizMe:

• The user steps through a series of questions, clicking a Next button to proceed to the next question.

The user enters an answer for each question and the app reports whether each answer is correct or not. For this tutorial, you'll create an app in which the questions are always the same unless you, the programmer, changes them. Later, you can create MakeAQuiz, an app that lets users create and modify the quiz questions. This tutorial assumes you are familiar with the basics of App Inventor -- using the Component Designer to build a user interface, and using the Blocks Editor to specify event- handlers-- both of which are explained in the HelloPurr, PaintPot, and WhackAMole tutorials. Connect to the App Inventor web site and start a new project. Name it QuizMe, and also set the screen's Title to QuizMe. Open the Blocks Editor and connect to the phone. Also download these pictures of baseball players and save them on your computer: larsenberra.jpg, dallasbraden.jpg, cyyoung.jpg, nolanryan.jpg.

, dallasbraden.jpg , cyyoung.jpg , nolanryan.jpg . • Example: Quiz App Version 1 Specification: The quiz

Example: Quiz App Version 1

Specification: The quiz app will display a single question at a time. The user enters an answer and clicks the "submit answer" button. The app responds by either displaying "correct" in the reply label, or displaying "incorrect: the answer is x". The user clicks on a next button to see the next question.

UI Design: We'll begin with a simple user interface: a question label where the question will be displayed, and AnswerBox where the user will answer, a

SubmitButton that the user clicks when answer is in, a ResponseLabel that will display "correct" or "incorrect", and a NextQuestion button that the user clicks to get to the next question.

button that the user clicks to get to the next question. Iterative Development Strategy: We'll first

Iterative Development Strategy: We'll first develop a version that just lists a question and responds to the next button by displaying the next question. For now, we'll ignore the user's answers.

Iteration 1: Questions and the Next Button.

In the blocks editor, our first task is to create a list of the questions. We'll drag in a define variable block and a make a list block, and populate the list with some questions:

a list block , and populate the list with some questions: Next, we want to get

Next, we want to get the first question in the list to display when the app begins. We'll use an Initialize event block of a component, in this case the QuestionLabel, to define this behavior. Remember that Initialize is called on each component as the app is starting up, so whatever we do here will appear when the user first sees the app. Here are the blocks:

We use the select list item block to grab the first item from the questions

We use the select list item block to grab the first item from the questions list (note that the list parameter is set to "questions" and the index to 1). The result, in this case "who wrote Remix?" will be displayed in the QuestionLabel.

Of course, we could have put the text "who wrote Remix?" directly in the QuestionLabel.Text. But we want to write the behaviors so that they will work on any list, and will work even if the list is rearranged. The more general "select the first item of the list and put it in the QuestionLabel" code allows for this.

Our next task is to program the behavior of the next button. To do this, we need to remember what question we are on at all times. To remember something, we just define a new variable. In this case, we need to remember the question number, i.e., the index into the list "questions":

number, i.e., the index into the list "questions": Note that this variable definition, like all of

Note that this variable definition, like all of them, should be placed outside the confines of any event-handler, just floating by itself in the program area.

Now that we have the questionNum variable, we can program the NextButton event handler. What we want to do is to increment the questionNum variable, e.g., change it from 1 to 2 or from 2 to 3, and then display the next question. Here are the blocks:

questionNum variable, e.g., change it from 1 to 2 or from 2 to 3, and then

This is some sophisticated code. The first operation sets the questionNum variable to itself plus 1. This is typically quite confusing for beginning programmers. The way to conceptualize it is to first realize that the variable questionNum represents a memory cell with some number in it:

questionNum

1

The user of the program can't see it, but that memory cell is in the phone's memory because of the questionNum variable definition we performed earlier.

The second thing to realize is that you have to read sequences of blocks right-to-left. For the blocks:

to read sequences of blocks right-to-left. For the blocks: the + operation is executed first. It

the + operation is executed first. It says to take the value in questionNum and add 1 to it. When the program first starts, the value of questionNum is 1, so by adding 1 we'll get 2 as the result of the + operation.

The result of the plus, 2, is then slotted into the set global questionNum to block, i.e., 2 is put into questionNum. This causes the hidden memory cell to no longer have a 1, but instead have a 2:

questionNum

2

Sometimes when we're tracing a program on paper to understand how it works, we'll cross out the old value and place the new one after it:

questionNum

1

2

and we'll leave off the box around the memory cell. This shows the history of execution, which can be helpful. But always remember that a memory cell holds one thing only, and the 1 is gone as soon as we (re-) set the variable questionNum.

So the first operation in the event-handler changes the hidden variable

questionNum to one bigger. The second operation:

questionNum to one bigger. The second operation: then uses this modified variable questionNum as the index

then uses this modified variable questionNum as the index into the list questions. Just like we might say, "get the 2nd item from a list", or "get the third item from a list", these blocks read as "get the 'questionNumth' item from the list. The app, when executing the select list item operation, must first evaluate the index parameter, which is the non-fixed value "questionNum". There could be anything in questionNum, but whatever that number is will be used for the index. If questionNum has 2 in it, we'll get the second item from questions ("who wrote The Big Switch") and put that into QuestionLabel.

The event-handler we have so far would work fine until the user got to the third (last) question. At that point, when the user clicked next, questionNum would have a value of three. We would then increment questionNum, changing it to four, and the select item call would ask for the 4th item in a three item list. This would cause the app to Force Quit, or as programmer say, "bomb out".

So we need to modify the blocks so that, when the NextButton is clicked we do something differently if we are on the last element of the list. Here's a solution:

are on the last element of the list. Here's a solution: The if-else block comes to

The if-else block comes to the rescue: if questionNum is equal to the length

of the questions list, we reset questionNum back to 1. So if questionNum is 3 and there are three things in the list questions, the test will be true and the app will execute the then-do branch.

If questionNum is 1,2, or in general any number less than the length of the list, the else-do branch is executed and we increment the questionNum.

Other solutions are of course possible: we could leave the questionNum at its max once its reached or we could gray out (enable=false) the next button once questionNum does reach its limit. The important thing for a programmer is to understand how to convert the specs of an app into blocks like the one in this example.

Iteration 2: Processing Answers

This is left as an exercise (see problem 2)

Summary

Lists allow us to give a name to related items. Then with list operations we can index into the list to grab particular items and even apply some operations to each element of the list. This ability to group can reduce the size of a program and make it more maintainable.

Problems

1. Sum of a list app: Create a list "numbers" with at least three integers,

then use a foreach block to compute the sum of the numbers in the list. For instance, if the list had the numbers 3,5, and 7, your app should display 15.

2. Quiz app: Extend the iteration 1 solution given in the text to create a

complete quiz app. You'll need another list, answers, and you'll need another event-handler to handle the AnswerButton.Click event.

Solutions:

Add a List

3. Complete a quiz application:

• The first question should be displayed on startup.

• When the user clicks next, the next question is displayed.

• When the user clicks next on the last question, the first question is displayed again.

• When the user enters an answer and clicks "Answer", the app checks the answer and reports either "correct" or "incorrect, the answer is showing the correct answer.

• You should have two lists, one for questions and one for answers, and use an if-statement to check if the answer is correct.

"

Chapter 8: Iteration

The previous chapter discussed lists and methods for iterating through a list, that is, applying some operations repeatedly to items in a list. This chapter continues the discussion of iteration and introduces the while-do block. In the chapter, you'll learn how to write mathematical apps such as one to sum up the first n numbers and another to compute factorial(n).

Computers are great at doing the same task over and over. They never get tired. As the chapter 4 discussion of the for-each block showed, the blocks within an event-handler need not be linear "recipe" like programs, but can contain repeat loops that execute some operations over and over.

In App Inventor, there are two blocks for specifying repeatable code: the for-each and the while-do. The text everyone in a list app in Chapter 4 used a for-each block to text all the phone numbers in a list.

The while-do is a bit more complicated to use, but it is more general than the for-each: whereas the for-each is specifically for repeating operations on each item of a list, a while-do can repeat any operations. Furthermore, whereas the for-each always repeats once for each item in the list, with the while-do the programmer can specify that the operations repeat while any arbitrary condition is true (the converse way to put it is that the program can repeat until any arbitrary condition becomes false.

can repeat until any arbitrary condition becomes false. With a while-do, the app checks a condition,

With a while-do, the app checks a condition, and if its true, executes some

operations (B in the diagram). After completing B, the app loops back up and rechecks the condition again. If its still true, B is repeated. If it is false, the app "pops out of the loop" and continues with C.

Computing the Sum of the First Three Numbers

What is the sum of the first 3 numbers? What is the sum of the first 5 numbers? The first N numbers? How did your brain compute it?

The hard thing about programming is usually not the problem we are solving: most of us can add up 1+2+3=6. The difficult part of it is breaking your thought process down so that you can instruct a computer to do the same thing.

When you add up the first so many numbers, your brain probably uses two memory cells-- one is a counter for the new number you're adding, and one for a "running sum". So you begin with 1 as the couner and 1 as the sum. Then you get the next counter 2 and add it to your sum, giving you 1+2=3 as the sum. Then you get the next counter 3 and add it to the running sum, which is 3. This gives you a new sum of 6. Then you get 4 and add it to the running sum, giving a new sum of 10. And so on.

If we were to trace these memory cells, we'd get:

counter

sum

1

1

2

3

3

6

4

10

This is how your brain works, but how do you get an app to do the same thing? This is where a while-do comes into play.

Let's start by writing an app that sums the first 5 numbers. Later, we'll generalize it to sum up the first n numbers, where n is some number input by the user. Here's pseudocode for what we want:

set counter to 1 set sum to 0 repeat while counter is less than or equal to 6:

add the counter to the running sum increment counter

Now let's convert this pseudocode into an App Inventor app. First, we need

to define two variables, which we'll call "counter" and "sum":

which we'll call "counter" and "sum": Next, we drag in a while-do block from the Control

Next, we drag in a while-do block from the Control drawer of the built-in palette:

block from the Control drawer of the built-in palette: Note the the while-do has a test

Note the the while-do has a test just like with the if and ifelse blocks. With both, the app performs the blocks inside if the test is true. The difference is that with the while-do, the app loops back up and checks the test again each time after executing the inside blocks. A while-do does something 0 or more times. An if does it 0 or 1 times.

In this case, we want to add up the first five numbers, so we want to repeat while the counter is less than 6. We'll add one to the counter each time so that at some point it will become 6 and the app will "pop-out of the loop". Here's how we fill in the while-do block:

the loop". Here's how we fill in the while-do block: When we reach the while test

When we reach the while test the first time, the value of counter is 1. Since 1 is less than 6, the app will execute the operations within the while-do, in this case the modification (set) of the sum and the modification (set) of the counter. So sum becomes 0 +1 = 1 and counter becomes 1+1 = 2.

counter

sum

2

1

After the counter is modified, we reach the bottom of the while-do (note that the blocks to modify TotalLabel.Text are below the while-do loop and will not be repeated). When the bottom is reached, the app loops back up and re- tests the while test (counter<6). Now counter is 2 which is still less than 6. So we repeat the blocks within the while again. This time sum becomes 2+1=3, and counter becomes 2+1=3:

counter

sum

3

3

We loop back up and test, and counter is still less than 6. After we repeat twice more, we have:

counter

sum

5

10

When we check the test, counter (5) is less than 6, so we go in the while again. sum is changed to 15 and counter to 6:

counter

sum

6

15

Now when we loop back up and check the test, it is false. When the while test is false, we "pop out of the loop" meaning we don't again repeat the operations within it. Instead, the app jumps to the blocks below the while loop, in this case the blocks to display the sum in TotalLabel.Text. The correct value 15 is displayed and the event-handler is complete.

Computing the Sum of the first N Numbers

Changing the app so that it can add up numbers up to any number n the user enters is relatively straight forward. We just introduce another variable, n, and set it to the value of the textbox in the user interface above the while-loop. We then modify the test so that it no longer tests that the counter is less than 5, but less than n+1:

Now if the user enters a 5 in the NText text box, the variable N

Now if the user enters a 5 in the NText text box, the variable N will be set to 5 and the while-do will repeat 5 times. And in fact, the app will display 15 in the TotalLabel.Text box, just as with our previous solution.

If the user closed the app and re-started it, then typed in a 3, the app would correctly display 6 as the sum.

A Bug in the Program

Now let's consider the case when the user enters a number and clicks the SumItButton, then enters a new number and clicks it again, without restarting the app. Specifically, assume the user first enters a three and clicks, then enters a 2. After correctly answering 6 the first time, the app would report that the sum of numbers from 1 to 2 is also 6! Watson, we have a bug! Can you step through the app to see what the problem is?

The problem lies in the fact that counter and sum are only initialized when the app starts, based on the variable definitions. In our scenario, after the app correctly computes the sum of 1 to 3 as 6, the values of the variables are:

counter

sum

4

6

When the user then enters a 2 in NText and clicks the SumItButton again, those values are still in counter and sum-- they are not re-initialized, even though we really want to start over.

The solution is to initialize the variables within the event-handler so that

each time the SumItButton is clicked, the computation begins anew. Here is the fixed solution:

the computation begins anew. Here is the fixed solution: Because the initializations of counter and sum

Because the initializations of counter and sum are within the event-handler, the sum will be computed correctly every time.

Problems

1. Write a factorial(n) application.

2. Write the text all numbers in a list app using a while-do instead of a for.

Chapter 9: Web Services, APIs and Mashing Data

This chapter introduces web services, APIs, RSS, and mashups, then steps through the development of an Android app that communicates with the Twitter API.

To computer users, the web is a bunch of sites that can be visited with a browser. Programmers see things differently-- to them the web is also a huge database of information which can be collected and processed (mashed) to create new and interesting apps.

Consider, for instance, the custom bookstore sites that sell books using Amazon's database of information along with their facilities for on-line transactions.

Such custom bookstores are possible because Amazon, like many sites, provides two levels of access to information: a human interface and an application programmer interface (API):

Most of us have used the human interface by typing in amazon.com into a browser. But let's say you were a basketball enthusiast and you wanted to setup a site for selling books about basketball. You could write a web app-- a computer program-- that made calls to Amazon to perform searches and get information about particular books. Your program could organize the data, combine it with other data (e.g., pictures of NBA stars), and display that information to visitors of your "basketballBooks.com" site.

Your program would communicate with Amazon, but instead of using amazon.com, as a person would do, your program would communicate with their API interface. API stands for application programmer interface and an application programmer is one who writes apps-- the basketball store creator, in this case. An API provides for computer-computer communication, one program talking to another, as opposed to a web app, which provides for human-computer interaction.

Technically, an API is the specification that describes how your program should talk to the web service at some server's site-- the type of requests it

expects, and the format of the data that will be returned to your program. Often, the data returned is some form of extensible markup language (XML), though there are also JSON APIs. The API tells the client programmer how to communicate with the web service.

Whereas HTML is the language used when a server sends information to a browser for human consumption, XML is generally used when a server sends information to a program on another server. Both HTML and XML include data within them (e.g., book information), but HTML also has presentation information-- specifications for how the information should be displayed-- while XML does not.

Here's an example of a search at amazon.com for Books about Baseball. The search returns a page that looks like this:

Baseball. The search returns a page that looks like this: The HTML behind this page is

The HTML behind this page is extremely complex and includes both the data you see and code for styling that data (e.g., code specifying that the book images should be aligned). Here's an abridged version of the HTML code:

<html>

<head>

<style type="text/css"><!-- BODY { font-family: verdana,arial,helvetica,sans-serif; font-size: small; background-color: #FFFFFF; color: #000000; margin-top: 0px; }

<div class="productImage"><a href="http://www.amazon.com/

Baseball-Prospectus-2010/dp/0470558407/

ref=sr_1_1?ie=UTF8&s=books&qid=1264011867&sr=1-1"> <img

src="http://ecx.images-amazon.com/images/I/

51kRbJCrDoL

Details" width="115" height="115"/> </a></div> <div class="productData"> <div class="productTitle"><a href="http://www.amazon.com/Baseball-

Prospectus-2010/dp/0470558407/

ref=sr_1_1?ie=UTF8&s=books&qid=1264011867&sr=1-1"> Baseball Prospectus 2010</a> <span class="ptBrand">by Baseball Prospectus</span><span class="binding"> (<span class="format">Paperback</span> - Feb 22, 2010)</span></div>

SL160_AA115

jpg"

class="" border="0" alt="Product

The important thing to understand is that browsers understand HTML code and use all the added styling information to render a page. However, it is clear to see that extracting just the data, e.g., the title of the books, is not so easy. A computer program reading this data in order to just grab the titles would have to know within what HTML tags that data resides. The code to parse this HTML-- to extract the data- would be non-trivial. Furthermore, if the HTML styling changed, the program code to parse it would no longer work!

This is the reason many web sites provide a non-HTML API web service that returns data in some well-documented XML language. The client code can call the service with a URL, as in the following example:

http://ecs.amazonaws.com/onca/ xml?AWSAccessKeyId=1x1x1x1x1x1x1x1 1 &Keywords=baseball&Operation=ItemSe

This URL is in the same format of the URLs that humans use to navigate the human web. But instead of returning HTML, it returns XML in Amazon's (fairly) well documented API. You can see the response I got from this request here:

<ItemSearchResponse> <Items> <Item>

<ASIN>0470558407</ASIN>

<ItemAttributes> <Author>Baseball Prospectus</Author> <Manufacturer>Wiley</Manufacturer>

<ProductGroup>Book</ProductGroup> <Title>Baseball Prospectus 2010</Title> </ItemAttributes> </Item> <Item>

<ASIN>1600783554</ASIN>

<ItemAttributes> <Author>Ron Shandler</Author>

<Manufacturer>Triumph Books</Manufacturer> <ProductGroup>Book</ProductGroup>

<Title> 2010 Baseball Forecaster (Ron Shandler's Baseball Forecaster)

</Title>

</ItemAttributes>

<Items>

<ItemSearchResponse>

The response has a list of items, and each item has a set of tagged attributes including title, ISBN, etc. The XML is much easier to parse compared to HTML and the expectation is that it won't change without the source site giving ample warning (and they don't need to change it for stylistic reasons, as with the HTML interface).

So a mashup program can call the amazon API, and perhaps call other APIs such as the Google Books API or a library's API. After the program parses the XML, the various data is all stored in the program's memory. It can then process it, organize it, and eventually display it in any manner it would like. If its goal is to sell books, Amazon provides methods for allowing custom book sites to earn money on click-throughs.

Here's how product advertising works, from Amazon web site:

 

Your application uses the Product Advertising API to supply item

1

descriptions and images, and customer and seller reviews, which you present to your customers.

2

Customers shop on your web site.

 

When the customer is ready to purchase the items in their e-commerce shopping cart, your application sends an HTML form to Product Advertising

3

API and Amazon completes the purchase by getting purchase information, such as payment method and shipping address, and then Amazon fulfills the order by shipping the items.

Some APIs are simple than Amazon's. For instance, Yahoo provides financial information with a URL that returns simple comma separated data. For instance, the URL:

http://download.finance.yahoo.com/d/

quotes.csv?f=sl1d1t1c1ohgv&e=.csv&s=IBM

returns the text:

"IBM",75.97,"11/19/

2008","4:01pm",-4.11,79.93,81.00,75.73,12606807

The API specification is simply this: the commas separate these nine pieces of information:

• Ticker symbol

• Last price (after a 20-minute delay)

• Date of that price

• Time of that price

• Change since the day's opening

• Opening price

• Day's high price

• Day's low price

• Trade volume

Mashups

The term mashup perhaps originated in the music field, with Eminem's album The Slim Shady LP combining samples from various other songs and artists. Today, numerous sites like ccmixter help artists mashup samples and create new art. Combining previously created art is controversial of course, due to copyright issues. For a great introduction to the general concept of mashups and the societal implications, see Lawrence Lessig's book Remix (you can find it for free on-line at http://www.bloomsburyacademic.com/remix.htm)

Just as music can be remixed, so can web programs and information. To a programmer, a mashup is a program that takes data from multiple sources (APIs) and combines it in interesting ways. Custom bookshops that combine data from multiple APIs would be considered mashups, but there are many, many more that use APIs from all walks of life. The site http://www.programmableweb.com/ provides a dynamic list of interesting

APIs and mashups. Perhaps the most popular example, and one of the first, is housingmaps.com which combines data from craigslist.com and Google's maps API. Here's a snapshot of it showing craigslist listings plotted onto a map of San Francisco:

craigslist listings plotted onto a map of San Francisco: Tweeting Big Stock Swings To Twitter Another

Tweeting Big Stock Swings To Twitter

Another interesting example of a mashup was provided by Bob DuCharme at http://www.devx.com/webdev/Article/40511/0/page/1. Bob combined Yahoo's stock information with the Twitter API to create a mashup that twitters him when a particular stock has a swing of 50 or more points. This diagram illustrates how it works:

In this mashup, DuCharme's server program requests data from Yahoo Finance, which returns it in

In this mashup, DuCharme's server program requests data from Yahoo Finance, which returns it in comma-separated value format. His program then processes it by checking it against its previous readings. If there is more than a 50 point difference, it uses the Twitter API to change the status on his twitter page. Bob and other humans can then check his twitter page for updates.

RSS

RSS stands for Really Simple Syndication. RSS is a specific XML language that is used by most blogs and in general any service that just needs to send out a simple list of items in an XML format.

Because RSS is so common, there are many clients and code libraries for processing RSS data, so you can help people access your data by putting it in this format. Note, however, that RSS is a fixed protocol-- if you have custom data you either have to fit it into RSS fields or define your own XML schema. For instance, the XML returned by Amazon, shown above, is not in RSS because Amazon provides pricing and other information that doesn't fit into the RSS protocol.

Creating Mashups

Mashups are generally created in high-level programming languages such as Python, Java, or Perl. Most information sources generally provide client library code in these popular languages that makes data access easy. In general, however, creating mashups requires sophisticated programming knowledge.

There have been some advancement in tools for "end-user" creation of

mashups. The term end-user in this context means someone who doesn't know how to program in a traditional textual language such as Python or Java (which includes most of the world).

Yahoo Pipes is one such end-user tool. With it, you can link various web services and RSS data sources together to create mashups. Here's an example of a pipe that mashes NY City apartment information with user input:

that mashes NY City apartment information with user input: This pipe allows the user to enter

This pipe allows the user to enter a NYC neighborhood, a keyword, and a minimum distance. In the sample shown, the user is looking for apartments near a park in Manhattan.

The pipe was created without any programming, at least of the traditional

textual kind. Here is what development looks like:

textual kind. Here is what development looks like: The developer just drags in functional nodes for

The developer just drags in functional nodes for getting user input, extracting data from sources, fitering, and displaying data. In the sample, for instance, the top node prompts the user for the neighborhood (the "where"), then funnels that information to a URL builder that creates a call to the API http://newyork.backpage.com/online/exports/Rss.xml. The results are then filtered by location and another input by the user, "what" (by default, the "what" is "park", but the user can enter any place for which they'd like to find an apartment that is near).

Sergey Brin Quote, stats about more computer->computer communication than human-communication

Twitter API

Twitter has an API that return data in RSS format. For instance, one of the API commands returns the public timeline (the newest twits from the world). if you enter:

in a browser, the browser will render something like:

in a browser, the browser will render something like: This is just because most browsers will

This is just because most browsers will render RSS in a format that's nice for viewing content. Really, the RSS sent to the browser looks like:

<?xml version="1.0" encoding="UTF-8"?> <rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:georss="http://www.georss.org/georss"> <channel> <title>Twitter public timeline</title> <link>http://twitter.com/public_timeline</link> <atom:link type="application/rss+xml" href="http://twitter.com/ statuses/public_timeline.rss" rel="self"/> <description>Twitter updates from everyone!</description> <language>en-us</language>

<ttl>40</ttl>

<item> <title>Juliana_Madeira: &quot;&#201; triste pensar que a natureza fala e que o g&#234;nero humano n&#227;o a ouve.&quot; Victor Hugo</title> <description>Juliana_Madeira: &quot;&#201; triste pensar que a natureza fala e que o g&#234;nero humano n&#227;o a ouve.&quot; Victor Hugo</description> <pubDate>Wed, 20 Jan 2010 20:10:23 +0000</pubDate> <guid>http://twitter.com/Juliana_Madeira/statuses/

7998009238</guid>

<link>http://twitter.com/Juliana_Madeira/statuses/7998009238</link>

</item>

and the browser has processed it to render it.

This URL returns a particular person's friend timeline:

If you type this command in a browser, it will prompt for a valid twitter username and password. You can also enter a URL of the form:

http://username:password@twitter.com/statuses/friends_timeline.xml

replacing "username" and "password" with your own authentication.

Putting REST URLs directly in a browser gives you an idea of how an API works, but generally these requests will come not from a person, but from a program. Your program will make an HTTP request, generally using high- level "client" library code for the particular language you are using, and hiding the URL details. The library code also takes care of parsing the XML returned from the service, providing your client with an easy-to-process list of data.

An App Inventor Twitter Client for Android

An Android programmer, using the Java SDK, could communicate with any API. App Inventor, however, does not yet provide blocks for calling an arbitrary API. It does, however, provide blocks for communicating with the Twitter API.

The blocks consist of request blocks and request-received blocks. Request blocks are used to send requests to the Twitter API: a request to login, a request to get the friends_timeline, etc. Typically these requests will be

made from within some event-handler (e.g., when the user clicks a button labeled "view friends timeline".

Requests are not processed immediately-- when you request a timeline, for instance, the timeline is not provided as the return value of the block. Instead, request and reply are asynchronous. You send the request with one block, then specify an event-handler that will be triggered when the app receives the request from Twitter.

This separation of request and reply is mandated by the Android system, as Android wants apps to always be ready to respond to external events, instead of waiting for some external request to complete.

Here's some program blocks that make use of two request-->handle event sequences:

that make use of two request-->handle event sequences: In these blocks, we first make a Login

In these blocks, we first make a Login request to Twitter. While this interaction is occurring, the program could handle other user or external events. When Twitter logs the user in, it sends notification back to the phone app, and the IsLoggedIn event occurs, triggering the corresponding event- handler. The programer has set things up so that, in the handler for "IsLoggedIn", it issues another request with RequestFriendTimeline block. Once again the app is free to handle other events while Twitter is doing its job. When Twitter returns the timeline, the FriendTimelineReceived event occurs, and the program processes it by displaying the information.

Problems

0. Create a mashup using Yahoo Pipes

already, you may want to register with another account for the tutorials we'll be doing.

2. Add at least one status message on the account, and follow at least one

person and get at least one person to follow you.

3. On your phone, download an Android Twitter client and post a status

message from it. What features does the Twitter Client you chose provide? Provide a screenshot of your Twitter Client and a description of its features

4. Now create a Twitter Client of your own using App Inventor. You can do

5. Write an Android application that combines texting and twitting. For

instance, the app might text one of your friends when you've added a new status message on Twitter. You don't have to do exactly this-- be creative!

Chapter 10: Persistent Data

Most interesting apps keep track of data over time, usually in some type of database. App Inventor provides two components, TinyDB and TinyWebDB, which allow your app to put things in a database and retrieve them later. This app discusses these components.

** Note: This text was written before the TinyDB component was added to App Inventor. TinyDB lets you store/retrieve data to persistent storage that lives directly on the phone. TinyWebDB stores/retrieves to a web database. TinyDB is simpler-- you just StoreValue tag-value pairs, and call GetValue to get them back. With TinyWebDB storing is the same, but to retrieve data you request with GetValue and then let the GotValue event handle things when the data arrives. But since the data lives off the particular phone, TinyWebDB can be used for sharing amongst phones/apps (e.g., multi- player games). ** End Note **

The apps we've looked at so far have used only transient data. Transient data is short-term: it is initialized when an app begins, and it "dies" when the app ends. It exists only within a particular phone and a particular instance of an app.

Consider, for instance, the quiz app discussed previously. The quiz questions

(and answers) are stored in a list. The list of questions is always the same for every run of the app. A programmer can change the questions in App Inventor, thereby creating a new version of the app, but the end-user has no way to modify the questions or add new questions.

Now suppose you wanted a quiz app that allows one end-user (the teacher) to change or add new questions. You might envision a parent creating various quizzes for their child on a long car-trip, or a school teacher setting up quizzes for students.

Given what we've learned so far, you could write an app that allows the list of questions to be changed. The user would enter new questions and answers in text boxes, click Submit, and the event-handler would add new entries to the list. Such a scheme would work reasonably in the car-trip scenario-- with the app continually running, the parent (quiz creator) and child (quiz taker) could pass the phone back and forth.

The scheme is limited, however, because the lists in App Inventor are transient data: when the app is closed, changes to lists are not recorded. Any questions entered by the user during a single "run" of the app are lost when the app is closed, and the next time the app is opened, it will show only the questions that are fixed part of the list blocks. Furthermore, the questions entered live only on the particular phone on which they are entered. So a teacher couldn't write a quiz for her students and allow them to take the quiz on their own phones.

What our app really needs is access to a database that lives on the web some place, and that can be accessed by multiple phones.

web some place, and that can be accessed by multiple phones. Persistent data is information stored

Persistent data is information stored in a database or a file. It is persistent in that even when the user closes the app, the data lives on. An example of persistent data is your profile information on Facebook. When you submit data to Facebook, the data you submit is stored in a database on the website's servers. This data is persistent since it will be there the next time

you visit the site or run a Facebook app.

With App Inventor, list variables are not persistent, so the app cannot just put teacher-submitted questions in a list. Instead, the app must store submitted the questions in a database. This way, when a student decides to take a test, even from a different phone, it can access the updated questions from the datbase. The next section demonstrates how to store to and retrieve from a database in the App Inventor world.

TinyWebDB

App Inventor provides a component, tinywebdb, which allows for apps to store and retrieve data from a database. The component can store data on any web service that follows a particular protocol.

The TinyWebDB component is found in the Not ready for prime time drawer of the designer. When you drag a TinyWebDB component into your app, it is placed in the 'non-visual component' area.

The component has one key property: the ServiceURL. By default, the ServiceURL property is set to http://appinvtinywebdb.appspot.com, which is a test service set-up by the Google App Inventor team. This test service is shared by many and has a limit of 100 entries, but it can be used to try things out.

For production apps, you'll want to set-up a service that you don't share with other apps. For this sample, we'll use a service set up at the University of San Francisco: http://usfwebservice.appspot.com:

of San Francisco: http://usfwebservice.appspot.com : The TinyWeb DB component is straight-forward to use: you

The TinyWeb DB component is straight-forward to use: you call StoreValue to store data with a tag and value. You request previously stored data by calling GetValue and providing a tag. When your phone receives the data from a request, a GotValue event is triggered.

To illustrate how things work, we'll begin with simplified version of the quiz app, one

To illustrate how things work, we'll begin with simplified version of the quiz app, one with only one question and answer. We'll consider only a "teacher" app that allows a teacher to view and modify the stored question and answer. As an exercise, we'll consider a second app that allows a student, on the same phone or another, to take the single question quiz.

With the teacher app, suppose there are two text boxes, Question Text and AnswerText, in which the teacher enters the question and answer. When the teacher clicks submit, the text that has been input in those boxes is stored to the database using TinyWebDB.

Here are the blocks for the SubmitButton.Click event-handler:

are the blocks for the SubmitButton.Click event-handler: The blocks just call the TinyWebDB.StoreValue function

The blocks just call the TinyWebDB.StoreValue function twice, once to store the question, with a tag of "QuizQuestion", and one to store the answer, with a tag of "QuizAnswer". The value of each is the text that the user has input into the respective textbox.

This code doesn't change anything in the phone's display. Instead, its purpose is to modify the database. If the user enters "Who is the President of the U.S.?" in the QuestionText box, and "Obama" in the AnswerText box, the following entries would be put in the database:

tag

value

QuizQuestion

Who is the President?

QuizAnswer

Obama

If the user closes the app, this data remains stored in the database.

The next time the user (teacher) opens the app, the app should display what was entered previously. To facilitate this, the app calls the GetValue function in the TinyWebDB.Initialize event:

the GetValue function in the TinyWebDB.Initialize event: TinyWebDB.GetValue requests data with a given tag. Here, we

TinyWebDB.GetValue requests data with a given tag. Here, we make two requests, one for the question and one for the answer, using the same tags we used to store the data above.

The GetValue function doesn't get a result directly; it just makes a request to the TinyWebDB web service. After making the requests, the app is free to handle other events while the web service is sending the requested data.

When the the requested data arrives at the phone, a GotValue event is triggered. It in this event-handler that the app can do something with the data it requested. Here are the blocks for the GotValue event:

it requested. Here are the blocks for the GotValue event: Both the requests the app made

Both the requests the app made in the Initialize event will trigger GotValue events, so the Got-Value event-handler will be invoked twice. Because of this, the handler must first ask which data is being received. Each entry received contains both the tag and the value, so the handler can ask if the tag returned was "QuizQuestion". If it is, the app takes the value ("Who is

the President of the U.S.?") and places it in the QuestionText.Text.

If the tag is not "QuizQuestion", it must be "QuizAnswer", so in the "else-do" blocks the app places the value ("Obama") in the AnswerText.

A Quiz with Multiple Questions

Now let's extend the simple quiz application so that there are multiple question and answer pairs. We'll still focus on the teacher app for creating quizzes.

Here's a simple "teacher" interface for entering test questions:

"teacher" interface for entering test questions: Previously entered question-answer pairs will appear below

Previously entered question-answer pairs will appear below the text "Existing QAs".

The application will put entries into tinyweb db in the following the form:

tag

value

 

WolbQuiz:1

What is the capital of California:Sacramento

WolbQuiz:2

What is the capital of Washington: Olympia

Each tag consists of a keyword to identify this particular application, "WolbQuiz", along with a number that uniquely identifies the question. Later in this lesson, we'll discuss how to build the tags using text and join.

The tags must be designed so that they can be reproduced to access the data in the value field. They shouldn't contain dynamic data-- data that the user enters-- because our app doesn't know what that data will be. For

instance, you wouldn't want the question to be a tag because the questions themselves are dynamic data.

The value of each entry in our scheme has both the question and answer, with a colon separating.

The sample app in this lesson is active. You can check out the actual quiz questions by visiting the web interface to the tinywebdb service at:

http://usfwebservice.appspot.com. When you get to the page, click on getvalue and enter a tag such as "WolbQuiz:1".

Programming the Behavior of the "Teacher" Application

Following are the blocks for the teacher app:

Programming the Behavior of the "Teacher" Application Following are the blocks for the teacher app:

On start-up, the app needs to load in the questions from the database so that the teacher can see the current quiz. The strategy is to request the first question-answer pair using "WolbQuiz:1". If it returns with a value, the app requests the second question, and so on, until a request is made that doesn't not return us a valid value. For example, if there were four questions stored in the web service, our fifth request ("WolbQuiz:5") will return an empty value since there is only tags up to "WolbQuiz:4". At that point, the app knows all questions have been loaded.

The TinyWebDB.Initialize event triggers this process by calling GetValue with the first key, "WolbQuiz:1". "WolbQuiz:1" is built using a join operation: we join the text "WolbQuiz:" with the variable qnum.

join the text "WolbQuiz:" with the variable qnum . When the app begins, the variable qnum

When the app begins, the variable qnum has an initial value of 1. qnum will be incremented later so that we can access the successive questions.

Recall that the TinyWebDB.GetValue call just requests the data from the web service-- the value is not returned to the GetValue block directly. Instead, when the data arrives to the phone from the web service, a TinyWebDB.GotValue event is triggered. The blocks in that event-handler will determine what the app does with the values returned from the requests:

the app does with the values returned from the requests: In the GotValue event, the app

In the GotValue event, the app first checks to see if the value returned is the empty string (has length of 0). If so, we know that our last request was for a tag that doesn't exist in the tinywebdb web service database. This might

happen on our first request if no questions have ever been added, or it will happen on the nth request if there are n-1 questions in the database.

If the value returned is empty, this means the loading of previously recorded question-answer pairs is complete, so the app can enable the Submit button so that the user can enter new entries.

If the value returned does not have a length of 0, the app has received a valid question-answer pair, and the "else-do" blocks are executed. The first thing those blocks do is add the question-answer pair returned into ExistingLabel, which displays all of the question-answer pairs. A join is used to concatenate the previous value of ExistingLabel with a newline character ("\n") and the new question-answer pair (valueFromWebDB). So if ExistingLabel was showing:

What is the capital of California:Sacramento

and the newly accessed question was

What is the capital of Washington: Olympia

then the ExistingLabel label would be updated to:

What is the capital of California:Sacramento What is the capital of Washington: Olympia

with the second question on a separate line due to the "\n".

Besides displaying the entry received from the database, the GotValue event-handler must also request the next question (we only request the first in the Initialize event). To do this, it increments qnum and requests the next question from TinyWebDB.

Processing the Entry of New Question-Answer Pairs

The app also allows the user ("teacher") to enter new question-answer pairs. The app has two textboxes, QuestionText and AnswerText, and a SubmitButton. Recall that the GotValue event handler only enables the SubmitButton when all the question-answers from the database have been loaded, so the SubmitButton.Click event can only be triggered after that process is complete. At that point, the variable qnum is set to the number of questions that were in the database, e.g., 4. Here is the SubmitButton.Click handler:

The SubmitButton.Click event handler first builds a new question-answer pair by joining the user's input

The SubmitButton.Click event handler first builds a new question-answer pair by joining the user's input from QuestionText and AnswerText with a colon in between. It then builds the tag as was done above with "WolbQuiz:" joined with qnum, and calls TinyWebDB.StoreValue to store the new data. To keep the list of question-answer pairs being displayed up-to-date, the ExistingLabel is updated with the new entry.

Summary

With the TinyWebDB component, you can create apps that remember things-- that store things in a database. Creating such an app requires you to design how the data will be stored using the restricted key-value pairs that TinyWebDB allows. You'll need a schemes such as was used in the quiz app-- a list of items separated by ";;" with each field in the item separated by "::". Then you'll need to program the blocks so that the data is inserted and retrieved in that manner. Fortunately, the Text operations like join and split make this relatively easy.

Problems

1. Create an application that stores your vote-- whatever you enter in a

textbox-- in the usfwebservice with a tag of your first name. The application should also show you what you have previously entered (as in the sample).

2. Working with a partner or partners, have your app show the votes of

three or more people.

3. Write a quiz creator (teacher app) as described in this sample.

database.