Android GPS positioning without Google Maps

Don’t get me wrong, google maps are awesome! And along with maps, so is google earth. In fact, my initial dabbling into GPS tracking used google earth to display GPS co-ordinates on a map. You can see a quick example here:

 

But I also got to wondering, if it would be (easier?) possible to use a third party mapping service while achieving a look and feel which is similar to google maps. Some research quickly turned up leafletJS, and it does look like it hits the nail on the head. I decided to use OpenStreetMap as a backend. The solution was going to be web based, but since I wanted to integrate GPS positioning from my phone, it had to be a hybrid app. Good… a perfect opportunity to learn about android webviews….

The final (demo) project can be found on GitHub, so i’ll gloss over the details of getting GPS co-ordinates (there are plenty of tutorials on that online), and instead focus more on the webview part. First of all, I created a simple index page in the android assets folder, and within that same folder I placed all the necessary CSS, Javascript, and images that leafletJS and I required. The only really interesting part there is vehicleScript.js, where apart from initializing the map as per leafletJS documenation, I added my own little function:


function updateLocation(lat,lng,time){
map.panTo(new L.LatLng(lat,lng));
var marker = L.marker([lat, lng]).addTo(map);
marker.bindPopup("Your Location at Time:"+time).openPopup();
}

You can see the function accepts three values, the latitude, longitude, and time. These three values would be provided by the native android app, which i’ll explain now…

 

In the andoid main activity, you can see in lines 99-101 where I added the webview to the layout:

 

mapView = (WebView) findViewById(R.id.mapView);
mapView.getSettings().setJavaScriptEnabled(true);
mapView.loadUrl("file:///android_asset/index.html");

 

Make sure not to forget that setJavaScriptEnabled(true), else javascript will be disabled in the webview. Android does this by default for security reasons. Also note the android way of referencing the asset folder, which is file:///android_asset. The next part comes in lines 72-74, where you can see exactly how the native android app sends the latitude, longitude, and time to the webview. I register a broadcast receiver to hook into the intents broadcast by the GPS service, and we then pass the received values to the webview:

if (mapView != null){
mapView.loadUrl("javascript:updateLocation("+lat+","+lng+",\""+time.format("%d-%m-%Y %H:%M:%S")+"\")");
}

So any url that is prefixed with the javascript: will actually execute within the webview as javascript. The end result looks something like so:

The end result using leafletJS and webviews

The end result using leafletJS and webviews

Resources: