JSR 179 - Location API
In devices where JSR 179 - Location API is implemented, there's no need to directly use JSR 82 (Bluetooth API) to read location data, since the Location API does all the necessary work for retrieval of the location data itself:- Searching the GPS module in the BT local area
- Pairing with GPS device
- Retrieval of positioning data
- Parsing of low-level NMEA sentences, turning them into high-level Java objects.
JSR 82 - Bluetooth API
If your device does not implement JSR 179, you'll still be able to retrieve location data from a Bluetooth GPS module, but you'll have to do it manually. For that, you need to perform the following tasks:To read location information from a bluetooth GPS, we need to implement the following tasks:
- Search for the Bluetooth GPS device
- Connect to the GPS device
- Read and Parse NMEA sentences
For the purpose of reading data from the BT-GPS lets create an GpsBt class. The first thing to do is to create some variable to store the URL address for your BT-GPS.
// current bluetooth device public String btUrl = ""; public String btName = ""; public void setDevice(String btUrl, String btName) { this.btUrl = btUrl; this.btName = btName; }Now we need to connect to the device and start reading the data.
public void start() { if (isActive) { stop(); } connect(); if (isConnected) { isActive = true; Thread t = new Thread(this); t.start(); } } public void connect() { if (btUrl == null || (btUrl.trim().compareTo("") == 0)) { isConnected = false; return; } try { conn = (StreamConnection) Connector.open(btUrl, Connector.READ_WRITE); in = new DataInputStream(conn.openInputStream()); isConnected = true; mode = 0; } catch (IOException e) { close(); } } public void run() { isActive = true; while (isActive) { // check if connection is still open if (!isConnected && isActive) { // connect to gps device connect(); } else { // read NMEA Strings readNMEASentences(); } } close(); isActive = false; }
As you may have noticed I'm implementing the reading loop using a thread. The reason for this, is that the BT-GPS is always sending data so you need to keep read from it before the connection buffer overflows. The data the BT-GPS sends are NMEA sentences, these sentences gives several information about the GPS status. The one we are searching for is the GPGGA sentence that gives essential fix data and provides 3D location and accuracy data.
public void readNMEASentences() { try { if (!isConnected) { return; } // check characters available int size = in.available(); if (size <= 0) { return; } // read data for (int j = 0; j < size; j++) { int i = in.read(); if (i != -1) { char l = (char) i; switch (mode) { case (STATE_SEARCH_SENTENCE_BEGIN): { // search for the sentence begin if (l == '$') { // found begin of sentence mode = 1; sb.setLength(0); } } break; case (STATE_READ_DATA_TYPE): { // check what kind of sentence we have sb.append(l); if (sb.length() == 6) { if (sb.toString().startsWith("GPGGA")) { mode = STATE_READ_SENTENCE; sb.setLength(0); } else { mode = STATE_SEARCH_SENTENCE_BEGIN; sb.setLength(0); } } } break; case (STATE_READ_SENTENCE): { // read data from sentence sb.append(l); if ((l == 13) || (l == 10) || (l == '$')) { mode = STATE_SEARCH_SENTENCE_BEGIN; currentInfo = new String(sb.toString()); } } break; } } else { close(); } } } catch (Exception e) { close(); } }
After we have the correct sentence we just need to parse the information and retrieve it to the user
public Location getLocation() { Location location = new Location(); if (isConnected && isActive && currentInfo != null) { location.parseGPGGA(currentInfo); } return location; }
To help us to retrieve data we use a class, called Location, to parse the GGA sentence and wrap the position data. We are also using a class called StringTokenizer to split the tokens in the sentence.
public class Location { // NMEA GPGGA Elements String utc; String latitude; String northHemi; String longitude; String eastHemi; String altitude; int quality; int nSat; String horDilution; String altitudeUnit; String geoidalHeight; String geoidalHeightUnit; String diffCorrection; String diffStationId; /** * Method that parses a NMEA string and returns Location. For more info check * this page: http://www.gpsinformation.org/dale/nmea.htm#GGA * * @param value - * string that represent NMEA GGA string */ public void parseGPGGA(String value) { // Helper class to parse strings StringTokenizer tok = new StringTokenizer(value, ","); utc = tok.nextToken(); latitude = tok.nextToken(); northHemi = tok.nextToken(); longitude = tok.nextToken(); eastHemi = tok.nextToken(); quality = Integer.parseInt(tok.nextToken()); nSat = Integer.parseInt(tok.nextToken()); horDilution = tok.nextToken(); altitude = tok.nextToken(); altitudeUnit = tok.nextToken(); geoidalHeight = tok.nextToken(); geoidalHeightUnit = tok.nextToken(); diffCorrection = tok.nextToken(); diffStationId = tok.nextToken(); } }
And that's a wrap we now have a class capable of reading the NMEA sentences from the BT-GPS and retrieve location info. Check the full source code for an complete application that allows you to search for devices, connect to them and shows the location info on the screen.
Link:http://www.developer.nokia.com/Community/Wiki/How_to_read_Location_from_Bluetooth_GPS
No comments:
Post a Comment