Maps , Location and Intent Service.

Any body who has ridden the new cab services like Uber and Ola  will have noted how they show the map , routes and even notifies user of their current journey  in their apps. Today I will share a simplistic example which will show users current location on the map  and update their latitude and longitude on the server via an Intent Service.

I have mentioned intent service , as I found that there is very little awareness about the functionality of the class among the general developers.  This stackoverflow post gives a very comprehensive over view of intent service. In short it is a subclass of service which runs on its own thread and is great for doing sequential background tasks without affecting the main thread. Multiple calls to the intent service creates an internal queue which sequentially executes tasks in the order it arrives without us having to do any book keeping.

So , there 2 parts to this tutorial. One is the server part which I have hosted in Google App Engine (GAE) and is written in python using Google’s webapp2 framework.  This is basically as very simple app which receives url with latitude , longitude and a name and saves it in the Data Store. The python tutorial for GAE will cover up the basics. I will give the link to my app at the end.

The second part of course is the app. To start, I will begin with the LocationUpdates example from Android Samples.  This gives us the best practices right of the bat . The code is very simple, it uses Google Play location Services Api which automatically determines when to use Wifi/ GPS to get the best location using minimum battery. To this I added the Intent Service to save the current location data whenever it is available.

 

@Override
 protected void onHandleIntent(Intent intent) {

 Log.d(TAG, "Service Started");

 final ResultReceiver receiver = intent.getParcelableExtra("receiver");
 String latitude = intent.getStringExtra("latitude");
 String longitude = intent.getStringExtra("longitude");
 String time = intent.getStringExtra("time");

 Bundle bundle = new Bundle();

 /* Update UI: Download Service is Running */
 receiver.send(STATUS_RUNNING, Bundle.EMPTY);

 try {
 JSONObject results = uploadData(longitude,latitude,time);

 /* Sending result back to activity */
 if (null != results ) {
 bundle.putString("result", results.toString());
 receiver.send(STATUS_FINISHED, bundle);
 }
 } catch (Exception e) {

 /* Sending error message back to activity */
 bundle.putString(Intent.EXTRA_TEXT, e.toString());
 receiver.send(STATUS_ERROR, bundle);

 }
 Log.d(TAG, "Service Stopping");
 this.stopSelf();

There are couple of things to note here ,

  • The service stop itself after the task is completed and what ever code that is written in onHandleIntent runs on a separate thread from the main thread.
  • Resultreceiver , this is like a call back which is implemented by the class calling this service. This mechanism is used to respond back to the main thread about the result of the task.

Here is the implementation of the resultreceiver.

public class UploadResultReceiver extends ResultReceiver {
 private Receiver mReceiver;

public UploadResultReceiver(Handler handler) {
 super(handler);
 }

public void setReceiver(Receiver receiver) {
 mReceiver = receiver;
 }

public interface Receiver {
 public void onReceiveResult(int resultCode, Bundle resultData);
 }

@Override
 protected void onReceiveResult(int resultCode, Bundle resultData) {
 if (mReceiver != null) {
 mReceiver.onReceiveResult(resultCode, resultData);
 }
 }
}

This class basically does two things

  • It defines an interface called Receiver , which will be implemented by the main activity. The main activity will then decide what to do with the result.
  • It extends the ResultReceiver class to override the onRecieveResult method , which uses the Receiever interface defined above as a callback.

The Receiver interface is implemented by the MainActivity as follows

@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
switch (resultCode) {
case DataUploadService.STATUS_RUNNING:

Toast.makeText(this, "Upload Started", Toast.LENGTH_LONG).show();
break;
case DataUploadService.STATUS_FINISHED:
/* Hide progress & extract result from bundle */
String result = resultData.getString("result");
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
break;

case DataUploadService.STATUS_ERROR:
/* Handle the error */
String error = resultData.getString(Intent.EXTRA_TEXT);
Toast.makeText(this, error, Toast.LENGTH_LONG).show();
break;
}

Now for the map part , the first thing that needs to be done is to get the api key for the Google Maps. The steps are mentioned here https://developers.google.com/maps/documentation/android/signup

The Api key has to be used in the Manifest.xml file. The main map code is very simple . In the layout the MapFragment has to be added like so


fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_marginTop="10dip"
android:layout_alignParentLeft="true"
android:layout_below="@+id/last_update_time_label"

The same is now used in the main activity


mapFragment =
 (MapFragment) getFragmentManager().findFragmentById(R.id.map);
googleMap = mapFragment.getMap();
googleMap.setMyLocationEnabled(true);[\code]

The Update to the map is done here

1
/** Display on the map **/

double latitude = mCurrentLocation.getLatitude();
double longitude = mCurrentLocation.getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
        latLng, 15);
googleMap.animateCamera(cameraUpdate);

This shows the point on the map. Last thing about this is that I have used httpurlconnection for the network transportation
which is recommended by Google for networking over the defaulthttpclient .

The data that is uploaded can be viewed here

http://agiotesting.appspot.com/

Thats all folks!! You can download the code here .

Siyanatullah Khan

Siyanatullah Khan

Mobile Software consultant with a penchant for blogging.

More Posts

Follow Me:
TwitterLinkedInGoogle Plus

Add a Comment

HTML Snippets Powered By : XYZScripts.com