Join Now
Quality Rating:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)
Expertise Level:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)

This page was last modified 02:18, 25 January 2008.

Utilizando Bluetooth GPS diretamente em Java ME

From Forum Nokia Wiki

Um dos acessórios mais vendidos para telefones móveis e PDAs são os módulos Bluetooth GPS (BT-GPS). Esses dispositivos recebem informações de posicionamento do sistema de satélites GPS e permitem verificar sua posição atual com margem de cerca de 5m de precisão. É possível acessar esses dados via Bluetooth a partir de telefones móveis, e nestes, via APIs Java.

Contents

JSR 179 - Location API

Em dispositivos equipados com a implementação da JSR 179 - Location API, não há necessidade de uso da API Bluetooth (JSR 82), pois a Location API se encarrega de todos os passos necessários à obtenção da posição, tais como:

  • Busca do dispositivo GPS Bluetooth na área local
  • Pareamento (pairing) com o dispositivo
  • Obtenção de informação de dados de posicionamento
  • Parsing das strings NMEA utilizadas na comunicação dos dados de posicionamento, retornando objetos de alto nível em Java.

Para usar GPS através da JSR 179, baixe o documento MIDP: Location API Developer's Guide v2.0, que também contém código-fonte e uma aplicação pronta para testar.

Clique [1] aqui para fazer uma busca de todos os aparelhos que suportam a JSR 179 - Location API.

JSR 82 - Bluetooth API

Caso seu dispositivo não implemente a JSR 179, você poderá utilizar um módulo Bluetooth GPS e ler as informações de posicionamento manualmente. Para tanto, é preciso implementar as seguintes tarefas:

  1. Pesquisar o dispositivo Bluetooth GPS
  2. Conectar ao dispositivo GPS
  3. Ler e interpretar as sentenças NMEA que contém informações de posicionamento

Para o primeiro passo necessitamos buscar por um dispositivo Bluetooth que implemente o serviço RFCOMM. Uma classe que realiza todo este trabalho, "BTManager.class", está incluída no código-fonte completo deste exemplo.

Se você necessita de mais informações sobre busca de dispositivos, veja [[2]].

Para o propósito de ler dados do BT-GPS vamos criar uma classe chamada GpsBt. A primeira coisa a se fazer é criar uma variável para armazenar a URL do seu dispositivo.

// current bluetooth device
  public String btUrl = "";
  public String btName = "";
 
  public void setDevice(String btUrl, String btName) {
    this.btUrl = btUrl;
    this.btName = btName;
  }

Agora precisamos nos conectar ao dispositivo e começar a ler os dados:

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;
  }

Como você pode ter notado, estou implementando o loop de leitura usando um Thread. A razão para isto é que o dispositivo GPS está sempre mandando dados, então você precisa lê-los continuamente para impedir que o buffer da conexão seja estourado. Os dados enviados pelo dispositivo GPS são sentenças NMEA, que fornecem várias informações sobre o status da posição atual. O que estamos procurando é pela sentença GPGGA, que nos dá informações essenciais sobre localização de nosso aparelho.

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();
    }
  }

Após termos obtido a sentença correta precisamos apenas interpretar a informação e mostrá-la ao usuário:

public Location getLocation() {
    Location location = new Location();    
    if (isConnected && isActive && currentInfo != null) {        
        location.parseGPGGA(currentInfo);        
    }
    return location;
  }

Para nos ajudar a buscar a informação, utilizamos uma classe, chamada Location, para interpretar a sentença GGA e encapsular os dados de posicionamento. Também estamos utilizando a classe StringTokenizer para ler todos os tokens presentes na sentença.

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();
  }
}

Em suma, agora temos uma classe capaz de ler sentenças NMEA de um BT-GPS e obter dados de posicionamento. Veja o código-fonte para uma aplicação completa de posicionamento.

Downloads

References

Related Discussions
Thread Thread Starter Forum Replies Last Post
GPS program Dallows PC Suite API and PC Connectivity SDK 1 2006-07-10 15:54
bluetooth: Nokia 6600 OK, Nokia SDK NO!!!?? sandrosandrosa Mobile Java General 1 2004-08-10 00:13
Problem in dialog while connecting to a bluetooth GPS device padhi_chinmaya Symbian Networking & Messaging 1 2008-01-03 16:45
GPS - Bluetooth ozerki General Symbian C++ 0 2007-01-05 10:39
Getting the location of a Nokia Series 60, N80 phone xgamerx Mobile Java General 12 2008-02-15 05:01
 
Powered by MediaWiki
     
     RDF Facets:
     
     
     qfnZtypeQUqfnTypeZCommunityContentQ
     qfnZtypeQUqfnTypeZWebpageQ
     qfnZtypeQUqfnTypeZWikiContentQ
     qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX