





















































In this article by Leon Anavi, author of the Tizen Cookbook, we will cover the following topics:
(For more resources related to this topic, see here.)
The data provided by the hardware sensors of Tizen devices can be useful for many mobile applications. In this article, you will learn how to retrieve the geographic location of Tizen devices using the assisted GPS, to detect changes of the device orientation and motion as well as how to integrate map services into Tizen web applications.
Most of the examples related to maps and navigation use Google APIs. Other service providers such as Nokia HERE, OpenStreetMap, and Yandex also offer APIs with similar capabilities and can be used as an alternative to Google in Tizen web applications.
It was announced that Nokia HERE joined the Tizen association at the time of writing this book. Some Tizen devices will be shipped with built-in navigation applications powered by Nokia HERE. The smart watch Gear S is the first Tizen wearable device from Samsung that comes of the box with an application called Navigator, which is developed with Nokia HERE. Explore the full capabilities of Nokia HERE JavaScript APIs if you are interested in their integration in your Tizen web application at https://developer.here.com/javascript-apis.
OpenStreetMap also deserves special attention because it is a high quality platform and very successful community-driven project. The main advantage of OpenStreetMap is that its usage is completely free. The recipe about Reverse geocoding in this article demonstrates address lookup using two different approaches: through Google and through OpenStreetMap API.
By following the provided example in this recipe, you will master the HTML5 Geolocation API and learn how to retrieve the coordinates of the current location of a device in a Tizen web application.
Ensure that the positioning capabilities are turned on. On a Tizen device or Emulator, open Settings, select Locations, and turn on both GPS (if it is available) and Network position as shown in the following screenshot:
Enabling GPS and network position from Tizen Settings
Follow these steps to retrieve the location in a Tizen web application:
function showError(err) { console.log('Error ' + err.code + ': ' + err.message); }
function showLocation(location) { console.log('latitude: ' + location.coords.longitude + ' longitude: ' + location.coords.longitude); }
function retrieveLocation() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(showLocation, showError); } }
retrieveLocation();
The getCurrentPosition() method of the HTML5 Geolocation API is used in the retrieveLocation() function to retrieve the coordinates of the current position of the device. The functions showLocation() and showError() are provided as callbacks, which are invoked on success or failure. An instance of the Position interface is provided as an argument to showLocation(). This interface has two properties:
The getCurrentPosition() method accepts an instance of the PositionOptions interface as a third optional argument. This argument should be used for setting specific options such as enableHighAccuracy, timeout, and maximumAge. Explore the Geolocation API specification if you are interested in more details regarding the attributes of the discussed interface at http://www.w3.org/TR/geolocation-API/#position-options.
There is no need to add any specific permissions explicitly in config.xml. When an application that implements the code from this recipe, is launched for the first time, it will ask for permission to access the location, as shown in the following screenshot:
A request to access location in Tizen web application
If you are developing a location-based application and want to debug it using the Tizen Emulator, use the Event Injector to set the position.
A map view provided by Google Maps JavaScript API v3 can be easily embedded into a Tizen web application. An internet connection is required to use the API, but there is no need to install an additional SDK or tools from Google. Follow these instructions to display a map and a marker:
<access origin="*" subdomains="true"></access>
<style type="text/css"> #map-canvas { width: 320px; height: 425px; } </style> <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=<API Key>&sensor=false"></script> Replace <API Key> in the line above with the value of the key obtained on the previous step. <script type="text/javascript"> function initialize(nLatitude, nLongitude) { var mapOptions = { center: new google.maps.LatLng(nLatitude, nLongitude), zoom: 14 }; var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions); var marker = new google.maps.Marker({ position: new google.maps.LatLng(nLatitude, nLongitude), map: map }); } </script>
<div id="map-canvas"></div>
initialize(51.501725, -0.126109);
The following screenshot demonstrates a Tizen web application that has been created by following the preceding guidelines:
Google Map in Tizen web application
Combine the tutorial from the How to do it section of the recipe with these instructions to display a map with the current location.
A source code of a simple Tizen web application is provided alongside the book following the tutorial from this recipe. Feel free to use it as you wish.
More details are available in the W3C specification of the HTML5 Geolocation API at http://www.w3.org/TR/geolocation-API/.
To learn more details and to explore the full capabilities of the Google Maps JavaScript API v3, please visit https://developers.google.com/maps/documentation/javascript/tutorial.
Navigation is another common task for mobile applications. The Google Directions API allows web and mobile developers to retrieve a route between locations by sending an HTTP request. It is mandatory to specify an origin and a destination, but it is also possible to set way points. All locations can be provided either by exact coordinates or by address. An example for getting directions and to reach a destination on foot is demonstrated in this recipe.
Before you start with the development, register an application and obtain API keys:
For more information about the API keys for the Directions API, please visit https://developers.google.com/maps/documentation/directions/#api_key.
Use the following source code to retrieve and display step-by-step instructions on how to walk from one location to another using the Google Directions API:
<access origin="*" subdomains="true"></access>
<ul id="directions" data-role="listview"></ul>
function showDirections(data) { if (!data || !data.routes || (0 == data.routes.length)) { console.log('Unable to provide directions.'); return; } var directions = data.routes[0].legs[0].steps; for (nStep = 0; nStep < directions.length; nStep++) { var listItem = $('<li>').append($( '<p>' ).append(directions[nStep].html_instructions)); $('#directions').append(listItem); } $('#directions').listview('refresh'); }
function retrieveDirection(sLocationStart, sLocationEnd){ $.ajax({ type: 'GET', url: 'https://maps.googleapis.com/maps/api/directions/json?', data: { origin: sLocationStart, destination: sLocationEnd, mode: 'walking', sensor: 'true', key: '<API key>' },
Do not forget to replace <API key> with the Key for server apps value provided by Google for the Directions API. Please note that a similar key has to be set to the source code in the subsequent recipes that utilize Google APIs too:
success : showDirections, error : function (request, status, message) { console.log('Error'); } }); }
retrieveDirection('Times Square, New York, NY, USA', 'Empire State Building, 350 5th Avenue, New York, NY 10118, USA');
The first mandatory step is to allow access to the Tizen web application to Google servers. After that, an HTML unordered list with ID directions is constructed. An origin and destination is provided to the JavaScript function retrieveDirections(). On success, the showDirections() function is invoked as a callback and it loads step-by-step instructions on how to move from the origin to the destination. The following screenshot displays a Tizen web application with guidance on how to walk from Times Square in New York to the Empire State Building:
The Directions API is quite flexible. The mandatory parameters are origin, destination, and sensor. Numerous other options can be configured at the HTTP request using different parameters. To set the desired transport, use the parameter mode, which has the following options:
By default, if the mode is not specified, its value will be set to driving.
The unit system can be configured through the parameter unit. The options metric and imperial are available. The developer can also define restrictions using the parameter avoid and the addresses of one or more directions points at the waypoints parameter. A pipe (|) is used as a symbol for separation if more than one address is provided.
An application with similar features for getting directions can also be created using services from Nokia HERE. The REST API can be used in the same way as Google Maps API. Start by acquiring the credentials at http://developer.here.com/get-started.
An asynchronous HTTP request should be sent to retrieve directions. Instructions on how to construct the request to the REST API are provided in its documentation at https://developer.here.com/rest-apis/documentation/routing/topics/request-constructing.html.
The Nokia HERE JavaScript API is another excellent solution for routing. Make instances of classes Display and Manager provided by the API to create a map and a routing manager. After that, create a list of way points whose coordinates are defined by an instance of the Coordinate class. Refer to the following example provided by the user's guide of the API to learn details at https://developer.here.com/javascript-apis/documentation/maps/topics/routing.html.
The full specifications about classes Display, Manager, and Coordinate are available at the following links:
All details, options, and returned results from the Google Directions API are available at https://developers.google.com/maps/documentation/directions/.
Geocoding is the process of retrieving geographical coordinates associated with an address. It is often used in mobile applications that use maps and provide navigation. In this recipe, you will learn how to convert an address to longitude and latitude using JavaScript and AJAX requests to the Google Geocoding API.
You must obtain keys before you can use the Geocoding API in a Tizen web application:
For more details regarding the API keys for the Geocoding API, visit https://developers.google.com/maps/documentation/geocoding/#api_key.
Follow these instructions to retrieve geographic coordinates of an address in a Tizen web application using the Google Geocoding API:
<access origin="*" subdomains="true"></access>
function retrieveCoordinates(data) { if (!data || !data.results || (0 == data.results.length)) { console.log('Unable to retrieve coordinates'); return; } var latitude = data.results[0].geometry.location.lat; var longitude = data.results[0].geometry.location.lng; console.log('latitude: ' + latitude + ' longitude: ' + longitude); }
function geocoding(address) { $.ajax({ type: 'GET', url: 'https://maps.googleapis.com/maps/api/geocode/json?', data: { address: address, sensor: 'true', key: '<API key>' },
As in the previous recipes, you should again replace <API key> with the Key for server apps value provided by Google for the Geocoding API.
success : retrieveCoordinates, error : function (request, status, message) { console.log('Error: ' + message); } }); }
geocoding('350 5th Avenue, New York, NY 10118, USA');
The address is passed as an argument to the geocoding() function, which sends a request to the URL of Google Geocoding API. The URL specifies that the returned result should be serialized as JSON. The parameters of the URL contain information about the address and the API key. Additionally, there is a parameter that indicates whether the device has a sensor. In general, Tizen mobile devices are equipped with GPS so the parameter sensor is set to true.
A successful response from the API is handled by the retrieveCoordinates() function, which is executed as a callback. After processing the data, the code snippet in this recipe prints the retrieved coordinates at the console. For example, if we provide the address of the Empire State Building to the geocoding() function on success, the following text will be printed: latitude: 40.7481829 longitude: -73.9850635.
Reverse geocoding, also known as address lookup, is the process of retrieving an address that corresponds to a location described with geographic coordinates.
The Google Geocoding API provides methods for both geocoding as well as reverse geocoding. In this recipe, you will learn how to find the address of a location based on its coordinates using the Google API as well as an API provided by OpenStreetMap.
Same keys are required for geocoding and reverse geocoding. If you have already obtained a key for the previous recipe, you can directly use it here again. Otherwise, you can perform the following steps:
If you need more information about the Geocoding API keys, visit https://developers.google.com/maps/documentation/geocoding/#api_key.
Follow the described algorithm to retrieve an address based on geographic coordinates using the Google Maps Geocoding API:
<access origin="*" subdomains="true"></access>
function retrieveAddress(data) { if (!data || !data.results || (0 == data.results.length)) { console.log('Unable to retrieve address'); return; } var sAddress = data.results[0].formatted_address; console.log('Address: ' + sAddress); }
function reverseGeocoding(latitude, longitude) { $.ajax({ type: 'GET', url: 'https://maps.googleapis.com/maps/api/geocode/json?', data: { latlng: latitude+','+longitude, sensor: 'true', key: '<API key>' }, Pay attention that <API key> has to be replaced with the Key for server apps value provided by Google for the Geocoding API: success : retrieveAddress, error : function (request, status, message) { console.log('Error: ' + message); } }); }
reverseGeocoding('40.748183', '-73.985064');
If an application developed using the preceding source code invokes the reverseGeocoding() function with latitude 40.748183 and longitude -73.985064, the printed result at the console will be: 350 5th Avenue, New York, NY 10118, USA. By the way, as in the previous recipe, the address corresponds to the location of the Empire State Building in New York.
The reverseGeocoding() function sends an AJAX request to the API. The parameters at the URL specify that the response must be formatted as JSON. The longitude and latitude of the location are divided by commas and set as a value of the latlng parameter in the URL.
OpenStreetMap also provides a reverse geocoding services. For example, the following URL will return a JSON result of a location with the latitude 40.7481829 and longitude -73.9850635:
http://nominatim.openstreetmap.org/reverse?format=json&lat=40.7481829&lon=-73.9850635
The main advantage of OpenStreetMap is that it is an open project with a great community. Its API for reverse geocoding does not require any keys and it can be used for free.
Leaflet is a popular open source JavaScript library based on OpenStreetMap optimized for mobile devices. It is well supported and easy to use, so you may consider integrating it in your Tizen web applications. Explore its features at http://leafletjs.com/features.html.
This recipe is dedicated to a method for calculating the distance between two locations. The Google Directions API will be used again. Unlike the Getting directions recipe, this time only the information about the distance will be processed.
Just like the other recipe related to the Google API, in this case, the developer must obtain the API keys before the start of the development. Please follow these instructions to register and get an appropriate API key:
If you need more information about the API keys for Directions API, visit https://developers.google.com/maps/documentation/directions/#api_key.
Follow these steps to calculate the distance between two locations:
<access origin="*" subdomains="true"></access>
function retrieveDistance(data) { if (!data || !data.routes || (0 == data.routes.length)) { console.log('Unable to retrieve distance'); return; } var sLocationStart = data.routes[0].legs[0].start_address; var sLocationEnd = data.routes[0].legs[0].end_address; var sDistance = data.routes[0].legs[0].distance.text;
console.log('The distance between ' + sLocationStart + ' and ' + sLocationEnd + ' is: ' + data.routes[0].legs[0].distance.text); }
function checkDistance(sStart, sEnd) { $.ajax({ type: 'GET', url: 'https://maps.googleapis.com/maps/api/directions/json?', data: { origin: sStart, destination: sEnd, sensor: 'true', units: 'metric', key: '<API key>' },
success : retrieveDistance, error : function (request, status, message) { console.log('Error: ' + message); } }); }
checkDistance('Plovdiv', 'Burgas');
Geographical coordinates can also be provided as arguments to the function checkDistance(). For example, let's calculate the same distances but this time by providing the latitude and longitude of locations in the Bulgarian cities Plovdiv and Burgas:
checkDistance('42.135408,24.74529', '42.504793,27.462636');
The checkDistance() function sends data to the Google Directions API. It sets the origin, the destination, the sensor, the unit system, and the API key as parameters of the URL. The result returned by the API is provided as JSON, which is handled in the retriveDistance() function.
The output in the console of the preceding example, which retrieves the distance between the Bulgarian cities Plovdiv and Burgas, is The distance between Plovdiv, Bulgaria and Burgas, Bulgaria is: 253 km.
For all details about the Directions API as well as a full description of the returned response, visit https://developers.google.com/maps/documentation/directions/.
This recipe offers a tutorial on how to detect and handle device motion in Tizen web applications. No specific Tizen APIs will be used. The source code in this recipe relies on the standard W3C DeviceMotionEvent, which is supported by Tizen web applications as well as any modern web browser.
Please follow these steps to detect device motion and display its acceleration in a Tizen web application:
<p>X: <span id="labelX"></span></p> <p>Y: <span id="labelY"></span></p> <p>Z: <span id="labelZ"></span></p>
function showError(err) { console.log('Error: ' + err.message); }
function motionDetected(event) { var acc = event.accelerationIncludingGravity; var sDeviceX = (acc.x) ? acc.x.toFixed(2) : '?'; var sDeviceY = (acc.y) ? acc.y.toFixed(2) : '?'; var sDeviceZ = (acc.z) ? acc.z.toFixed(2) : '?'; $('#labelX').text(sDeviceX); $('#labelY').text(sDeviceY); $('#labelZ').text(sDeviceZ); }
function deviceMotion() { try { if (!window.DeviceMotionEvent) { throw new Error('device motion not supported.'); } window.addEventListener('devicemotion', motionDetected, false); } catch (err) { showError(err); } }
deviceMotion();
The deviceMotion() function registers an event listener that invokes the motionDetected() function as a callback when device motion event is detected. All errors, including an error if DeviceMotionEvent is not supported, are handled in the showError() function. As shown in the following screenshot, the motionDetected() function loads the data of the properties of DeviceMotionEvent into the HTML5 labels that were created in the first step. The results are displayed using standard units for acceleration according to the international system of units (SI)—metres per second squared (m/s2). The JavaScript method toFixed() is invoked to convert the result to a string with two decimals:
A Tizen web application that detects device motion
Notice that the device motion event specification is part of the DeviceOrientationEvent specification. Both are still in draft. The latest published version is available at http://www.w3.org/TR/orientation-event/.
The source code of a sample Tizen web application that detects device motion is provided along with the book. You can import the project of the application into the Tizen IDE and explore it.
In this recipe, you will learn how to monitor changes of the device orientation using the HTML5 DeviceOrientation event as well as get the device orientation using the Tizen SystemInfo API. Both methods for retrieving device orientation have advantages and work in Tizen web applications. It is up to the developer to decide which approach is more suitable for their application.
Perform the following steps to register a listener and handle device orientation events in your Tizen web application:
function showError(err) {
console.log('Error: ' + err.message);
}
function orientationDetected(event) {
console.log('absolute: ' + event.absolute);
console.log('alpha: ' + event.alpha);
console.log('beta: ' + event.beta);
console.log('gamma: ' + event.gamma);
}
function deviceOrientation() {
try {
if (!window.DeviceOrientationEvent) {
throw new Error('device motion not supported.');
}
window.addEventListener('deviceorientation', orientationDetected, false);
} catch (err) {
showError(err);
}
}
deviceOrientation();
If DeviceOrientationEvent is supported, the deviceOrientation() function binds the event to the orientationDetected() function, which is invoked as a callback only on success. The showError() function will be executed only if a problem occurs.
An instance of the DeviceOrientationEvent interface is provided as an argument of the orientationDetected() function. In the preceding code snippet, the values of its four read-only properties absolute (Boolean value, true if the device provides orientation data absolutely), alpha (motion around the z axis), beta (motion around the x-axis), and gamma (motion around the y axis) are printed in the console.
There is an easier way to determine whether a Tizen device is in landscape or portrait mode. In a Tizen web application, for this case, it is recommended to use the SystemInfo API.
The following code snippet retrieves the device orientation:
function onSuccessCallback(orientation) {
console.log("Device orientation: " + orientation.status);
}
function onErrorCallback(error) {
console.log("Error: " + error.message);
}
tizen.systeminfo.getPropertyValue("DEVICE_ORIENTATION", onSuccessCallback, onErrorCallback);
The status of the orientation can be one of the following values:
Tizen is famous for its excellent support of HTML5 and W3C APIs. The standard Vibration API is also supported and it can be used in Tizen web applications. This recipe offers code snippets on how to activate vibration on a Tizen device.
if (navigator.vibrate) {
navigator.vibrate(3000);
}
if (navigator.vibrate) {
navigator.vibrate(0);
}
navigator.vibrate([]);
The W3C Vibration API is used through the JavaScript object navigator. Its vibrate() method expects either a single value or an array of values. All values must be specified in milliseconds. The value provided to the vibrate() method in the preceding example is 3000 because 3 seconds is equal to 3000 milliseconds.
The W3C Vibration API allows advanced tuning of the device vibration. A list of time intervals (with values in milliseconds), during which the device will vibrate, can be specified as an argument of the vibrate() method. For example, the following code snippet will make the device to vibrate for 100 ms, stand still for 3 seconds, and then again vibrate, but this time just for 50 ms:
if (navigator.vibrate) {
navigator.vibrate([100, 3000, 50]);
}
In this article, we learned the details of various hardware sensors such as the GPS, accelerometer, and gyroscope sensor. The main focus of this article was on location-based services, maps, and navigation.