- Introduction
- Design of Native Mobile Apps with Mapping Features
- Details of Mobile Mapping Within Embedded Browsers
- Running the Mobile Map Apps in Emulators of Eclipse and Xcode
- Wrapping Up
Details of Mobile Mapping Within Embedded Browsers
Now let's jump right into implementing a simple map and embedding it in browsers. To explain how to implement mobile mapping using the Google Maps JavaScript API within embedded browsers, I've broken the process into three main steps:
- Create a map using the Google Maps JavaScript API.
- Embed the map in the WebView browser on Android.
- Embed the map in the UIWebView browser on iPhone.
The following sections provide the details of each of these main steps.
Step 1: Create a Map Using Google Maps JavaScript API
In June 2010, the Google Maps JavaScript API celebrated its fifth birthday. The most heavily trafficked API on the Web, this API provides a fully interactive mapping experience (that is, you can click, drag, and zoom the maps). It's the default choice of hundreds of thousands of developers for their mapping requirements, both on the Web and in mobile applications.
The original family of Google Maps APIs is renowned for innovation and rich feature sets, but the newly graduated Google Maps JavaScript API v3 has been rewritten from the ground up to provide better support for modern mobile browsers. In addition to giving end users a great mobile experience with improved performance, it's amazingly flexible and simple for developers to use.
Let's walk through the simple steps of creating your first map. You'll need just a few lines of HTML and JavaScript:
- Load the Google Maps JavaScript API v3 with the following code:
- Set up a div (here, ID map_canvas) where you'll render map tiles:
- Define a function (initialize in this example) that will be called when the document loads:
- Inside the function, specify a map option (I chose type ROADMAP and zoom level 14), create a map object using the map option, and render it inside the map_canvas div:
- Center the map at a predefined initial location.
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>
<div id="map_canvas" style="width:100%; height:100%"></div>
<body style="margin:0px; padding:0px;" onload="initialize()">
function initialize() { var myOptions = { zoom: 14, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); map.setCenter(initialLocation); }
That's it! You have a clickable, draggable, and zoomable map!
Often it's useful for mobile applications to detect the latitude and longitude of a mobile user automatically, so consider taking advantage of the W3C geolocation method supported by advanced browsers such as Safari. You can query a user's location info directly in JavaScript:
// Safari supports the W3C Geolocation method if(navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude); map.setCenter(initialLocation); }, function() { // not supported });
This code centers the map at the current location of a mobile user. Inspect the code to see how easy it is to do[md]it even works on desktop browsers that support it. (To see it in action from your desktop browser, grant permission to share your location.)
New breeds of browsers (desktop or mobile) that support HTML5 and Google APIs make it possible for developers to implement very sophisticated mobile apps. Adrian Graham's blog post "Google APIs + HTML5 = A New Era of Mobile Apps" sheds light on many advanced techniques, such as pre-fetching using local storage, app caching, and geolocation using the Google Maps JavaScript API for both desktop and mobile web.
Now that we have a basic map working, let's move along to see how to embed the map into Android and iPhone native apps.
Step 2: Embed the Map in the WebView Browser on Android
For this part of the process, we'll create a native Android app, customize the layout and set up a WebView, and embed the map inside:
- Create a native Android app by extending from the ubiquitous Activity class:
- To embed your custom map into the Android app, define an instance of WebView in your new MyMapActivity class; then declare a constant string MAP_URL to point to the URL of your map:
- Now you need to implement a custom version of the onCreate method (called when the activity is first created) by specifying the main layout of your mobile app, calling a method setupWebView (details to follow), and setting a device orientation:
- The method setupWebView implements the details of instantiating the webView based on a predefined layout, enabling JavaScript, and setting a WebViewClient to load the map using the loadUrl method of webView:
public class MyMapActivity extends Activity { }
private WebView webView; private static final String MAP_URL = "http://bit.ly/aw2bxu";
public class MyMapActivity extends Activity { private WebView webView; private static final String MAP_URL = "http://bit.ly/aw2bxu"; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setupWebView(); this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } }
/** Sets up the WebView object and loads the URL of the page **/ private void setupWebView(){ webView = (WebView) findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); webView.setWebViewClient(new WebViewClient()); webView.loadUrl(MAP_URL); }
This code snippet for loading a map in an embedded browser is generic for loading any web pages inside native Android apps, independent of any specifics of mapping logic. By separating the mapping logic from loading, I've made it straightforward for you to replicate the process in other mobile devices, as long as the embedded browser is supported.
Now let's look at how to load your map inside a native iPhone app.
Step 3: Embed the Map in the UIWebView Browser on iPhone
Similar to the process for the native Android app just discussed, this process requires only a few straightforward steps:
- In a native iPhone application, you typically create a class by extending from UIViewController in the header file. Declare a UIWebView instance variable webView as your embedded browser:
- In the main implementation file, customize the viewDidLoad method by adding the following code:
@interface MyMapController : UIViewController { IBOutlet UIWebView *webView; }
- (void) viewDidLoad { NSString *url = @"http://bit.ly/aw2bxu"; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]]; [webView loadRequest:request]; [super viewDidLoad]; }
Upon completion of the viewDidLoad message, when the method is called, the app creates a request object pointing to your map URL and calls the loadRequest method of the webView to load your map.
Notice that loading of the web page inside UIWebView is independent of any specifics of mapping logic, just as with the Android code in the preceding section.