This page shows how to get up and running quickly on Windows platforms using either IE or FireFox.
This example just verifies that you have the Garmin Communicator ActiveX Plugin installed and that you can communicate with it using JavaScript.
The bare minimums are:
Step-By-Step
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Check for Garmin Communicator Plugin</title>
</head>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/prototype/prototype.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDevicePlugin.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDeviceControl.js"> </script>
<script type="text/javascript">
var control;
function load() {
try {
control = new Garmin.DeviceControl();
if(control.isPluginInitialized()) {
$('message').innerHTML = "<h2>Garmin Communicator plugin version "+control.getPluginVersionString()+" found!</h2>";
}
} catch(e) {
$('message').innerHTML = "<h2>" + e.message + "</h2>";
}
}
</script>
<body onload="load()">
<h1>Check for Garmin Communicator Plugin</h1>
<div id="message"></div>
<object id="GarminActiveXControl" style="WIDTH: 0px; HEIGHT: 0px; visible: hidden" height="0" width="0" classid="CLSID:099B5A62-DE20-48C6-BF9E-290A9D1D8CB5">
<object id="GarminNetscapePlugin" type="application/vnd-garmin.mygarmin" width="0" height="0"> </object>
</object>
</body></html>The next example adds a call to unlock the plugin. This call is required before calling any other communicator methods. Normally you pass the base URL of your host site and the key obtained from Garmin, however for development on your localhost you don't need to pass any parameters. The important point about the key is that it must be verified against the exact same URL that was used to generate it. So if the key was generated using 'http://mydomain.com/', none of the following will successfully unlock the plugin:
Only 'http://mydomain.com/' will work!
Follow the steps in the last example to run this example.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Unlock the Plugin</title>
</head>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/prototype/prototype.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDevicePlugin.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDeviceControl.js"> </script>
<script type="text/javascript">
var control;
function load() {
try {
control = new Garmin.DeviceControl();
if(control.isPluginInitialized()) {
$('message').innerHTML = "<h2>Garmin Communicator plugin version "+control.getPluginVersionString()+" found!</h2>";
}
if(control.unlock("http://mydomain.com","pasteYourKeyInHere")) {
$('status').innerHTML = "The plug-in has been unlocked successfully";
} else {
$('status').innerHTML = "The plug-in was not unlocked successfully";
}
} catch(e) {
$('message').innerHTML = "<h2>" + e.message + "</h2>";
}
}
</script>
<body onload="load()">
<h1>Unlock the Plugin</h1>
<div id="message"></div>
<div id="status"></div>
<object id="GarminActiveXControl" style="WIDTH: 0px; HEIGHT: 0px; visible: hidden" height="0" width="0" classid="CLSID:099B5A62-DE20-48C6-BF9E-290A9D1D8CB5">
<object id="GarminNetscapePlugin" type="application/vnd-garmin.mygarmin" width="0" height="0"> </object>
</object>
</body></html>This example starts getting more interesting and demonstrates how to get a list of connected devices. The key point in this example is the use of call-back method to handle the plugin responses. The two steps typical of handling call-back communication with the plugin are:
var listener = Class.create();
listener.prototype = {
onFinishFindDevices: function(json) {
... }}control.register( new listener() );
Step-By-Step
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Connect to Garmin GPS Devices</title>
</head>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/prototype/prototype.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDevicePlugin.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDeviceControl.js"> </script>
<script type="text/javascript">
var control;
//create a call-back listener class
var listener = Class.create();
listener.prototype = {
initialize: function() { },
onFinishFindDevices: function(json) {
var devices = json.controller.getDevices();
var str = "<b>Devices Found: "+devices.length+"</b><ol>";
if (json.controller.numDevices > 0) {
for( var i=0; i < devices.length; i++ ) {
str += "<li>"+devices[i].getDisplayName()+"</li>";
}
str += "</ol>";
$('devices').innerHTML = str;
}
}
}
function load() {
try {
control = new Garmin.DeviceControl();
control.register(new listener());
var unlocked = control.unlock("http://mydomain.com","pasteYourKeyInHere");
$('msg').innerHTML = "<h2>Found Plugin, unlocked="+unlocked+"</h2>";
} catch(e) { alert(e); }
}
function findDevices() {
try {
control.findDevices();
} catch(e) { alert(e); }
}
</script>
<body onload="load()">
<h1>Auto Load Plugin</h1>
<div id="msg"></div>
<div id="devices"></div>
<input type="button" value="Find Devices" onclick="findDevices()">
<object id="GarminActiveXControl" style="WIDTH: 0px; HEIGHT: 0px; visible: hidden" height="0" width="0" classid="CLSID:099B5A62-DE20-48C6-BF9E-290A9D1D8CB5">
<object id="GarminNetscapePlugin" type="application/vnd-garmin.mygarmin" width="0" height="0"> </object>
</object>
</body></html>This example enters the realm of cool, allowing you to see your own track or waypoint data on a Google map. This code is closer to a real-world application, supporting progress bars and status line feedback. This code is taken from the DeviceControl API Demo which you can refer to for a running example.
The JavaScript is a little more verbose, but the methods are broken down into logical sections that taken one-at-a-time are not too hard to understand:
Using Google maps with Garmin GPS data is achieved by pointing a script reference to google.com, which contains a site-specific key (see http://www.google.com/apis/maps/signup.html to get your own) and a reference to the GoogleMapController.js, a utility for converting GPX data to GPolyline vectors among other handy things.
Step-By-Step
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Overlay Track Data on a Google Map</title>
</head>
<style type="text/css" media="all">@import "apidemo/garminGpsControlAPIDemo.css";</style>
<script src="http://maps.google.com/maps?file=api&v=2.69&key=ABQIAAAAkOp4960CVjgwg7aH_RVbsBQ8mFNy8mluGNJxasFfpjfy_rK2-hTqlIAT8DmZDqe108rJCva4VdWiGA" type="text/javascript"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/prototype/prototype.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDevicePlugin.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDeviceControl.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GoogleMapController.js"> </script>
<script type="text/javascript">
var GarminDeviceControlDemo = Class.create();
GarminDeviceControlDemo.prototype = {
////////////////////////////////////////////////////////////////////////
//prototype constructor method:
initialize: function(statusDiv, mapId) {
this.status = $(statusDiv);
this.mc = new Garmin.MapController(mapId);
this.findDevicesButton = $("findDevicesButton");
this.cancelFindDevicesButton = $("cancelFindDevicesButton");
this.deviceSelect = $("deviceSelect");
this.deviceInfo = $("deviceInfoText");
this.readDataButton = $("readDataButton");
this.cancelReadDataButton = $("cancelReadDataButton");
this.readTracksText = $("readTracksText");
this.readTracksSelect = $("readTracksSelect");
this.readWaypointsSelect = $("readWaypointsSelect");
this.progressBar = $("progressBar");
this.progressBarDisplay = $("progressBarDisplay");
this.garminController = null;
this.tracks = null;
this._intializeController();
this._setStatus("Plug-in initialized. Find some devices to get started.");
this.findDevicesButton.disabled = false;
this.findDevicesButton.onclick = function() {
this.findDevicesButton.disabled = true;
this.cancelFindDevicesButton.disabled = false;
this.garminController.findDevices();
}.bind(this)
},
////////////////////////////////////////////////////////////////////////
//Garmin.DeviceControl call-back methods:
onFinishFindDevices: function(json) {
this.findDevicesButton.disabled = false;
this.cancelFindDevicesButton.disabled = true;
if(json.controller.numDevices > 0) {
var devices = json.controller.getDevices();
this._setStatus("Found " + devices.length + " devices.");
this._listDevices(devices);
this.cancelReadDataButton.onclick = function() {
this.readDataButton.disabled = false;
this.cancelReadDataButton.disabled = true;
this._hideProgressBar();
this.garminController.cancelReadFromDevice();
}.bind(this)
this.readDataButton.disabled = false;
this.readDataButton.onclick = function() {
this.readDataButton.disabled = true;
this.cancelReadDataButton.disabled = false;
this._showProgressBar();
this.garminController.readFromDevice();
}.bind(this)
} else {
this._setStatus("No devices found.");
}
},
onStartFindDevices: function(json) {
this._setStatus("Looking for connected Garmin devices");
},
onCancelFindDevices: function(json) {
this._setStatus("Find cancelled");
},
onProgressReadFromDevice: function(json) {
this._updateProgressBar(json.progress.getPercentage());
this._setStatus(json.progress);
},
onCancelReadFromDevice: function(json) {
this._setStatus("Read cancelled");
},
onFinishReadFromDevice: function(json) {
this.readDataButton.disabled = false;
this.cancelReadDataButton.disabled = true;
this._hideProgressBar();
this._setStatus("Data read from device.");
var gpsData = json.controller.gpsData;
this._setStatus("Parsing track data...");
var factory = new Garmin.GpsDataFactory();
factory.parseGpxDocument(gpsData);
this.tracks = factory.getTracks();
this.waypoints = factory.getWaypoints();
this._setStatus(this.tracks.length + " tracks and " + this.waypoints.length + " waypoints found");
this._listTracks(this.tracks);
this._listWayPoints(this.waypoints);
},
////////////////////////////////////////////////////////////////////////
//internal utility methods:
_intializeController: function() {
try {
this.garminController = new Garmin.DeviceControl();
this.garminController.unlock("http://mydomain.com","pasteYourKeyInHere");
this.garminController.register(this);
} catch (e) {
this._setStatus(e.message);
}
},
_showProgressBar: function() {
Element.show(this.progressBar);
},
_hideProgressBar: function() {
Element.hide(this.progressBar);
},
_updateProgressBar: function(value) {
var percent = (value <= 100) ? value : 100;
this.progressBarDisplay.style.width = percent + "%";
},
_listDevices: function(devices) {
for( var i=0; i < devices.length; i++ ) {
this.deviceSelect.options[i] = new Option(devices[i].getDisplayName(),devices[i].getNumber());
if(devices[i].getNumber() == this.garminController.deviceNumber) {
this.deviceSelect.selectedIndex = i;
this._showDeviceInfo(devices[i]);
}
}
this.deviceSelect.onchange = function() {
var device = this.garminController.getDevices()[this.deviceSelect.value];
this.showDeviceInfo(device);
this.garminController.setDeviceNumber(this.deviceSelect.value);
}.bind(this)
this.deviceSelect.disabled = false;
},
_showDeviceInfo: function(device) {
this.deviceInfo.innerHTML = "Part Number:\t\t" + device.getPartNumber() + "\n";
this.deviceInfo.innerHTML += "Software Version:\t" + device.getSoftwareVersion() + "\n";
this.deviceInfo.innerHTML += "Description:\t\t" + device.getDescription() + "\n";
this.deviceInfo.innerHTML += "Id:\t\t\t" + device.getId();
},
_listTracks: function(tracks) {
this._clearTracks();
for( var i=0; i < tracks.length; i++ ) {
var trk = tracks[i];
if(trk.isDrawable()) {
this.readTracksSelect.options[i] = new Option(trk.getStartDate() + " - (" + trk.getDuration() + ")",i);
}
}
this._displayTrack(tracks[this.readTracksSelect.selectedIndex]);
this.readTracksSelect.onchange = function() {
var trk = this.tracks[this.readTracksSelect.selectedIndex];
this._displayTrack(trk);
}.bind(this)
this.readTracksSelect.disabled = false;
},
_listWayPoints: function(waypoints) {
this._clearWayPoints();
for( var i=0; i < waypoints.length; i++ ) {
var wpt = waypoints[i];
this.readWaypointsSelect.options[i] = new Option(wpt.getName(),i);
}
this.readWaypointsSelect.onchange = function() {
var wpt = this.waypoints[this.readWaypointsSelect.selectedIndex];
this._displayWayPoint(wpt);
}.bind(this)
this.readWaypointsSelect.disabled = false;
},
_clearTracks: function() {
for( var i=0; i < this.readTracksSelect.options.length; i++ ) {
this.readTracksSelect.options[i] = null;
}
},
_clearWayPoints: function() {
for( var i=0; i < this.readWaypointsSelect.options.length; i++ ) {
this.readWaypointsSelect.options[i] = null;
}
},
_displayTrack: function(track) {
this.mc.map.clearOverlays();
this.mc.centerAndScale(track.getStartLat(), track.getStartLng());
this.mc.addTrack(track);
},
_displayWayPoint: function(wpt) {
this.mc.map.clearOverlays();
this.mc.centerAndScale(wpt.getLat(), wpt.getLng());
this.mc.addWayPoint(wpt);
},
_setStatus: function(statusText) {
this.status.innerHTML = statusText;
}
};
//display is created when HTML page is loaded
var display;
function load() {
display = new GarminDeviceControlDemo("statusText", "readMap");
}
</script>
<body onload="load()">
<object id="GarminActiveXControl"
style="WIDTH: 0px; HEIGHT: 0px; visible: hidden" height="0" width="0"
classid="CLSID:099B5A62-DE20-48C6-BF9E-290A9D1D8CB5"> <object
id="GarminNetscapePlugin" type="application/vnd-garmin.mygarmin"
width="0" height="0"> </object> </object>
<h2>Overlay Track Data on a Google Map</h2>
<div id="actionStatus">
<div id="statusText">Status Text</div>
<div id="progressBar" style="display: none;" align="left">
<div id="progressWrapper"><div id="progressBarDisplay"> </div></div>
</div>
</div>
<div id="deviceBox">
<input type="button" value="Find Devices" id="findDevicesButton" disabled="true" />
<input type="button" value="Cancel Find Devices" id="cancelFindDevicesButton" disabled="true" />
<br />
<select name="deviceSelect" id="deviceSelect" disabled="true">
<option value="-1">No Devices Found</option>
</select>
<br />
<textarea id="deviceInfoText" rows="3" cols="60"></textarea>
</div>
<div id="readBox">
<input type="button" value="Read From Device" id="readDataButton" disabled="true" />
<input type="button" value="Cancel Read From Device" id="cancelReadDataButton" disabled="true" />
<br />
<select name="readTracksSelect" id="readTracksSelect" disabled="true">
<option value="-1">No Tracks Found</option>
</select>
<select name="readWaypointsSelect" id="readWaypointsSelect" disabled="true">
<option value="-1">No Waypoints Found</option>
</select>
<div id="readMap" style="width:400px; height:400px;"> </div>
</div>
</body>
</html>Next-up, sending data back to a GPS device. This example consists of a text box that contains an example GPX file and a Write To Device button. As long as the text is valid GPX it will be accepted by the device so feel free to put your own data here. You can try this functionality out first on the API Demo page. The code is very similar to the last example and we'll leave it to you to read through it. Enjoy...
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Write GPX Data to Garmin GPS</title>
</head>
<style type="text/css" media="all">@import "apidemo/garminGpsControlAPIDemo.css";</style>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/prototype/prototype.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDevicePlugin.js"> </script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDeviceControl.js"> </script>
<script type="text/javascript">
var GarminDeviceControlDemo = Class.create();
GarminDeviceControlDemo.prototype = {
////////////////////////////////////////////////////////////////////////
//prototype constructor method:
initialize: function(statusDiv, mapId) {
this.status = $(statusDiv);
this.findDevicesButton = $("findDevicesButton");
this.cancelFindDevicesButton = $("cancelFindDevicesButton");
this.deviceSelect = $("deviceSelect");
this.deviceInfo = $("deviceInfoText");
this.writeDataButton = $("writeDataButton");
this.cancelWriteDataButton = $("cancelWriteDataButton");
this.writeDataText = $("writeDataText");
this.writeDataFilename = $("writeDataFilename");
this.progressBar = $("progressBar");
this.progressBarDisplay = $("progressBarDisplay");
this.garminController = null;
this.tracks = null;
this._intializeController();
this._setStatus("Plug-in initialized. Find some devices to get started.");
this.findDevicesButton.disabled = false;
this.findDevicesButton.onclick = function() {
this.findDevicesButton.disabled = true;
this.cancelFindDevicesButton.disabled = false;
this.garminController.findDevices();
}.bind(this)
},
////////////////////////////////////////////////////////////////////////
//Garmin.DeviceControl call-back methods:
onFinishFindDevices: function(json) {
this.findDevicesButton.disabled = false;
this.cancelFindDevicesButton.disabled = true;
if(json.controller.numDevices > 0) {
var devices = json.controller.getDevices();
this._setStatus("Found " + devices.length + " devices.");
this._listDevices(devices);
this.cancelWriteDataButton.onclick = function() {
this.writeDataButton.disabled = false;
this.cancelWriteDataButton.disabled = true;
this._hideProgressBar();
this.garminController.cancelWriteToDevice();
}.bind(this)
this.writeDataButton.disabled = false;
this.writeDataButton.onclick = function() {
this.writeDataButton.disabled = true;
this.cancelWriteDataButton.disabled = false;
this._showProgressBar();
this.garminController.writeToDevice(this.writeDataText.value, this.writeDataFilename.value);
}.bind(this);
} else {
this._setStatus("No devices found.");
}
},
onStartFindDevices: function(json) {
this._setStatus("Looking for connected Garmin devices");
},
onCancelFindDevices: function(json) {
this._setStatus("Find cancelled");
},
//The device already has a file with this name on it. Do we want to override? 1 is yes, 2 is no
onWaitingWriteToDevice: function(json) {
if(confirm(json.message.getText())) {
this._setStatus('Overwriting file');
json.controller.respondToMessageBox(true);
} else {
this._setStatus('Will not be overwriting file');
json.controller.respondToMessageBox(false);
}
},
onProgressWriteToDevice: function(json) {
this._updateProgressBar(json.progress.getPercentage());
this._setStatus(json.progress);
},
onFinishWriteToDevice: function(json) {
this._hideProgressBar();
this._setStatus("Data written to the device.");
this._hideProgressBar();
this.writeDataButton.disabled = false;
this.cancelWriteDataButton.disabled = true;
},
////////////////////////////////////////////////////////////////////////
//internal utility methods:
_intializeController: function() {
try {
this.garminController = new Garmin.DeviceControl();
this.garminController.unlock("http://mydomain.com","pasteYourKeyInHere");
this.garminController.register(this);
} catch (e) {
if(e == "OutOfDatePluginException") {
alert("Plug-in out of date");
} else if(e == "PluginNotInstalledException") {
alert("Plug-in not installed");
} else if(e == "BrowserNotSupportedException") {
alert("Browser not supported");
} else {
alert("Error initializing - " + e);
}
}
},
_showProgressBar: function() {
Element.show(this.progressBar);
},
_hideProgressBar: function() {
Element.hide(this.progressBar);
},
_updateProgressBar: function(value) {
var percent = (value <= 100) ? value : 100;
this.progressBarDisplay.style.width = percent + "%";
},
_listDevices: function(devices) {
for( var i=0; i < devices.length; i++ ) {
this.deviceSelect.options[i] = new Option(devices[i].getDisplayName(),devices[i].getNumber());
if(devices[i].getNumber() == this.garminController.deviceNumber) {
this.deviceSelect.selectedIndex = i;
this._showDeviceInfo(devices[i]);
}
}
this.deviceSelect.onchange = function() {
var device = this.garminController.getDevices()[this.deviceSelect.value];
this._showDeviceInfo(device);
this.garminController.setDeviceNumber(this.deviceSelect.value);
}.bind(this)
this.deviceSelect.disabled = false;
},
_showDeviceInfo: function(device) {
this.deviceInfo.innerHTML = "Part Number:\t\t" + device.getPartNumber() + "\n";
this.deviceInfo.innerHTML += "Software Version:\t" + device.getSoftwareVersion() + "\n";
this.deviceInfo.innerHTML += "Description:\t\t" + device.getDescription() + "\n";
this.deviceInfo.innerHTML += "Id:\t\t\t" + device.getId();
},
_setStatus: function(statusText) {
this.status.innerHTML = statusText;
}
};
//display is created when HTML page is loaded
var display;
function load() {
display = new GarminDeviceControlDemo("statusText", "readMap");
}
</script>
<body onload="load()">
<object id="GarminActiveXControl" style="WIDTH: 0px; HEIGHT: 0px; visible: hidden" height="0" width="0" classid="CLSID:099B5A62-DE20-48C6-BF9E-290A9D1D8CB5">
<object id="GarminNetscapePlugin" type="application/vnd-garmin.mygarmin" width="0" height="0"> </object>
</object>
<h2>Write GPX Data to Garmin GPS</h2>
<div id="actionStatus">
<div id="statusText">Status Text</div>
<div id="progressBar" style="display: none;" align="left">
<div id="progressWrapper"><div id="progressBarDisplay"> </div></div>
</div>
</div>
<div id="deviceBox">
<input type="button" value="Find Devices" id="findDevicesButton" disabled="true" />
<input type="button" value="Cancel Find Devices" id="cancelFindDevicesButton" disabled="true" />
<br />
<select name="deviceSelect" id="deviceSelect" disabled="true">
<option value="-1">No Devices Found</option>
</select>
<br />
<textarea id="deviceInfoText" rows="3" cols="60"></textarea>
</div>
<div id="writeBox">
<input type="button" value="Write To Device" id="writeDataButton" disabled="true" />
<input type="button" value="Cancel Write To Device" id="cancelWriteDataButton" disabled="true" />
<br />
Filename: <input type="text" id="writeDataFilename" value="test.gpx"><br />
Write Contents:<br />
<textarea id="writeDataText" name="writeDataText" rows="21" cols="75">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="mymy">
<metadata>
<link href="http://www.garmin.com">
<text>Garmin International</text>
</link>
<time>2006-12-23T02:02:36Z</time>
</metadata>
<wpt lat="37.778721" lon="-122.414819">
<name>Burger King</name>
<desc>1200 Market St
San Francisco, CA 94102</desc>
<sym>Fast Food</sym>
</wpt>
<wpt lat="37.867791" lon="-122.499298">
<ele>19.35</ele>
<name>Motionbased</name>
<sym>Waypoint</sym>
</wpt>
</gpx>
</textarea>
</div>
</body>
</html>