How do I get the Location and use the Digital Compass?

This lesson describes how to detect the location, heading, acceleration and rotation of a mobile device, using the built in GPS, accelerometer and digital compass hardware. GPS hardware is required for location support, an accelerometer is required for acceleration support and a digital compass is required for heading and rotation support. Screen captures and source code are provided.

Introduction

The iOS and Android engine can track the location, heading, acceleration and rotation of a device, if GPS, accelerometer and digital compass hardware are available. LiveCode commands can start, stop and capture relevant position and heading information that can then be used in your application.

From time to time, an iOS device may request to calibrate the compass hardware. LiveCode provides a feature to set the timeout for the calibration request or probe the current timeout value.

Note: This lesson assumes that your device has GPS, accelerometer and digital compass hardware.

Download the sample stack from this url: https://tinyurl.com/yc2uq5mm

A Simple Test Interface

A Simple Test Interface

Create a simple application interface, as is show in the figure of this section. The interface consists of eight buttons and a text field. The buttons control the activation of tracking location, heading, acceleration, rotation rate and the timeout settings. The text field displays the location, heading, acceleration, rotation rate and error information from the device.

You can select which sensor you would like to access by selecting the sensor option from the button that displays the label "Location". Selecting this button opens a combo box that provides a selection of sensors that can be accessed.

The stack card contains the following five message handlers that update the text field:

on rotationRateChanged
	put the params & return before field "log"
end rotationRateChanged

on locationChanged
	put the params & return before field "log"
end locationChanged

on headingChanged
	put the params & return before field "log"
end headingChanged

on accelerationChanged
	put the params & return before field "log"
end accelerationChanged

on trackingError
	put the params & return before field "log"
end trackingError

Testing for Location Tracking Support

Testing for Location Tracking Support

Button "Test for Support" tests whether or not the device provides support for the sensor selected by the top right button. The code on the button script is as follows:

on mouseUp
	if mobileSensorAvailable (the label of button "sensor") is true then
		answer the label of button "sensor" && "Tracking is Supported." with "Okay"
	else
		answer the label of button "sensor" && "Tracking is not Supported." with "Okay"
	end if
end mouseUp

This calls function mobileSensorAvailable() that returns either true or false. Depending on the name of the sensor type passed in to this function, the result may vary. Not all devices support all sensors that are accessible via LiveCode.

Getting Location Information

Getting Location Information

Button "Start Tracking" informs LiveCode that the selected sensor should start to collect data. The code of that button is as follows:

on mouseUp
	mobileStartTrackingSensor the label of button "sensor", the hilited of button "Loosely"
end mouseUp

Note: mobileStartTrackingSensor may request permission from the user to access the GPS hardware, depending on how the system preferences have been set up.

If location tracking cannot be started, either because device support is not available or because the user denied access to GPS information then a trackingError message is sent.

In this example, once the location is being tracked, LiveCode sends locationChanged messages to your stack, each time a change in location is detected.

Sensor tracking can be halted by selecting button "Stop Tracking", which has the following code:

on mouseUp
	mobileStopTrackingSensor the label of button "sensor"
end mouseUp

You can request sensor information directly, without having to process the changed messages. This is implemented under button "Get Current Reading" with the following code:

on mouseUp
	get mobileSensorReading(the label of button "sensor", true) 
	if it is an array then
		combine it using return and "="
	end if
	put "Current Reading" && it & return before field "log"
end mouseUp

mobileSensorReading ("location", true) returns an array with the following information:

  • horizontal accuracy – The maximum error in meters of the position indicated by longitude and latitude.
  • latitude – The latitude of the current location, measured in degrees relative to the equator. Positive values indicate positions in the Northern Hemisphere, negative values indicate positions in the Southern Hemisphere.
  • longitude – The longitude of the current location, measured in degrees relative to the zero meridian. Positive values extend east of the meridian, negative values extend west of the meridian.
  • vertical accuracy – The maximum error in meters of the altitude value.
  • altitude – The distance in meters of the height of the device relative to sea-level. Positive values extend upward of sea-level, negative values downward.
  • timestamp – the time at which the measurement was taken, in seconds since 1970.

Note: If the latitude and longitude could not be measured, then those keys, together with the horizontal accuracy key are not present. If the altitude could not be measured, then that key together with the vertical accuracy are not be present.

Test for Heading Tracking Support

Test for Heading Tracking Support

Select "Heading" from the top right button and then press button "Test for Support". This test whether your device supports heading data. Similarly, by selecting acceleration and rotation rate, you can test for the availability of the other sensor types.

Note: Digital compass support is only available in iOS 4.0 and later.

Getting Heading Information

Getting Heading Information

Button "Start Tracking", in conjunction with the selection of "Heading" informs LiveCode that heading information should be collected. The code of that button is as follows:

If heading tracking cannot be started, then the headingError message is sent.

Once the heading is being tracked, LiveCode sends headingChanged messages to your stack, each time a change in heading is detected.

Heading tracking can be halted by selecting button "Stop Tracking", that has the following code:

You can request heading information outside of the headingChanged messages that are sent when heading changes are detected. This is implemented under button "Get Current Reading".

mobileSensorReading ("heading", true) returns an array with the following information:

  • accuracy – The maximum deviation (measured in degrees) between the reported heading and true geomagnetic heading. The lower the value, the more accurate the reading.
  • magnetic heading – The heading (measured in degrees) relative to magnetic north.
  • true heading – The heading (measured in degrees) relative to true north. If the true heading could not be calculated (usually due to location tracking not being enabled, or lack of calibration), then this key is not present.
  • heading – The true heading, if available, otherwise the magnetic heading.
  • x, y, z – The geomagnetic data (measured in microtesla) for each of the x, y, and z axes.
  • timestamp – the time at which the measurement was taken, in seconds since 1970.

Note: In order to calculate the true heading, location tracking must be enabled simultaneously with heading tracking.

Other Sensor Support

In addition to location and heading, LiveCode also supports acceleration and rotation rate.

The detailed reading for these sensors returns the following information:

mobileSensorReading ("acceleration", true) returns an array with the following information:

  • x, y, z – The acceleration in for each of the x, y, and z axes.
  • timestamp – the time at which the measurement was taken, in seconds since 1970.

mobileSensorReading ("rotation rate", true) returns an array with the following information:

  • x, y, z – The change in rotation for each of the x, y, and z axes.
  • timestamp – the time at which the measurement was taken, in seconds since 1970.

Setting the Calibration Timeout Value

Setting the Calibration Timeout Value

An iOS device may sometimes prompt the user to calibrate the magnetometer in order to provide reliable heading information. This feature is turned off by default and will not allow the user to be prompted, if a calibration may be required.

A timeout delay in seconds can be set using iphoneSetHeadingCalibrationTimeout. This allows the device to prompt the user to perform a calibration, should one be needed. If the timeout delay is set to 0, no calibration requests are permitted. Values greater than 0 specify the duration for which the calibration request prompt is displayed. The message is automatically dismissed, if the user does not respond to the message in the time set by the timeout.

The following code allows the user to set the timeout delay:

on mouseUp
	ask question "What Timeout do You want?" with "10" titled "Heading Calibration Timeout"
	if it is an integer then
		iphoneSetHeadingCalibrationTimeout it
	end if
end mouseUp

Getting the Calibration Timeout Value

Getting the Calibration Timeout Value

The value of the timeout delay can be returned using iphoneHeadingCalibrationTimeout().

on mouseUp
	local tResult
	put iphoneHeadingCalibrationTimeout() into tResult
	if tResult is a number then
		answer "Heading Calibration Timeout is set to:" && tResult with "Okay"
	else
		answer "No Heading Calibration Timeout available." with "Okay"
	end if
end mouseUp

15 Comments

Thomas McGrath III

As is the stack included with this lesson does not report heading information. I downloaded and selected my provisioning profile and built the standalone. When I select the "Test for Heading Support" It is confirmed yet no data is collected after selecting the "Start Heading Tracking" and then selecting the "Get Current Heading".

I am able to get the heading to work in other stacks.

LiveCode 5.0.2 (1469)
iPhone4 (not 4S)
xCode 4.2 (4D199)
iOS 5.0.1 (9A405)

Hanson Schmidt-Cornelius

Hi Thomas,

thank you for your comment. An updated version of the stack is now available for download.

Kind Regards,

Hanson

genie

When is "on trackingError" triggered? Is it triggered when device goes out of coverage area such as where GPS cannot be tracked?

Thanks,
Genie

Hanson Schmidt-Cornelius

Hi Genie,

the "trackingError" is not specific to GPS and is also triggered by the acceleration and rotation sensors.

Reasons for a GPS error could be that the sensor has just been started, the user denied use of it or your device could not receive a signal.

Kind Regards,

Hanson

Lungile

If I am able to use GPS navigation on an Android phone, does that not mean mobile tracking is allowed on the phone?

When I test for mobile Sensor to check for support, it gives a not supported message. I'm not sure why because my phone has GPS navigation.

Hanson Schmidt-Cornelius

Hi Lungile,

have you tested if mobile tracking is permitted for the application you created?

Kind Regards,

Hanson

Lungile

Hi Hanson

Yes, everything is working perfectly now. Thank you very much.

Kind regards
Lungile

Jack

Everytime I try to save this as a Standalone Android APK using Windows 7 I get told not supported on this platform

What's wrong?

Hanson Schmidt-Cornelius

Hi Jack,

yes, you would get that message if you are trying to build an iOS standalone from Windows. The reason you were getting that message is because the standalone application settings were set to build for iOS. Unsetting an iOS build target from Windows can be challenging.
I have uploaded a new version of the stack that is set to build for Android by default.
Anyone who is loading the stack on a Mac can set the build target to iOS if they like.

Kind Regards,

Hanson

Andres

I have a Samsung J5 2016 (Android 6) smartphone mobile and have GPS, but this sample says that GPS is not supported on my phone?
Thank you

simon

What's the best way to retrieve just on member of the array returned when getting the sensor with mobileSensorReading ("location", true)?
In other words let say after executing the above command I just want to retrieve the timestamp of the reading. How should I do it?
Thanks

Elanor Buchanan

Hi Simon

As mobileSensorReading ("location", true) returns an array you can access any specific key using array notation e.g.

put mobileSensorReading ("location", true) into tDetails
put tDetails["timestamp"] into tTimestamp

I hope that helps.

Elanor

simon

Thanks Elanor that's perfect. Another great LC feature.
I should have thought about this...
Regards

Simon Schvartzman

Hi Elanor, many thanks for your clarification. I wonder if you have seen any script that would calculate the speed the GPS is traveling (by car) using the GPS data. The one I have developed so far gives me pretty unstable results. I saw a few old posts on the forum regarding the subject but none was conclusive. Regards

Elanor Buchanan

Hi Simon,

The location sensor will actually return a speed component in the correct circumstances, if there is not a measurable speed the key will not be included in the array.

This was added in LiveCode 6.0

https://quality.livecode.com/show_bug.cgi?id=10635

But there is a bug reported against the documentation for mobileSensorReading and mobileCurrentLocation, specifically that this is not documented.

https://quality.livecode.com/show_bug.cgi?id=16662

If that is not helpful I think the best option is to use the Haversine formula, although this will not be very accurate for driving on roads.

I hope that helps.

Kind regards

Elanor

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.