Archive for the ‘HTML5’ Category

Where Part 1 focused on non-GPS enabled devices, Part 2 is totally focused on mobile web geolocation. The great news is that the usage of HTML5 location services along-side the fact that there is a GPS chipset in most, if not all, modern smartphones and tablets dramatically improves the chances of getting an accurate location. And, besides that fact — mobile geolocation is simply a lot of fun to work with.

I also want to point out that there are an increasing number of really good blog posts covering the topic of “how to use” the API that look at the nitty-gritty of how the code works. This post is different in that I’ve tried to focus on “how to build successful applications” with the API, and how to get the most out of the API so that you can successfully implement your unique requirements.

What’s different about desktop vs. mobile HTML5 Geolocation? With mobile you can access the GPS if it’s available. It’s important to note that in order to access a device GPS you have to set the optional enableHighAccuracy property in your code. Contrary to what is shown in some samples on the internet, you can use this property with both the getCurrentPosition() and watchPosition() functions.

//One time snapshot
navigator.geolocation.getCurrentPosition(
     processGeolocation,
     // Optional settings below
     geolocationError,
     {
         timeout: 0,
         enableHighAccuracy: true,
         maximumAge: Infinity
     }
);

//Tracking users position
watchId = navigator.geolocation.watchPosition(
     processGeolocation,
     // Optional settings below
     geolocationError,
     {
         timeout: 0,
         enableHighAccuracy: true,
         maximumAge: Infinity
     }
);

How accurate is it??? This is the million dollar question, right? When using enableHighAccuracy() on a phone where all the appropriate permissions have been selected and granted, I’ve typically seen accuracy readings as low as 3 meters (~10 feet) that were obtained within 10 – 30 seconds of kicking off the geolocation functionality. I’d consider that excellent for most consumer and retail applications. You should be aware that like any location-based functionality you will get spurious (abnormal) results that fall way outside the norm, and sometimes these results are wildly wrong.

I’ve seen claims that using the enableHighAccuracy() property slows down the phones ability to deliver a location. I’m going to argue that those claims are misleading. It is true that the GPS, itself, can take a significant amount of time to warm up and start delivering high accuracy results. For an in-depth look at that topic see my post on the Six Most Common Use Cases for Android GPS. However, there are conditions where simply enabling the enableHighAccuracy() property doesn’t affect the speed in which you can get the initial result. More on these topics below.

What is the best way to try out various configuration scenarios? I’ve built an HTML5 Geolocation Testing tool that can be used in browser, or it can be repurposed to work in PhoneGap or Titanium. It is a jQuery-based mobile application that includes a map and settings view were you can adjust all the different properties and try out different configuration scenarios. It’s a work-in-progress so I welcome suggestions and pull requests.

 Why HTML5 Geolocation rather than native? Applications using HTML5 Geolocation typically have slightly different requirements than native GPS-based applications. Each platform has its advantages and disadvantages and it all comes down to your requirements, budget, timeframes and skill sets:

  • Ability to re-use existing JavaScript and HTML5 skills to build a high-accuracy mobile application.
  • Don’t have access to native platform developers or skillsets on Android, iPhone and/or Windows Phone.
  • Need a cross-platform stand-alone web app, or a web app that has been repurposed to work with PhoneGap or Titanium.
  • Quickly locate the user/consumer within a reasonable expectation of accuracy.
  • Typically it is a non-commercial, consumer grade application that does not have extremely high accuracy requirements (e.g. < 1 meter).

How fast can I get an initial location result? The answer is very fast, potentially within a few seconds, given the following scenarios:

  • If there was a cached GPS or Network location stored on the phone. The GPS location is, of course, from the GPS chipset. The Network location comes from your wireless carrier and is dependent on your phone and their capabilities.
  • How the timeout and maximumAge properties are set. If you set timeout = 0 and maximumAge = Infinity it will force the application to grab any cached location, if one is available. Other settings may result in delays.
  • If the phone or tablet has decent internet connectivity and Wifi enabled.
  • If the device is in an urban area with many wifi nodes broadcasting their SSIDs nearby.
  • The device has a clear and uninterrupted view of the sky. GPS’s listen for a very weak signal from multiple satellites. These signals can be partially or completely blocked by buildings, thick foliage, vehicle roofs, etc.

 How accurate is the initial location result? Hah, you might have guessed I’d say that it depends.  When you first kick off a geolocation request, accuracy does depend on a number of different factors that are mentioned above. And it’s safe to say that, in the vast majority of cases, the first location is not the most accurate and typically not the most dependable. If you want the fastest, most accurate location possible then you will most likely need to either do multiple snapshots, or use watchLocation until your desired level of accuracy is met. It’s important to note because I’ve been asked about this many times, you cannot expect the GPS, itself, to have enough time to lock onto a satellite and deliver a fast, accurate initial location. It may take dozens of seconds or even minutes. Yep, it’s true. Factors that affect initial location accuracy include:

  • Cached locations – how recently the user accessed location functionality. For example, applications like Facebook typically grab a location when you open the app. So frequent users of social media are more likely to have a fresh, cached location that non-social media users. If you are targeting business travelers, the cached location might the last city before they got on a plane. Or, it could be your home neighborhood and not where you work or go to games.
  • Wifi turned “on”. If the Wifi is turned on then the device can access the location service and there is a much greater chance that the initial result is fairly accurate. If you didn’t have a chance to read Part 1, when the Wifi is on your browser gathers local Wifi node information from your Wifi card, and it can use that information in a location service provider request over the internet to try and triangulate your position. Typically this means your initial location can be within a block or two of the actual position. Also, it is possible if Wifi is turned on that you can get a significantly more accurate initial location than if you were using GPS by itself with no Wifi or internet.
  • Internet connectivity strength. If you have a poor internet connection and no Wifi, then the browser’s requests to the location service can be delayed, blocked or even interrupted.
  • No VPN. Take note commercial application developers: as mentioned in Part 1, if VPN software is in use it can wildly affect accuracy and even place you in another State (or Country).

Can I use HTML5 Geolocation for mobile tracking? Yes, with caveats. Typically HTML5 tracking applications are built inside a native wrapper framework such as PhoneGap or Titanium. There are several immediate problems with stand-alone, browser-only HTML5 tracking applications. First, there is no built-in functionality to keep the screen from going to sleep. Second, when the screen goes to sleep the HTML5 Geolocation functionality also goes to sleep. Native-based tracking applications can work around these limitations and listen passively in the background when they are minimized. Third, you have little control over the GPS settings to help management battery consumption.

Can I use HTML5 Geolocation offline? Yes! If there is no cellular connection or Wifi available, then HTML5 Geolocation can still access cached locations and real-time GPS information. This is vastly different from what was discussed in Part 1 as related to applications targeted at laptops, desktops and tablets that may or may not have GPS. If a device does not have a built-in or externally available GPS then your offline application will not work.

Handling abnormal location results. Your application will occasionally encounter widely inaccurate results and you need to handle these gracefully for the best user experience possible. My recommendation is to check the timestamps and distance traveled between the current geolocation object and the previous one. If the distance or speed seems excessive then you’ll need to reject the result. In the reference section below is a link to more information on calculating the distance between two points containing latitude and longitude. As an example, see the attached screenshot with the spurious results indicated by red circles. Also note in the screenshot the accuracy level was 3 meters, so it’s important to understand that even at high accuracy levels you still need to very that each location meets your minimum requirements. This way your results will always look polished and professional to the end user.

Spurious results

What are some of the downsides of using HTML5 Geolocation versus native? The bottom line is that for simple location gathering and basic tracking HTML5 Geolocation is just fine. This should meet the requirements for most consumer applications. For anything more complex than that you should consider looking at going native.

  • It may not work on older phones and older browsers (depending on your definition of old). See below in the references section for a link to a fallback library to handle these situations.
  • HMTL5 Geolocation offers significantly less control over GPS settings. This can have an unacceptable impact on more complex applications.  Because of this, I also suggest that HTML5 Geolocation is not suitable for long-running tracking applications.
  • Battery life management. This is a direct result of bullet #2. It’s more challenging to manage battery life with HTML5 Geolocatoin if your requirements call for continuous use of the GPS.  Your control is very limited with respect to these two properties: timeout and maximumAge.
  • Cannot use it when the application is minimized. If your requirements calls for the ability to passively receive locations while in a minimized state then, as mentioned earlier, you will have to go native.
  • Very little control over how often you want location updates. You’ll need to do a bunch of custom coding to emulate what is already built into native application APIs. For example, the native Android API offers very detailed control over what type of geolocation data you can get access to, how you can access it and how often. Read more on that topic in my post on How Accurate is Android GPS Part 1 – Understanding Location Data and also take a look at Android’s LocationManager Class.

References

W3C Geolocation API Specification 

HTML5 Geolocation Test Tool

Mozilla – Using Geolocation

Calculating distance between two points.

Geolocation fallback library for older browsers

Tags: , , , , , , , ,
Posted in Browsers, HTML5, Mobile | 19 Comments »

A closer look at Base64 image performance

This post takes a closer look at Base64 image performance, offers some use cases and raises some questions. I’ve had a number of conversations recently over the benefits of using client-side, Base64 image strings to improve web app performance over making multiple <img> requests. So I ran a few tests of my own, and the results are shown at the bottom of the post.

If you aren’t familiar with them, a Base64 image is a picture file, such as a PNG, whose binary content has been translated into an ASCII String. And, once you have that string then copy-and-paste into your JavaScript code. Here’s an example of what that looks like:

<html>
<body onload="onload()">
	<img id="test"/>
	<script type="text/javascript">
		var html5BadgeBase64 = "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXH…";
		function onload(){
			var image = document.getElementById("test");
			image.src = "data:image/png;base64," + html5BadgeBase64;
		}
	</script>
</body>
</html>

There are other ways of doing this that I’m not covering in this post such as using server-side code to convert images on the fly, passing Base64 strings in URLs, etc.

The most commonly cited advantage is that including a Base64 string in your JavaScript code will save you one round-trip HTTP request. There is absolutely no argument on this subject. The real questions in my mind are: what are the optimal number and size for Base64 images? And, is there a way to quantify how much if any they help with performance?

Size? Base64 image strings will always be larger than their native counterparts. Take the following example using a copy of the relatively small HTML5 logo and a decent sized screenshot. As you can see the text equivalent is 33% and 31% greater, respectively.

Html5.png  = 1.27KB (64×64 pixels)
Html5base64.txt = 1.69KB (1738 characters)
% Difference =  +33%

Screenshot.png = 19KB (503×386 pixels 24bit)
ScreenshotBase64.txt = 24.9KB (25584 characters)
% Difference = +31%

In comparison, when working with <img> tags you’ll be working with an ID that points to the actual image file stored in memory.

Convenience? As you can see, the length of your base64 strings can get quite long. The simple HTML5 logo in the previous example becomes a 1738 character long string and that’s only 1.69KBs worth of image.

Can you imagine having a dozen of images similar in size to the 19KB Screenshot example? That would create over 300,000 ASCII characters. Let’s put that into the perspective of a Word document. Using 1” margins all the way around, this would create a document approximately seven and a quarter pages long!

I assert that Base64 is best for static images, ones that don’t change much at all over time. The bigger the image the more time consuming it can become convert it, copy-and-paste it into your code and then test it. Any time you make a change to the image you’ll have to repeat the same steps. If you accidentally inject a typo into a Base64 string you have to reconvert the image. That’s simply the best approach from a productivity perspective.

In comparison when using a regular old PNG file, you create the new version, copy it out on the web server, flush your browser cache, run a quick test with no need to change any code and bang you’re ready to go have a cup of coffee.

Caching? It depends on your header caching settings, browser settings and web server settings. I’ll just say that typically base64 images will be cached either in your main HTML file or in a separate JavaScript library.

Bandwidth? Using base64 images will increase the amount of bandwidth used by your website. Compare the size of your HTML file with Base64 images to the size of the same file simply using <img> tags. You can do some basic math if you add up the size of a particular page and multiple it by the number of visits. Better to err on the side of caution, because there really isn’t a good way to tell which images and JavaScript files are getting catched in your visitors browsers and for how often. Here’s an example where you have a 30GB bandwidth limit per month, and simply converted all of your PNG images to Base64 could very easily push you over the limit:

100,000 page hits/ month (main.html) x 256KB = 25.6 GB (incls. 75KB of standard PNG images)

100,000 page hits/month (main.html) x 293.5KB =  29.4 GB (incls. 97.5KB Base64 images)

Also, some providers give you decent tools that you can use to experiment with Base64 images versus regular images and test that against your bandwidth consumption.

Latency? This variable doesn’t really apply directly to Base64 images. There are many factors that determine latency that I’m not going to discuss here. There are some more advanced networking tools that let you figure out average latency on your own web servers. Every request will be unique based on network speed, the number of hops between the client and the web server, how the HTTP request was routed over the internet, TCP traffic over the various hops, load on the web server, etc.

A few quick performance tests.

What would a Base64 blog post be without a few tests? I devised four simple tests. One in which I referenced a JavaScript file containing Base64 images. One which contained five <img> tags and then I re-ran the tests again to view the cached performance.

These tests were performed on a Chrome Browser over a CenturyLink DSL with a download speed of 9.23MB/sec and an upload speed of 0.68MB/sec. Several tracert(s) of TCP requests from my machine to the web server showed more than 30 hops with no significant delays or reroutes. The web server is a hosted machine.

Test 1 – JavaScript file with Base64 images.This test consists of an uncached basic HTML file that references a 125KB JavaScript library containing five base64 images.

Time to load 1.9KB HTML file: 455ms

Time to load 125KB JavaScript file: 1.14s

Total load time: 1.64s

Test 2 – Cached JavaScript file with Base64 images. This test consists of reloading Test 1 in the browser

Time to load cached HTML file: 293ms

Time to load cached JavaScript file: 132ms

Total load time: 460ms

Test 3 – using <img> tags to request PNG images. This test consists of an uncached HTML file that contains five <img> tags pointing to five remotely hosted 20KB PNG files.

Time to load 1KB HTML file: 304ms:

Time to load five images: 776 ms

Total load time: 1.08s

Test 4 – cached html file using <img> tags to request PNG images. This consists of reloading Test 3 in the browser

Time to load cached HTML file: 281ms

Time to load five cached images: 16ms

Total load time: 297ms

Conclusions

It’s not 100.0000% true that multiple HTTP requests results in slower application performance in comparison to embedding Base64 images. In fact, I’ve seen anecdotal evidence of this before on production apps, so it was fun to do a some quick testing even if my tests were not completely conclusive beyond a doubt.

My goal was to spark conversation and brainstorm on ideas. I know some of you will say that thousands of tests need to be run an statistically analyzed. My argument is that these tests represented actual results that I could see with my own eyes rather than being lumped into some average or medium statistic.

Note that I’m just posting a snapshot of the tests I ran. I didn’t have enough time to draw up a significant battery of tests to cover as many contingencies as possible. However, the test numbers I’ve posted were fairly consistent in the favor of the multiple PNG requests loading faster than a single .js file containing five Base64 images. Obviously more significant testing is needed to sort out other real-world variables, such as image file sizes versus application size and under a variety of conditions and different browsers.

Resources

JavaScript library with five Base64 images

HTML file that reference JavaScript library of five Base64 images

HTML file with five <img> tags

[Edited 2/26/13: fixed a few typos]

Tags: , ,
Posted in Browsers, HTML5 | 1 Comment »

Tonight I had the pleasure of presenting at the HTML5 Denver User Group. It looked like there was a really good turnout of over 130 people. I followed an excellent presentation on JSON by Tom Marrs. He really dived down into the guts of what JSON is, and I wished someone had done as good of a job explaining it when I was just getting started using JSON.

The concept of my presentation was that there are three main approaches to building web mobile applications: JavaScript mobile, Hybrid and Responsive. By a show of hands it looked like over 50% in the audience were brand new to web mobile and I had planned for that so hopefully the level of content was just right. If you want to discuss any of the content in more detail, feel free to drop me an email.

Here’s a link to a PDF version of the presentation. 

Tags: ,
Posted in HTML5, Mobile | 2 Comments »

Dispelling Responsive App Testing Myths

There’s been a lot of buzz about Firefox’s Responsive Design View and to a lesser extent Chrome’s User Agent swapper. These built-in, ready-to-go tools are awesome and huge time savers for web developers. But, they are NOT a substitute for testing your app across multiple browsers and on different devices.

A highly simplified definition of responsive design is it lets your web app dynamically adjust content based on screen height, width and pixel density. There are over a dozen responsive frameworks including Twitter Bootstrap, 960 Grid, jQuery and Titan. The number of them has exploded in recent years and it’s a daunting task to figure out which ones meet your project’s needs. So, the intent of this blog post is to provide some super simple, quick guidelines for getting started with testing your apps against them.

What does Firefox’s Responsive Design View do? It lets you change the dimensions of your application on-the-fly and even rotate it by simply clicking a button. Very cool! It lets you pretend to see what your app will look like on different screen sizes. In the latest versions of Firefox, you can access this view via Tools > Web Developer > Responsive Design View.  See the screenshot for an example of what the tool looks like.

What does Responsive Design View not do? It does not emulate the actual functionality of browsers on different sized devices. So, simply swapping screen sizes on your Windows desktop Firefox browser is not a valid substitute for physically testing your app on a tablet or smartphone. Firefox offers a separate download for Firefox on Android if you want to test on a mobile device.

What does a user-agent do? The user-agent is intended to identify a browser to a webserver or web application. It is sent by the browser in the HTTP request header. The agent can be parsed and used to determine if any specific actions need to be taken within an application. So, if you are using Chrome you can spoof using Internet Explorer 9. Here’s an example of a user-agent for Firefox running on Windows 7 64-bit:

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0

The most common use of user-agents on webservers is for creating site visit statistics that provide a generalized break-down of site visitors by browser type.

The most common use of user-agents in web applications is for determine how content is displayed and how JavaScript may be used in that browser. If you have some JavaScript that you know won’t work in IE, then you want to try and do your best to detect specific versions of IE to control your content.

Why spoof the user-agent? Simply put, it tricks an application into being displayed based on the user-agent characteristics. The key word is “display”. The user-agent spoof does not emulate actual browser functionality. It only shows you what the app looks like if it contains browser-specific code by tricking it into thinking it’s running on a specific browser. However, to properly test full browser functionality you need an actual install of the browser on a specific device and operating system.

Is user-agent detection reliable? In general, no. User-agent detection within your code is not reliable. Because user-agents can be easily spoofed these days, it is no longer a single reliable source for determining how your application will display content. Even jQuery, for example, recommends against relying on user-agents as a sole means of determining browser type.

For JavaScript, it’s usually best to check to see what is supported by a particular JavaScript library, for example in jQuery.

$("p").html("This frame uses the W3C box model: <span>" +
jQuery.support.boxModel + "</span>");

Or, if you are building larger applications consider a special detection library like Modernizr that helps with HTML, CSS and JavaScript coding patterns.

What about CSS3 Media Queries? CSS3 Media Queries are considered to be an integral part of responsive design coding patterns. They let you use CSS to detect certain characteristics of a browser in order to adjust the styling of an application by doing things such as swapping visibility of HTML elements or even adding or removing DIVs from the layout. Using Firefox’s Responsive Design tool or Chrome’s user-agent swapper can be used to test these elements with a healthy dose of caution. You still need to do your final testing for browser-specific functionality on the respective browsers themselves. Here is an example of a media query looking for maximum and minimum screen width:

@media screen and (min-device-width:768px) and (max-device-width:1024px) {
    /* styles go here */
}

You can also run media queries from within JavaScript:

var portraitMatch = window.matchMedia("(orientation: portrait)");
portaitMatch.addListener(orientationChangeHandler);
function orientationChangeHandler() {
  if (portraitMatch.matches) {
    // Portrait orientation
  } else {
    // Landscape orientation
  }
}

Using Media Queries is considered a best practice when used in conjunction with a feature detection library such as Modernizr, or feature detection coding patterns to validate if a CSS feature works on a particular browser.  Feature detection code may be the way to go if you are only detecting a handful of CSS3 attributes and don’t need the extra weight of a full blown library like Modernizr, for example:

if (document.createElement("detect").style.borderRadius === "") {
    //TODO if borderRadius detected
}

if (document.createElement("detect").style.WebkitBorderRadius === "") {
    //TODO if webkitBorderRadius detected
}
Tags: , ,
Posted in Browsers, HTML5 | Comments Off

If you have only one web site that is built for desktop browsers then you definately need to read this post. The one-size website-fits-all days are gone along with the AMC Gremlin. Mobile is a much different world than desktop and your visitors, users and customers will know that. This post is based on a presentation that I did at GIS in the Rockies 2012, and another blog post I wrote called 3 Steps for Determining if Your Website is Mobile Ready.

The presentation mentions GIS, or Geographic Information Systems, however it applies to anyone considering mobile.

Why care about mobile? For once the internet analyst firms are clear on one thing: mobile device sales have  surpassed desktop sales world-wide, yep I mean not just in the good ol’ U.S.A, around January’ish 2012. There are more than 835 million mobile users now, and studies show that people are spending the majority of their free time using their devices. And the patterns they use to interact with the devices are becoming ingrained and, for better or for worse, expected. And that expectation has reached a fervored pitch as the iPhone fanboys (and fangirls) demonstrated when the iPhone 5 launched. Everyone wants the latest and greatest even if it’s not all that different.

What about mobile user expectations? Mobile users have significantly different expectations on performance, look-and-feel, and capabilities. There are also differences between devices, for example as you may already know an Android user interface is fairly different from iPhone. Catering to those needs will boost your chances of success. So, here’s just a sampling:

  • Many different screen sizes. Typically smaller screen sizes and a wide vareity of screen pixel densities.
  • The mouse is gone. Navigation is done using fingers for gestures such as pinch and swipe. Greasy, french fry picking fingers are much less precise than any computer mouse.
  • Less memory. Phones have less memory and they can be slower than your high-powered laptop.
  • Poor internet connection. There are no gaurantees on a mobile internet connection, unless you happen to be dragging a CAT6 ethernet cable with you everwhere you go. Connections can be spotty and 4G connections can be inconsistent.
  • Battery life is awful. If you are at a conference, for example, using the phone heavily may kill the battery in  4 – 5 hours. Tablets are typically a bit better. In comparison, desktop computers are always plugged in.
  • Not all mobile devices are the same. iPhone and iPad run a different operating system from Android. Not only are the platforms completely different underneath, but users have different expectations of each platform. You can’t share the same code between iOS and Android, or even Windows Phone.

How about those six steps you mentioned? It’s these differences that really drive the six migration steps. And, these suggestions apply to all the different approaches to mobile whether you are building for mobile web, hybrid, native or responsive*:

  1. Start prototyping today. Let your developers loose to start playing and to get an idea the capabilities of different devices and operating systems. Have them use your existing web site content.
  2. Analyze your existing website usage. Use analytics tools such as Google Analytics to analyze what browser and operating systems your visitors are using. Look to see if there are any trends related to mobile usage. If you don’t use online analytics, there are also tools that can examine your existing web site logs.
  3. Reevalute all use cases and workflows. Mobile is so different from desktop. Refresh your approach on how to work your magic in that enviroment by taking into account how people use their smartphone everyday.
  4. Expect that you will need to rewrite code. Don’t try to make the code fit if it doesn’t meet the requirements. Besides, sometimes it’s a good thing to rebuild so that you clean house and bring a fresh perspective.
  5. Buy as many devices as possible. Since all devices are different, the more you can test on the better. For example, have as many types of Android and iOS devices running different OS versions on several different cell providers.
  6. Dig deep into browser differences. All browsers are different, especially mobile browsers. Check out caniuse.com as your next new best friend.

* A short note on Responsive websites. These use CSS3 media queries to detect and control what HTML content is visible to certain devices. CSS3 is generally considered to be one of the three technologies that together make up HTML5. Those three components are HTML (version 5) + Cascading Style Sheets (version 3) +  some new JavaScript APIs. NOTE: all three of these technologies are built into the browser by the browser vendors such as Google, Mozilla, Microsoft and Apple.

Tags:
Posted in Android, HTML5, iPhone, Mobile | Comments Off

Accessing HTML5 Geolocation via ActionScript

Read on to learn how to access the HTML5 Geolocation API using ActionScript in a web app. Using the patterns below you can get access to a visitor’s approximate location in applications that run in a desktop or laptop browser. Mobile ActionScript/Flex/AIR apps have convenient, built-in access to location via the flash.sensors.Geolocation Class. However, with a web app you have to cobble together your own code using ExternalInterface.

The key to all this is using ExternalInterface’s addCallback().  This method lets you access ActionScript from JavaScript code in the wrapper HTML file, which if you didn’t know is the .html file that is used to launch Flash Player.

There are two steps to take that make it work:

Step 1. In addCallback() set the first parameter to the name of the function you will invoke in JavaScript to send data to your ActionScript method. Set the second parameter to the name of the actual ActionScript method. ActionScript will then recognize when the method specified in the second parameter is called. Essentially this sets up a listener in ActionScript.

Step 2. Set the call() method so that it invokes a public JavaScript function. When it’s done running, then you fire off the JavaScript function specified in the first parameter of addCallback().

If that doesn’t make any sense, check out the code below to see how it all fits together. Note, you can either hard code your JavaScript in the wrapper HTML file, or you can do what I do below and inject it into the DOM at runtime using the document.insertScript pattern so you know it’s always there.

public function findLocation():void
{
	if (!Geolocation.isSupported)
	{
		const  VERIFY_GEOLOCATION:String =
			"document.insertScript = function(){" +
				"verify_geolocation = function(){"+
					"var geoEnabled = false;" +
					"if(navigator && navigator.geolocation)" +
					"{" +
					"    return geoEnabled = true;" +
					"}" +
					"else{" +
					"    return geoEnabled = false;" +
					"}"+
				"}"+
			"}";

		const  GET_GEOLOCATION:String =
			"document.insertScript = function(){" +
				"get_geolocation = function(){"+
					"var mySWF = document.getElementById('YourApplicationName');"+
					"navigator.geolocation.getCurrentPosition(function(position){"+
					"     mySWF.sendGeolocationToActionScript(position);"+
					"});"+
				"}"+
			"}";

		if(ExternalInterface.available)
		{
			//load the script into DOM
			ExternalInterface.call(VERIFY_GEOLOCATION);

			//call the JS function
			var geoEnabled:Boolean = ExternalInterface.call("verify_geolocation");

			if(geoEnabled == true){
				//Load the script into DOM
				ExternalInterface.call(GET_GEOLOCATION);

				//Step 1: set the ActionScript callback
				ExternalInterface.addCallback("sendGeolocationToActionScript",geolocationResultHandler);

				//Step 2: call the JS Function
				ExternalInterface.call("get_geolocation");
			}
		}
	}
}

//Access this Handler from JavaScript
public function geolocationResultHandler(obj:Object):void
{
	//Access the HTML5 Geolocation object properties just like you would in JavaScript
	Alert.show("Latitude: " + obj.coords.latitude + ", "Longitude: " + obj.coords.longitude );
}

Test Notes:

I compiled this code using FlashBuilder 4.6 using Apache Flex 4.6. The functionality was tested on Internet Explorer 9, Chrome 21 and Firefox 14.

References:

Adobe ActionScript Reference – ExternalInterface
Adobe Help – Accessing Flex from JavaScript

Tags: , , ,
Posted in ActionScript, FlashBuilder, HTML5 | Comments Off