Social Icons

No Text While Driving

No Text While Driving

App Inventor Classic • App Inventor Classic • FOR APP INVENTOR 2 CLICK HERE• App Inventor Classic • App Inventor Classic

This information pertains to App Inventor 1 (Classic). For tutorials about App Inventor 2, go to the App Inventor 2 Tutorials.

Download Refined Version (Book Chapter PDF)

This tutorial demonstrates how an app can respond to text messages automatically. You'll build an app that sends back a response when a text message is received. The idea for the app came from University of San Franciso student Daniel Finnegan.

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.If you are not familiar with the basics, try stepping through some of the basic tutorials before continuing.

Getting Started

Connect to the App Inventor web site and start a new project. Name it NoTextWhileDriving, and also set the screen's Title to "NoTextWhileDriving". Open the Blocks Editor and connect to the phone.

Introduction

You'll design the app so that it sends a response to any text message received. You'll also allow the user to customize the response sent.

The tutorial introduces the following App Inventor concepts:

  • The Texting component for sending texts and processing received texts.
  • The TinyDB database component for saving the customized message even after the app is closed.

Set up the Components

The user interface for NoTextWhileDriving is simple: it has a text box for the response message and a button for submitting a change to this message. It also has two checkboxes: one to decide whether or not you want to be receiving messages and one to choose to enable Google Voice. This is useful for texting if your phone doesn't have a SIM card. Visit the Texting over Google Voice tutorial to learn more about this.

You'll also need a Texting component and a TinyDB component, both of which will appear in the "non-visual" component area. A table of detailed instructions for designing the components is below, but you can also build it from the following picture of what it should look like:

The components listed below were used to create the designer window shown above. Drag each component from the Palette into the Viewer and name it as specified below:

Component Type Palette Group What you'll name it Purpose of Component Component Settings
Label Basic PromptLabel Let the user know how the app works Set the Text to "The text below will be sent in response to all texts while this app is running."
Label Basic ResponseLabel Displays what text will be sent to incoming messages.
TextBox Basic NewResponseTextbox User will enter custom response here Set the Hint

to "Enter custom response."

Button Basic SubmitResponseButton User clicks this to submit new response Set the text

to "Submit Response."

CheckBox Basic CheckBoxReceivingEnabled Let the user choose if they want to receive messages.
CheckBox Basic CheckBoxGvEnabled Let the user choose if they want to respond using Google Voice.
Texting Social Texting1 The component that processes the texts
TinyDB Basic TinyDB1 The component that will store the response in the database

Add behaviors to the components

NoTextWhileDriving has the following behaviors:

  1. When a text is received, the message displayed in ResponseLabel is sent as a text message response to the sender.
  2. When the user modifies the custom message in NewResponseTextbox and clicks the SubmitResponseButton , the new message is saved persisently in the phone's database.
  3. When the app begins, the custom message is loaded from the database into ResponseLabel.

1. Responding to a text

When a text message is received by the phone, the Texting.MessageReceived event is triggered. Your app should handle this event by setting the PhoneNumber and Message properties of the Texting component appropriately and sending the response text.

You'll need the following blocks:

Block type Drawer Purpose
Texting1.MessageReceived Texting1 Event-handler triggered when the phone receives a text
set Texting1.PhoneNumber to Texting1 Set the PhoneNumber property before sending
value number My Definitions This is the phone number of the person who sent the text
set Texting1.Message to Texting1 Set the Message property before sending
ResponseLabel.Text ResponseLabel This is the message the user has entered
Texting1.SendMessage Texting1 Send the message

The blocks should look like this:

How the Blocks Work

When the phone receives any text message, the Texting1.MessageReceived event is triggered. The phone number of the sender is in the argument number, and the sender's message is in the argument messageText.

In response, the app sends a text message to the sender. To send a text, the app sets the two key properties of the Texting component: PhoneNumber and Message. Texting.PhoneNumber is set to the number of the sender, and Texting.Message is set to the text in ResponseLabel -- this might be the default, "I'm driving right now, I'll contact you shortly.", or the user may have modified it. Once these properties are set, Texting1.SendMessage is called to actually send the response text message.

The if block prevents the app from sending the automatic reply if it receives its own message. This would happen, for example, if the user is texting their own number to test the app.

Test the behavior. You'll need a second phone to test this behavior. From the second phone, send a text to the phone that is running the app. You can set up one phone with Google Voice or start two emulators to communicate with one another to test this behavior. Does the second phone receive the response text? If that works, try modifying the response message and sending another message from the second phone. Is the new response sent?

2. Storing the custom response

The app so far works, but if you close the app and reopen it, the custom message will be lost. To make things more convenient for the user, store the custom response message they enter into a database using the TinyDB component.

TinyDB provides two blocks: StoreValue and GetValue . The former allows you to store a tagged piece of information, while the latter let's you retrieve one.

You'll need the following blocks to store the custom message:

Block type Drawer Purpose
SubmitResponseButton.Click SubmitResponseButton User clicks this button to submit new response message
ResponseLabel.Text ResponseLabel Sets the response to be what the user inputs.
NewResponseTextbox.Text NewResponseTextbox The response message entered by the user is here
TinyDB1.StoreValue TinyDB1 Store the custom message in the phone's database
text ("responseMessage") Text Use this as the tag for the data
ResponseLabel.Text ResponseLabel The response message entered by the user is displayed here after the user submits their new response.

The blocks should look like this:

How the Blocks Work

When the user clicks the SubmitResponseButton, the app will store the response message entered by the user as the shown text that will be sent. The text in this label (ResponseLabel.Text) will be stored in TinyDB. The text responseMessage is used as a tag to uniquely identify the information-- later, you'll use that same tag to retrieve the message from the database.

3. Retrieving the saved response message

Program the Screen1.Initialize event-handler so that the saved custom response message is retrieved from the database and placed in ResponseLabel. Check the retrieved data to make sure there's something there-- after all, the first time the app is used, the database will not have any message saved. If there is a stored message, place it in the ResponseLabel so that the user can see it and so that it will be used to respond to incoming texts.

You'll need the following blocks:

Block type Drawer Purpose
def variable ("response") Definitions A temporary variable to hold the retrieved data
text (blank) Text Initial value for the variable can be anything
Screen1.Initialize Screen1 This is triggered when app begins
Texting1.ReceivingEnabled Texting1 Sets the app so that it receives SMS text messages
number (3) Number The app is initialized to receive text messages while the app is running or when it's not
CheckBoxGvEnabled.Checked CheckBoxGvEnabled Sets status of the Google Voice Enabled checkbox
Texting1.GoogleVoiceEnabled Texting1 If Google Voice is enabled, SMS messages will be sent over Google Voice
if else test Control To ask if texting should be enabled.
not= block Math Check if the retrieved value is not equal to (=) 1
Texting1.ReceivingEnabled Texting1 Lets the user decide whether or not the app will received SMS messages
CheckBoxReceivingEnabled.Checked(x2) CheckBoxReceivingEnabled Sets status of the Receiving Enabled checkbox.
true Logic Sets the app to receive text messages
false Logic Sets the app to not receive text messages
set Response Definitions Sets the variable to the value retrieved from db.
TinyDB1.GetValue TinyDB1 Get the stored response text from the database
text ("responseMessage") Text Plug into tag slot of GetValue, make sure text is same as was used in StoreValue above
if test Control To ask if the retrieved value has some text
> block Math Check if length of retrieved value is greater than (>) 0
length test Text Check if length of retrieved value is greater than 0
global response (x2) My Definitions This variable holds the value retrieved from GetValue
number (0) Math To compare with length of response
set ResponseLabel.Text to Message If we retrieved something, place it in ResponseLabel

The blocks should look like this:

How the Blocks Work

When the app begins, the Screen1.Initialize event is triggered. The app calls the TinyDB1.GetValue with a tag of responseMessage-- the same tag used when you stored the user's entry earlier. The resulting value is placed in the variable response. When the app starts, we set the Texting component to have receiving enabled, but not Google Voice, which is displayed on the user interface. ReceivingEnabled takes a number value 1 (receiving disabled), 2 (receiving enabled while app is running), or 3 (receiving enabled when app is running and is not running)

The variable response is used so that the value returned from the database can be checked. If it has a length of 0, then there was no database entry with a tag of responseMessage-- something that will occur the first time a user runs this app. But if the length is greater than 0, the app knows that a custom response has been stored previously, and the retrieved value can be placed in the ResponseLabel which the user will see and which is used as the message for any response texts sent.

Test the app. Enter a new response message in the NewResponseTextbox and click the SubmitResponseButton. Then restart the app by clicking the Restart App button in the Blocks Editor. This will cause the app to re-initialize just like it will when a user closes the app and reopens it later. Does the custom message you entered appear?

Selecting Response Settings

The user interface has two checkboxes that the user can toggle: whether Receiving is enabled and whether Google Voice is enabled. The first allows the user to decide whether or not they want to be receiving messages. The second lets the user decide if they want to send messages from their own phone number or from a Google Voice account. When the user toggles these switches, the changes are communicated to the Texting component which enables or disables these properties as marked.

You'll need the following blocks.

Block type Drawer Purpose
CheckBoxGvEnabled.Changed CheckBoxGvEnabled Detects if the user toggles this control.
Texting1.GoogleVoiceEnabled Texting1 Sets whether or not Google Voice is enabled
CheckBoxGvEnabled.Checked CheckBoxGvEnabled Returns true or false value.
CheckBoxReceivingEnabled.Changed CheckBoxReceivingEnabled Detects if the user toggles this control.
if else block Control Checks whether or not receiving is enabled.
= block Math Checks whether or not receiving is enabled.
true Logic Checks whether or not receiving is enabled.
CheckBoxReceivingEnabled.Checked CheckBoxReceivingEnabled Returns true or false value.
Texting1.ReceivingEnabled(x2) Texting1 Sets whether or not receiving is enabled.
number(1) Math Sets ReceivingEnabled as false.
number(3) Math Sets ReceivingEnabled as true.

The blocks should look like this:

Test the app. Try texting your Android device when the "Receiving Enabled" is checked and then when it is not checked. Do you receive texts when it is unchecked? Try texting over Google Voice. If any of these features aren't working like you expect them to, go back and look at the blocks again!

No Text While Driving, Final Program

Variations

Once you get the No Text While Driving app working, you might want to explore some variations. For example,

  • Write a version that speaks the received texts aloud. You'll need to use the TextToSpeech component.
  • Write a version that lets the user define custom responses for particular phone numbers.
  • Write a version that sends custom responses based on the user's location (e.g., I'm in church...)

Review

Here are some of the ideas covered in this tutorial:

  • The Texting component can be used both to send text messages and process the ones that are received.
  • The TinyDB component is used to store information persistently, in the phone's database, so that it there each time the app is opened.

Scan the Sample App to your Phone

Scan the following barcode onto your phone to install and run the sample app.

Or download the apk

Download Source Code

If you'd like to work with this sample in App Inventor, download the source code to your computer, then open App Inventor, go to the My Projects page, and choose More Actions | Upload Source.

MIT and Google are grateful to Professor David Wolber, CS Professor at The University of San Francisco, for developing this tutorial.

Done with No Text While Driving? Return to the other tutorials here.

Tutorial Version: 

Tutorial Difficulty: 

  • Advanced

Tutorial Type: 

  • SMS Texting
  • Data Storage