Sharing Data With Gestures: Corona SDK App Setup

Sharing Data With Gestures: Corona SDK App Setup

Tutorial Details
  • Technology: Corona SDK
  • Difficulty: Advanced
  • Completion Time: 45 - 60 Minutes
This entry is part 1 of 3 in the series Corona SDK: Sharing Data with Gestures

In this tutorial, we’re going to launch into a series that will allow two mobile devices to transfer information with a “Bump” gesture. This app will require a combination of client-side and server-side programming, and we’ll cover all the steps to code both aspects. From here on, this app will affectionately be referred to as “Thump.”

The main function of our “Thump” app will be the cross-device communication of data through an intermediary web server. The act of thumping two mobile devices together will appear to the end-user as local device to device communication, when in fact the web server has processed the data exchange. While the idea of local device communication may seem like the most practical approach at first, in practice it is filled with cross-platform hangups and security nightmares! So instead, we will use a Rails app hosted on the Heroku platform to handle receiving messages from our devices and delivering the message to its intended recipient.

The way this works is quite interesting. The server will essentially make an estimation of who the most likely recipient of a message will be based on a combination of GPS coordinates and a server timestamp. By simultaneously (or near simultaneously) thumping our two devices together, we will send latitude and longitude information over to the server so it can determine that our two locationally similar devices were trying to communicate with each other in something near real-time. Simple, right?

While this method isn’t exactly perfect, it does provides a statistical likelihood that our two devices intended to communicate with each other. One of the big problems with a service like this (and our app is no exception) would be an event like a tradeshow or somewhere where lots of people might be trying to “thump” all at the same time. While it may be unlikely, it could potentially allow for the transmission of a message to an unintended recipient.

We’ll start by creating some basic functionality for our mobile app. In our main.lua file, we will add some essential lines of code to get us started.

local ui = require('ui')
system.setLocationAccuracy( 10 )
local isSimulator = "simulator" == system.getInfo("environment")
local deviceId = system.getInfo("deviceID")

The first line requires that we include the UI library which greatly assists the creation of native components in Corona. This code will be included in a source-code zip file attached to this Mobiletuts+ tutorial. Next, we will set a location accuracy threshold for our devices. We need the device to try its best to get us a location within an error tolerance of no more than 10 meters. If the distance is any greater than this, we run the risk of picking up accidental thumps from devices that are not in our vicinity. To make things easier while we develop, we will detect whether our app is running in the Corona simulator or on the device. This will be to primarily prevent odd behavior from features not currently supported by the simulator. Lastly, we need to identify a device with a unique value. A deviceID like this will prevent the server from trying to deliver a message back to the device that sent it instead of the intended recipient.

local bg = display.newRect(0, 0, display.contentWidth, display.contentHeight)
local logo = display.newImageRect("logo.png", 172, 107)
logo.x = display.contentWidth / 2
logo.y = (display.contentHeight / 2) - 150

Next, we create a background rectangle that gives our app a nice, white background. The next 3 lines will display a logo in the top-center part of the screen.

local titleLabel = ui.newLabel{
        bounds = { 15, 5, 290, 55 },
        text = "Message",
        font = native.systemFontBold,
        textColor = { 12, 12, 100, 255 },
        size = 24,
        align = "center"
}
titleLabel:setReferencePoint(display.TopCenterReferencePoint)
titleLabel.y = logo.y + 60

The above code uses the UI libary’s access to the native display components for the device. In this case, we are simply displaying the word “Message” in a dark blue hue. The scope of this article doesn’t include all the intricacies of the native display library, so I suggest taking a look on the Corona site if you’re new to the SDK. The Y coordinates are being set to 60 pixels greater than the position of the logo we just displayed.

if isSimulator then
	-- Simulator (simulate the textField area)
	textField = display.newRect( 20, titleLabel.y + 60, 280, 30 )
	textField:setFillColor( 200, 200, 200 )
else
	local function fieldHandler( event )
		if ( "submitted" == event.phase ) then
			native.setKeyboardFocus( nil )
		end
	end
    textField = native.newTextField( 20, titleLabel.y + 60, 280, 30, fieldHandler )
end
textField:setReferencePoint(display.TopCenterReferencePoint)
textField.x = display.contentWidth / 2
textField.y = titleLabel.y + 60

One of the limitations of the simulator is that it cannot display all native components of mobile devices properly. To prevent it from throwing errors, we will detect if we are running the app in the simulator and display a gray box instead of an input field. This will help us with our positioning of the elements. If the app is not running in the simulator, we are going to display a native “textField” component that will allow the end user to type a message. The fieldHandler callback is necessary to detect for a phase of “submitted”, or, in other words, the user pressing the “return” button. By catching this event we can hide the keyboard after the user has finished typing their message.

local removeKeyboard = function( event )
        -- Hide keyboard
        native.setKeyboardFocus( nil )
end
bg:addEventListener( "tap", removeKeyboard )

As an added user interface bonus, we can add an event listener to our white background that waits for a “tap” event. This way, if the user taps the screen outside of the keyboard area, it will remove focus from it and cause it to disappear.

local latitudeText = ""
local longitudeText = ""
if isSimulator then
	local alert = native.showAlert( "Error", "GPS not available in Simulator" )
else
 	local locationHandler = function(event)
		latitudeText = string.format( '%.8f', event.latitude )
		longitudeText = string.format( '%.8f', event.longitude )
	end
	Runtime:addEventListener( "location", locationHandler )
end

Now on to the good stuff! First, we’ll detect whether we are running in the simulator and simply display an error message that the GPS is not available. When we are running on the device, we create a runtime listener that continuously grabs our location from the device’s location service and calls our locationHandler method with this data. We convert this down to have 8 decimal places of accuracy which should be more than accurate for our purposes.

local getThump = function(event)
	if event.isShake == true then
		local alert = native.showAlert( "Thump!", "Location: "..latitudeText..","..longitudeText.."\r\nMessage: "..textField.text, {"OK"} )
		system.vibrate()
	end
end
Runtime:addEventListener("accelerometer", getThump)

Lastly, we will create another runtime event listener that takes data from the device’s accelerometer and passes it to our method getThump. Inside this method we will detect whether the event was a “shake” event. A shake event is another name for what will happen when we “thump” two devices together in hopes of transmitting a message. Since we haven’t written our server component yet, we will simply display this data in an alert box to show that our app is working thus far. To test this out, you can simply type a message and give the device that is running the app a shake.

Next Time. . .

Stay tuned for part II of this series next week, where we will tackle the server-side functionality in Rails on Heroku!

Series NavigationSharing Data With Gestures: Rails & Heroku Setup»

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://macappsdaily.com Alex

    I’m gonna check this out when I get home. I’ll look forward to part 2 :)

  • moosc

    Great tutorial!!!
    Please more Corona tuts!

  • Bvac

    Whoa! This is exactly what I wanted to implement and I’m so glad that Corona is up to the task! Thanks for the tutorial.