Search This Blog

Wednesday, September 22, 2010

A simple GPS monitor in j2me with google maps support.

Application without google maps : 
This is a simple application that shows the device's current location coordinates on the screen. It can be built in four easy steps - 
1)Creating a canvas for displaying results. 
2)Starting a new thread so that it doesn't slow down our application. 
3)Using Location Provider object to retrieve the coordinates. 
4)Displaying the coordinates on the canvas. 

MyCanvas a canvas inherited class, which has a paintMe() function that takes 3 parameters, can be called whenever we need to refresh the screen with new data. In this case we are not using google maps so image passed can be anything else or null. LocationProvider is a class that is used to obtain gps data from the device. 
Object of this class is initialized by setting it to LocationProvider.getInstance(Criteria) , where Criteria is a class that holds the options for the LocationProvider object. 
Examples of the options would be horizontal accuracy, vertical accuracy etc. 
See how these objects are initialized below in the GpsTracker() constructor. startApp() is the entry point for the MIDlet where we create and start a new thread. run() contains the code for the thread, where we call getLocation() of Locationprovider object which returns Location object. 
We then retrieve coordinates from the Location object by calling its getQualifiedCoordinates() method. Once we have the coordinates we can call paintMe() method of MyCanvas to refresh the page.

GpsTracker.java code :

import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.location.Coordinates;
import javax.microedition.location.Criteria;
import javax.microedition.location.Location;
import javax.microedition.location.LocationException;
import javax.microedition.location.LocationProvider;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.rms.*;

public class GpsTracker extends MIDlet implements CommandListener,Runnable {
 //Create options menu command
 Command exitCommand = new Command("Exit", Command.EXIT, 2);
 Command refreshCommand = new Command("Refresh", Command.OK, 3);
 Criteria cr= new Criteria();
 Display display;
 Displayable screen;
 LocationProvider lp;
 Location l;
 Coordinates c;
 Thread thread;
 Image image;
 MyCanvas canvas;
 byte[] byte_data;
 String url;
 HttpConnection httpConn = null;
 int respCode;

 
 public GpsTracker()  {
  display = Display.getDisplay(this);
  cr.setHorizontalAccuracy(500);
  
  try {
   lp= LocationProvider.getInstance(cr);
  } catch (LocationException e1) {
   e1.printStackTrace();
  }

  image = null;
  //Add options to menu
  canvas = new MyCanvas(image,0,0);
  canvas.addCommand(exitCommand);
  canvas.addCommand(refreshCommand);
  canvas.setCommandListener(this);
 }

 protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
  lp=null;
 }

 protected void pauseApp() {
 }

 protected void startApp() throws MIDletStateChangeException {  
  try {
   thread = new Thread(this);
   thread.start();
  } catch (Exception e) {
   e.printStackTrace();
  }  
 }
 
 public void exitCom() throws MIDletStateChangeException{
  notifyDestroyed();  
  destroyApp(true);
   }

 public void commandAction(Command command, Displayable d) {
  String label = command.getLabel();
     if(label.equals("Exit")){
       try {
   exitCom();
  } catch (MIDletStateChangeException e) {
   e.printStackTrace();
  }
     }
     
     else if(label.equals("Refresh")){
        refreshMap();
      } 
 }

 public void run() {
  try {
  //get location
  l = lp.getLocation(300);
  if(lp.getState()==LocationProvider.AVAILABLE){
  c = l.getQualifiedCoordinates();
  
  }
  } catch (Exception e) {
   e.printStackTrace();
  } 
  display.setCurrent(canvas);
 }
 
public void refreshMap(){
 try {
    l = lp.getLocation(300);
    if(lp.getState()==LocationProvider.AVAILABLE){
    c = l.getQualifiedCoordinates(); 
    coordinates="";
    image = null;
    canvas.paintMe(image,c.getLatitude(), c.getLongitude()); 
    }  
 }  catch (Exception e) {
  e.printStackTrace();
 } 
}
}

class MyCanvas extends Canvas{
   Image image = null; //the image to be set on the screen
   double lat = 0.0; //latitude
   double lon = 0.0; //longitude

   //constructor
   public MyCanvas(Image m,double lat1,double lon1){
     try{
       paintMe(m,lat1,lon1);
     }catch(Exception e){
       e.printStackTrace();
     }
   }

 //paint the screen
 protected void paint(Graphics g) {
  g.setColor(0xffffff);
     g.fillRect(0, 0, getWidth(), getHeight());

     if(image != null){
       g.drawImage(image, getWidth() / 2, getHeight() / 2, Graphics.HCENTER | Graphics.VCENTER);
       g.setColor(0x000000);
       g.drawString("Lat : " + lat + " Lon : " + lon,getWidth() / 2,getHeight() ,Graphics.HCENTER | Graphics.BASELINE);
     } else {
       g.setColor(0x000000);
    g.drawString("Lat : " + lat + " Lon : " + lon,getWidth() / 2,getHeight() ,Graphics.HCENTER | Graphics.BASELINE);
       g.drawString("GPS Monitor", getWidth() / 2, getHeight() / 2,  
       Graphics.HCENTER | Graphics.BASELINE);
     }
  
 }
 
 public void paintMe(Image m, double lat2, double lon2){
  this.image=m;
  this.lat=lat2;
  this.lon=lon2;
  repaint();
 }
}

Adding Google Maps to the Application With one more simple step google map can be displayed on the screen showing your current location. For that you need this GoogleMaps.java file, download it and include it in your project. Next you need to create an object of type GoogleMaps in you MIDlet, and you can call its retrieveStaticImage(height,width,latitude,longitude,zoom_level,image_format) method which will return the map image.

GoogleMaps map;
 Image image;
 image = map.retrieveStaticImage(480, 320, c.getLatitude(), c.getLongitude(), 14, "png");
 canvas.paintMe(image,c.getLatitude(), c.getLongitude());-->
You can pass this image to paintMe() to draw it on the screen. If you want to display additional details like marker, path etc on the map, modify GoogleMaps.java and modify the return url in getMapUrl() method.

1 comment: