LBS e a API Location - Exemplo

12/09/2007

0

Eterna orientadora: Drª Thienne Mesquita Johnson (thienne@ieee.org) Contribuição: Portal jmebrasil.org e j2me-list-subscribe@soujava.dev.java.net
Centro: CCET - Centro de Ciências Exatas e Tecnologia
Site: www.cci.unama.br
Artigo: www.devmedia.com.br/articles/viewcomp.asp?comp=5356

Serviços Baseados em Localização (LBS) utilizando dados (dados geométricos de lattitude-longitude-altura) do dispositivo GPS (fonte gratis) ou qualquer outra fonte disponibilizada pela operadora de telefonia celular (triangulação de antenas, cell-id...) e a classe javax.microedition.location de J2ME (JSR 179 ou API Location).
Como é um assunto pouco discutido, queria amostrar um exemplo.

ilustração da posição física do dispositivo móvel.

para dispositivos móveis (ex. celulares)


// classes de uso do j2me
 import javax.microedition.midlet.*;
 import javax.microedition.lcdui.*;
 import javax.microedition.location.*;
 import LandmarkEditor;
 
 public class locationMidlet extends Midlet implements CommandListener {
     private Form form = null;
     private static Display display = null;
     // criação dos comandos
     private Command cmdExit;
     private Command cmdPesquisar;
     private Command cmdEditorPOI;
     // campos de latitude, longitude, altura e método usado
     private String lat = "", long = "", alt = "", meth = "";
     // provedor de locazação
     private LocationProvider provedor = null;
     // criterios p/ localização
     private Criteria cr = null;
     // referencia ao Editor de Marcos 
     private LandmarkEditor editorPOI = null;
     // permite saber se o aplicativo iniciou
     boolean inicializado = false;
     // itens do formulário dos informações
     private StringItem siLocalidade;
     private StringItem ErroMsg;
     private StringItem lat;
     private StringItem long;
     private StringItem alt;
     private StringItem meth;
     private static locationMidlet INSTANCIA = null;
     public Alert alert = null;

     private Form myForm;
     private boolean isInitialized;
     private boolean splashIsShown;


     // Main Location MIDlet
     public locationMidlet (){
        if( display == null ){
           // 1ª chamada do MIDlet
           initMIDlet();
        }

          display = Display.getDisplay(this);
          // criação do formulário com titulo
          form = new Form("LBS");
          // subtitulo
          form.append(new StringItem(null, "Localização!"));
          // criação dos comandos
          cmdExit = new Command("Sair", Command.EXIT, 0);
          cmdPesquisar = new Command("Pesquisar", Command.SCREEN, 1);
          cmdEditorPOI = new Command("Editor", Command.STOP, 2);
          // adiciona os comandos ao formulário
          form.addCommand(cmdExit); 
          form.addCommand(cmdPesquisar); 
          form.addCommand(cmdEditorPOI);
          // gerenciador de comandos 
          form.setCommandListener(this);
          editorPOI = new LandmarkEditor(this, data);
          criarProvedor();
          INSTANCIA = this;
     }

     // padrão Singleton p/ o método getInstance
     public static locationMidlet getInstance() {
          if (INSTANCIA == null) {
             INSTANCIA = new locationMidlet();
          }
          return INSTANCIA;
     }

     protected void startApp() throws MIDletStateChangeException{
          if ((display.getCurrent() == null) || (!inicializado)) {
          display.setCurrent(form);

          // amostrará o resultado da consulta do servlet LBS 
          siLocalidade = new StringItem("", "");
          ErroMsg = new String("");
          lat = new String("");
          long = new String("");
          alt = new String("");
          meth = new String("");

          display.setCurrent(form);

          thread tGetLocation = new thread(){
             public void run(){
                while(!splashIsShown){
                  Thread.yield();
                }

                doTimeConsumingInit();
        
                while(true){
                  // loop           
                  Thread.yield();
                }

                try{
   // obtêm uma instância da classe Location
                   LocationProvider provedor=LocationProvider.getInstance(cr);
                   // pega a localização com tempo limite de 60s
                   Location loc=provedor.getLocation(60);
                }
                catch(LocationException e){
                   Alert alert = new Alert("Information", "Dados de localização inválidos", null, AlertType.INFO);
                   display.setCurrent(alert);                
                }
                catch(InterruptedException e){
                   Alert alert = new Alert("Information", "Parada inexperada", null, AlertType.INFO);
                   display.setCurrent(alert);
                }
             }
          }; 

         try {
             tGetLocation.start();
             tGetLocation.join();
             f.append(found(loc)+"location");
             // obtêm uma instancia um QualifiedCoordinates que representa as coordenadas 
             QualifiedCoordinates qc=loc.getQualifiedCoordinates();
             // uso das informações de coordenadas, vincula (exibição) ao formulario (display)
             // Caso haja coordenadas de localização
             coordenadas();
         } 
         catch(Exception e) {
            // tratamento de erro, 
            Alert alert = new Alert("Information", "Dados de localização invalidos", null, AlertType.INFO);
            display.setCurrent(alert);
         }
     }

     // passa o objeto de exibição (Display) do MIDlet e passa a proxima tela depois da exibição do splash screen

     private void initMIDlet(){
        Thread splashScreen = new Thread(new SplashScreenTest());
        splashScreen.start();
        
        Thread myGameThread = new Thread(this);
        myGameThread.start();       
    }

    private void doTimeConsumingInit(){ 
        // Just mimic some lengthy initialization for 10 secs
        long endTime= System.currentTimeMillis()+10000;
        while(System.currentTimeMillis()<endTime ){}
        
        // init the game´s main Displyable (here a Form)
        myForm = new Form("Game Started!");
        myForm.addCommand(exitCommand);
        myForm.setCommandListener(this);
        isInitialized=true;
        display.setCurrent(myForm);
        
    }

    public class SplashScreen implements Runnable{
        private SplashCanvas splashCanvas;
        
        public void run(){
            splashCanvas = new SplashCanvas ();      
            display.setCurrent(splashCanvas);
            splashCanvas.repaint();
            splashCanvas.serviceRepaints();
            while(!isInitialized){
                try{
                    Thread.yield();
                }catch(Exception e){}
            }
        }

    }
    
    public class SplashCanvas extends Canvas {
            protected void paint(Graphics g){
            g.drawString("Show splash screen", 15, 60, Graphics.BOTTOM| Graphics.LEFT );
            g.drawString("image here!", 15, 75, Graphics.BOTTOM| Graphics.LEFT );
            splashIsShown=true;
        }
    }

     public static Display getDisplay(){
         return display;
     }

     // função de pausa orbigatoria do MIDlet
     protected void pauseApp(){
        Alert alert = new Alert("Information", "App em pausa", null, AlertType.INFO);
        display.setCurrent(alert);
        initialized = true;
     }

     // função orbigatoria do midlet (saida) 
     protected void destroyApp(boolean unconditional) throws MIDletStateChangeException{} 

     // gerenciador de ação (comando)
     public void commandAction(Command cmd, Displayable s) {
         if (cmd == cmdExit){
             destroyApp(true);
             notifyDestroyed();
         }
 
         else if (cmd == cmdPesquisar){
             PesquisarGet();
         }

         else if (cmd == cmdEditorPOI){
            if (coord != null){
               editorPOI.showEditor(coord, LandmarkEditor.MODE_ADDNEW);
            }
            else{
                Alert alert = new Alert("Information", "Dados de localização não são válidos", null, AlertType.INFO);
                display.setCurrent(alert);
            }
        } 
     }

     // Tela de apresentação (Splash Screen)

     public void showSplashScreen(Display d, Displayable next){
        Image logo = null;
   
         try {
            // res é a pasta padrão de imagens em um projeto de um MIDlet seguido do nome da imagem
           logo = Image.createImage("/res/GUJ.jpg");
         }
         catch(IOException e){}
    
         Alert a = new Alert("Time Tracker", "Elias Franco Lopes.", logo, null); 
         a.setTimeout(Alert.FOREVER);
         display.setCurrent(a, next);
     }

     // Inicializa o Provedor de Localização (LocationProvider)
     protect void criarProvedor() {
          if (ConfigurationProvider.isLocationApiSupported()){
             ConfigurationProvider.getInstance().autoSearch(this);
          }
          else{
             Alert alert = new Alert("Information", "Dispositivo não suporta a API Location", null, AlertType.INFO);
             // atualiza o display
             display.setCurrent(alert);
             destroyApp(false);
             notifyDestroyed();
        }

        ConfigurationProvider config = ConfigurationProvider.getInstance();
        provedor = config.getSelectedProvider();

        if (provedor == null) {
             Alert alert = new Alert("Information", "MIDLet não pode funcionar sem um provedor de localização", null, AlertType.INFO);
             // atualiza o display
             display.setCurrent(alert);
             destroyApp(false);
             notifyDestroyed();
          }

        if (provedor != null){
              provedor.setLocationListener(this, intervalo, timeout, maxage);
        }

        if (provedor == null) {
            // obtêm uma instancia da classe criteria
            cr = new Criteria();
            // Precisão de 1000m horizontalmente e verticalmente
            cr.setHorizontalAccuracy(100);
            cr.setVerticalAccuracy(100);
            // ajusta o nível de consumo de potência do aparelho p/ realizar a localização (nível alto p/ melhor localização)
            c.setPreferredPowerConsumption(Criteria.POWER_USAGE_HIGH);
       
             thread tGetLocation = new thread(){ 
                 public void run(){ 
                    try{
                       // obtêm uma instância da classe Location 
                       provedor = LocationProvider.getInstance(cr);
                       // pega a localização com tempo limite de 60s 
                       Location loc=provedor.getLocation(60); 
                    } 
                    catch(LocationException e){ 
                       Alert alert = new Alert("Information", "Não é possível criar o LocationProvider para criteria", null, AlertType.INFO);
                       display.setCurrent(alert);
                    } 
                    catch(InterruptedException e){ 
                       Alert alert = new Alert("Information", "Parada inexperada", null, AlertType.INFO);
                       display.setCurrent(alert);
                    } 
                 } 
             }; 
        } 
     }

     public static void coordenadas(){
        if((qc != null) || (loc.isValid())) {
           AddressInfo address = loc.getAddressInfo();
           // obtêm a latitude
           lat = Coordinates.convert(qc.getLatitude(), Coordinates.DD_MM_SS), "");
           // obtêm a longitude
           long = Coordinates.convert(qc.getLongitude(), Coordinates.DD_MM_SS), "");
           // obtêm a altura
           alt = Coordinates.convert(qc.getAltitude(), Coordinates.DD_MM_SS), "");
           String locate = c.convert(alt,1);
           // obtêm a método de localização
           meth = location.getLocationMethod();

           if((loc.getLocationMethod() & loc.MTE_SATELLITE) !=0){
              f.append(?Method = Satellite?);
           }

           // exibe a altura
           f.append("Altura: "+lat);
           // exibe a latitude
           f.append("Latitude: "+long);
           // exibe a longitude
           f.append("Longitude: "+alt);
           // exibe o método
           f.append("Método: "+meth);
           // exibe a localizadde
           f.append(siLocalidade);
           // atualiza o display
           display.setCurrent(f);
        }
        else{
           // caso a localização ou as coordenadas não é valida.
           String msg = location.getExtraInfo(?application/X-jsr179-location-nmea?);
           f.append("Localização não válida: "+msg);
           loc.getExtraInfo(String mimetype);
           getExtraInfo(?application/X-jsr179-location-nmea?);
           getExtraInfo(?text/plain?);
           f.append(?loc.getExtraInfo("text/plain"));
        }
        qc = loc.getQualifiedCoordinates();
     }

     // Exibe o estado do provedor de localização
     public static void showProvStatus(){
        Gauge indicador = new Gauge(null, false, 50, 1);
        indicador.setValue(Gauge.CONTINUOUS_RUNNING);

        Alert alert = new Alert("Information", "Espere, procurando por dados de localização....", null, AlertType.INFO);
        alert.setIndicator(indicador);
        display().setCurrent(alert);
    }

     // Acesso ao Servlet Usando metodo Get
     public void PesquisarGet() throws IOException {
        // Criação dos elementos HttpConnection e InputStream utilizados numa conexão do tipo GET
        HttpConnection hc = null;
        InputStream is = null;
        boolean ret = false;

        thread tConnection = new thread(){
           public void run(){
              // Inicializa uma conexão
              hc = (HttpConnection) Connector.open(url);
              hc.setRequestMethod(HttpConnection.GET);
           }
        };
 
        // Definição de URL que enviara os dados (coordenadas) para a pesquisa
        String url = "http://ENDEREÇO_DO_SERVLET:8080/" + "?" + "latitude=" + lat + "&longitude=" + long
 
        try{
           // Inicializa uma conexão
           AlertType.INFO.playSound(m_Display);
           tConnection.start();
           tConnection.join();
           // Inicia o InputStream para troca de mensagens
           is = hc.openInputStream();
           ret = processResp(hc, is)     
         }
 
         finally{
            if (is != null)
               // Finaliza conexão
               is.close();   
               if (hc != null)
                  hc.close();
            }
            if(ret == false)
               showAlert(erroMsg);
            }
 
     // Processa uma reposta do Servlet
     public boolean processaResp(HttpConnection hc, InputStream is) throws IOException {        
        erroMsg = null; 
        // se conexão realizada e resposta foi OK, calcula o tamanho da resposta (resultado)
        if(hc.getResponseCode() == HttpConnection.HTTP_OK){
           int length = (int) hc.getLength();
           string str;
              
           if(length != -1){
              byte servletData[] = new Byte[lenght];
              // recebe resposta do servlet e depois guarda em str
              is.read(servletData);
              str = new string(servletData);
           }
           else{  
              ByteArrayOutputstream bos = new ByteArrayOutputstream();
              int ch;
              while(ch = is.read() != -1)
                 bos.write(ch);
             
              str = new String(bos.toByteArray());
              bos.close()
           }
           // amostra o resultado (resposta do servlet) no display   
           siLocalidade.setText(str);
           return true;
        }
        else{
           erroMsg = new String(hc.getResponseMessage());
           showAlerta(erroMsg);
           return false;
        }

        // exibe um alerta
        private void showAlerta(String msg){
           alert = new Alert("Error", msg, null, AlertType.ERROR);
           alert.setTimeout(3000); // 3 seg
           display.setCurrent(alert, this);
           return null;
        }

} // fim de locationMidlet 



Um alerta é flexível bastante, entretanto. Para demitir a tela com toda a chave ou para indicar um animation simples, é necessio usar um Canvas p/ a splash screen.
A classe Canvas da tela de apresentação (splash screen)


import java.util.*;
import javax.microedition.lcdui.*;

public class SplashScreen extends Canvas {
    private Display display;
    private Displayable next;
    private Timer timer = new Timer();

    public SplashScreen(Display display, Displayable next){
        this.display = display;
        this.next = next;
        display.setCurrent(this);
    }

    protected void keyPressed(int keyCode){
        dismiss();
    }

    protected void paint(Graphics g){
       g.setColor(255, 0, 0);
       g.fillRect(0, 0, getWidth(), getHeight(  ));
       g.setColor(255, 255, 255);
       g.drawString("Hello World!", 0, 0, g.TOP | g.LEFT);
    }

    protected void pointerPressed(int x, int y){
        dismiss();
    }

    protected void showNotify(){
        timer.schedule(new CountDown(), 5000);
    }

    private void dismiss(){
        timer.cancel();
        display.setCurrent(next);
    }

    private class CountDown extends TimerTask {
        public void run(){
            dismiss();
        }
    }
}



Classe do editor de marcos/pontos de interesse (landmark)


     import java.io.IOException;
     import java.util.Enumeration;
     import javax.microedition.lcdui.*;
     import javax.microedition.location.*;
     import ControleMarcos;

     Editor de Marcos/pontos de interesse (landmark)
     class LandmarkEditor extends Form implements CommandListener{
     // campos referentes aos marcos. (*) = campos obrigatórios
     private TextField nameField;
     private TextField descField;

     // campos do AddressInfo
     private TextField countryField;
     private TextField stateField;
     private TextField cityField;
     private TextField streetField;
     private TextField buildingNameField;
     // constantes
     public static final int MODE_UPDATE = 0;
     public static final int MODE_ADDNEW = 1;
     private QualifiedCoordinates coord = null;
     private Displayable route = null;
     private TouristData data = null;
     // informação de coordenadas
     private StringItem lat;
     private StringItem lon;
     private StringItem alt;
     // lista do marco selecionado
     private List list;
     private Command saveNewCmd;
     private Command saveUpdatedCmd;
     private Command updateCmd;
     private Command removeCmd;
     private Command listCmd;
     private Command routeCmd;

     public LandmarkEditor(Displayable route, TouristData data){
        super("Editor de Marcos");

        nameField = new TextField("Name (*):", "", 20, TextField.ANY);
        descField = new TextField("Description (*):", "", 40, TextField.ANY);
        countryField = new TextField("Country:", "", 20, TextField.ANY);
        stateField = new TextField("State:", "", 20, TextField.ANY);
        cityField = new TextField("City:", "", 20, TextField.ANY);
        streetField = new TextField("Street:", "", 20, TextField.ANY);
        buildingNameField = new TextField("Building name (*):", "", 20, TextField.ANY);
        lat = new StringItem("Lat:", "");
        lon = new StringItem("Lon:", "");
        alt = new StringItem("Alt:", "");
        list = new List("Landmarks:", List.EXCLUSIVE);
        cmdSaveNew = new Command("Savar", Command.OK, 1);
        cmdSaveUpdated = new Command("Savar", Command.OK, 1);
        cmdUpdate = new Command("Atualizar", Command.OK, 1);
        cmdRemove = new Command("Remover", Command.OK, 1);
        cmdList = new Command("Listar", Command.OK, 1);
        cmdRoute = new Command("Rota", Command.BACK, 1);

        this.route = route;
        this.data = data;

        // comandos do editor de marcos
        addCommand(routeCmd);
        addCommand(listCmd);
        setCommandListener(this);

        // comandos da lista de marcos 
        list.addCommand(routeCmd);
        list.setCommandListener(this);
    }

    // inicializa campos e exibe o editor de marcos
    public void showEditor(QualifiedCoordinates newCoord, int mode){
        this.coord = newCoord;

        // inicializa as coordenadas
        lat.setText(formatDouble(newCoord.getLatitude(), 3));
        lon.setText(formatDouble(newCoord.getLongitude(), 3));
        alt.setText(formatDouble(newCoord.getAltitude(), 1));

        // inicializa campos
        nameField.setString("");
        descField.setString("");
        countryField.setString("");
        stateField.setString("");
        cityField.setString("");
        streetField.setString("");
        buildingNameField.setString("");

        deleteAll();
        append(nameField);
        append(descField);
        append(countryField);
        append(stateField);
        append(cityField);
        append(streetField);
        append(buildingNameField);

        append(lat);
        append(lon);
        append(alt);

        // Atualiza existente marco
        if (mode == MODE_UPDATE){
            Landmark lm = ControleMarcos.getInstance().localizarProxMarco(newCoord);

            if (lm != null){
                nameField.setString(lm.getName());
                descField.setString(lm.getDescription());

                AddressInfo info = lm.getAddressInfo();
                if (info != null){
                    countryField.setString(info.getField(AddressInfo.COUNTRY));
                    stateField.setString(info.getField(AddressInfo.STATE));
                    cityField.setString(info.getField(AddressInfo.CITY));
                    streetField.setString(info.getField(AddressInfo.STREET));
                    buildingNameField.setString(info.getField(AddressInfo.BUILDING_NAME));
                }
            }

            removeCommand(updateCmd);
            removeCommand(saveNewCmd);
            addCommand(saveUpdatedCmd);
            addCommand(listCmd);
        }
        // adiciona novo marco ao LandmarkStore.
        else if (mode == MODE_ADDNEW){
            removeCommand(updateCmd);
            removeCommand(saveUpdatedCmd);
            addCommand(saveNewCmd);
            addCommand(listCmd);
        }
        display.setCurrent(this);
    }

    public void showList(){
        list.deleteAll();
        Landmark lm = null;
        Enumeration enuMarcos = ControleMarcoss.getInstance().getLandMarks();

        // verifica se o marco existe no landmarkstore.
        if (landmarks != null){
            while (enuMarcos.hasMoreElements()){
                lm = ((Landmark) enuMarcos.nextElement());
                list.append(lm.getName(), null);
            }

            list.addCommand(cmdUpdate);
            list.addCommand(cmdRemove);
        }
        // marco ñ localizado (lista em branco)
        else{
            list.removeCommand(cmdUpdate);
            list.removeCommand(cmdRemove);
        }
        display.setCurrent(list);
    }

    // verefica se os campos obrigatórios foram preenchidos
    private String checaCampos(){
        if (nameField.getString().equals("")){
            return "Nome";
        }
        else if (nameField.getString().equals("")){
            return "Descrição";
        }
        else if (buildingNameField.getString().equals("")){
            return "Local";
        }
        return null;
    }

     private Landmark gerarMarco(){
        String field = checaCampos();
        if (field != null){
           erroMsg = new String("Valor do campo obrigatório ("+ field + ") está errado");
           showAlerta(erroMsg);

           /*
           Alert alert = new Alert("Error", "Valor do campo obrigatório ("+ field + ") está errado.", null, AlertType.ERROR);
              alert.setTimeout(3000); // 3 secs
              display().setCurrent(alert, this);
              return null;
           }
           */

        AddressInfo info = new AddressInfo();
        info.setField(AddressInfo.COUNTRY, countryField.getString());
        info.setField(AddressInfo.STATE, stateField.getString());
        info.setField(AddressInfo.CITY, cityField.getString());
        info.setField(AddressInfo.STREET, streetField.getString());
        info.setField(AddressInfo.BUILDING_NAME, buildingNameField.getString());

        Landmark lm = new Landmark(nameField.getString(), descField.getString(), coord, info);
        return lm;
    }

        public void commandAction(Command command, Displayable displayable){
        Landmark landmark = null;

        // adiciona novo marco ao LandmarkStore
        if (command == cmdSaveNew){
            landmark = gerarMarco();
            if (landmark != null){
                try{
                    ControleMarcos.getInstance().addMarco(landmark);
                    data.createProximityListener(coord);
                }
                catch (IOException e)
                {
                    Alert alert = new Alert("Error", "Erro de Entrada/Saída", null, AlertType.ERROR);
                    display().setCurrent(alert);
                }
                // novo marco avaliado na lista
                showList();
            }
        }
        // atualiza o marco
        else if (command == cmdSaveUpdated){
            landmark = gerarMarco();
            if (landmark != null){
                try{
                    ControleMarcos.getInstance().atualizarMarco(landmark);
                    data.createProximityListener(coord);
                }
                catch (IOException e){
                    Alert alert = new Alert("Error", "Erro de Entrada/Saída", null, AlertType.ERROR);
                    display().setCurrent(alert);
                }
                catch (LandmarkException e){                   
                    Alert alert = new Alert("Error","Marco não localizado no Landmark Store.", null, AlertType.ERROR);
                    display().setCurrent(alert);
                }
                // atualiza o marco avaliado na lista
                showList();
            }
        }
        // retorna a tela anterior
        else if (command == cmdRoute){
           display().setCurrent(route);
        }
        // Show landmark editor for the selected landmark.
        else if (command == cmdUpdate){
            int index = list.getSelectedIndex();
            landmark = ControleMarcos.getInstance().proxMarco(index);
            showEditor(landmark.getQualifiedCoordinates(), MODE_UPDATE);
        }
        // Remove o marco selecionado do LandmarkStore
        else if (command == cmdRremove){
            try{
                int index = list.getSelectedIndex();
                landmark = ControleMarcos.getInstance().proxMarco(index);
                ControleMarcos.getInstance().removeMarco(landmark);

                Alert alert = new Alert("Information", "Marco removido com sucesso.", null, AlertType.INFO);
                display().setCurrent(alert);
            }
            catch (IOException e){
                Alert alert = new Alert("Error", "Erro de Entrada/Saída",null, AlertType.ERROR);
                display().setCurrent(alert);
            }
            catch (LandmarkException e){
                Alert alert = new Alert("Error", "Marco não localizado no Landmark Store.",
                        null, AlertType.ERROR);
                alert.setTimeout(3000); // 3 secs
                TouristMIDlet.getDisplay().setCurrent(alert);
            }
            showList();
        }
        // exibe a lista de marcos localizados
        else if (command == cmdList){
            showList();
        }
    }

    public static String formatDouble(double value, int decimals){
        String doubleStr = "" + value;
        int index = doubleStr.indexOf(".") != -1 ? doubleStr.indexOf("."): doubleStr.indexOf(",");
        // determina o ponto de decimal
        if (index == -1) return doubleStr;
        // trunca todos os decimais
        if (decimals == 0){
            return doubleStr.substring(0, index);
        }

        int len = index + decimals + 1;
        if (len >= doubleStr.length()) len = doubleStr.length();
        double d = Double.parseDouble(doubleStr.substring(0, len));
        return String.valueOf(d);
    }
}



Classe que cuida das ações sobre os marcos (landmark)


import java.io.IOException;
import java.util.Enumeration;
import javax.microedition.location.*;

public class ControleMarcos{
    private LandmarkStore store = null;
    private static final String STORE-NOME = "TURISTA";
    private static final String CATEG-PADRAO = null;
    private static ControleMarcos INSTANCIA = null;

    private ControleMarcos(){
        String nome = null;
        // tenta localizar no LandmarkStore "TURISTA".
        try{
            store = LandmarkStore.getInstance(STORE-NOME);
        }
        catch (NullPointerException e){
        }

        // verifica se a LandmarkStore selecionada existe
        if (store == null){
            // LandmarkStore não existe
            try{
                // cria um LandmarkStore de nome "TURISTA".
                LandmarkStore.createLandmarkStore(STORE-NOME);
                name = STORE-NOME;
            }
            catch (IllegalArgumentException e){                
            }
            catch (IOException e){
            }
            catch (LandmarkException e){
            }

            store = LandmarkStore.getInstance(nome);
        }
    }

    // padrão Singleton p/ o método getInstance
    public static ControleMarcos getInstance(){
        if (INSTANCIA == null){
            INSTANCE = new ControleMarcos();
        }
        return INSTANCIA;
    }

    // localiza o marco selecionado do LandmarkStore usando o indice
    public Landmark proxMarco(int index){
        Landmark lm = null;
        Enumeration enuCm = ControleMarcos.getInstance().getLandMarks();
        int counter = 0;

        while (enuCm.hasMoreElements()){
            lm = (Landmark) enuCm.nextElement();
            if (counter == index){
                break;
            }
            counter++;
        }
        return lm;
    }

    // localizado o próximo marco na LandmarkStore de acordo com coodenadas 
    public Landmark localizarProxMarco(Coordinates coord){
        Landmark landmark = null;
        double latRaio = 0.1;
        double lonRaio = 0.1;
        float dist = Float.MAX_VALUE;

        try{
            // gera um vetor de marcos de acordo com as coordenadas.
            Enumeration enu = store.getLandmarks(null, coord.getLatitude() - latRaio, coord.getLatitude() + latRadio, coord.getLongitude() - lonRaio, coord.getLongitude() + lonRadius);
            float tmpDist;
            Landmark tmpLandmark = null;

            while (enu.hasMoreElements()){
                tmpLandmark = (Landmark) enu.nextElement();
                tmpDist = tmpLandmark.getQualifiedCoordinates().distance(coord);

                if (tmpDist &lt dist){
                    landmark = tmpLandmark;
                }
            }
        }
        catch (IOException e){
            return null;
        }
        return landmark;
    }

    public Enumeration getLandMarks(){
        Enumeration enu = null;
        try{
            enu = store.getLandmarks();
        }
        catch (IOException e){
        }
        return enu;
    }

    // método de adição de marco
    public void addMarco(Landmark landmark) throws IOException{
        store.addLandmark(landmark, CATEG-PADRAO);
    }

    // método de atualização do marco
    public void atualizarMarco(Landmark landmark) throws IOException, LandmarkException{
        store.updateLandmark(landmark);
    }

    // método de remoção do marco
    public void removeMarco(Landmark landmark) throws IOException, LandmarkException{
        store.deleteLandmark(landmark);
    }



Código para uso no desktop, por exemplo com um GPS ligado ao computador via bluetooth


 import javax.microedition.location;
 //...

 void locationDesktop(){
     LocationProvider lp = LocationProvider.getInstance(null);
     Location loc = lp.getLocation(10);
     QualifiedCoordinate qc = LocationProvider.getInstance(
          new Criteria()).getLastKnownLocation().getQualifiedCoordinates() ;
     String exinf = l.getExtraInfo("text/plain");
     System.out.println("A palavra é... " + exinf); 
     if ((qc != null) || (location.isValid()){
        double latitude = qc.getLatitude();
        double longitude = qc.getLongitude();
        String locate = c.convert(alt,1);
        graphics.drawString(locate,4,30,Graphics.TOP|Graphics.LEFT); 
        System.out.println("Latitude: " + latitude);
        System.out.println("Longitude: " + longitude);
        System.out.println("Método: "+location.getLocationMethod());
     else{
        // caso a localização ou coordenadas não é valida.
        String msg = location.getExtraInfo(?application/X-jsr179-location-nmea?);
System.out.println(?Localização não valida: ?+msg);
     }

 }



Código da classe do servlet (servidor web) que receberá as coordenadas (dados gps) e realizará a consulta

Classe do servlet


import javax.servlet.http.*;
 import javax.servlet.*;
 import java.io.*;
 import java.util.*;
 import java.sql.*;
 
 public class Servlet extends HttpServlet {
      
      // Procedimento doGet (recebimento de solicitação do cliente)
      public void doGet(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {      
         
         // Captura os dados passados por parametro atraves do endereço URL
         String latitude = request.getParameter("latitude"),
         longitude = request.getParameter("longitude");
         String localidade = pesquisaLocal(latitude, longitude);
 
         // se resultado vazio, amostra msg de erro
         if(localidade == null){
     res.SendError(res.SC_BAD_REQUEST, "Nao possivel localizar o local");
     return;
 }
 
 res.SendContentType("text/plain");
 // Inicializa o objeto PrintWriter que vai escrever(enviar pro dispositivo) a resposta
         PrintWriter out = res.getWriter();
 out.print(localidade);
 out.close();
 desconectar();
      }
 
      // Pesquisa num banco de dados
      public String pesquisaLocal(String latitude, String longitude){
 Connection conn = null;
 Statement st = null;
 StringBuffer msgb = new StringBuffer("");
                // commando básico de pesquisa em um BD 
 String sql = Select LOCALIDADE From DADOS_LOCALIDADE Where latitude = " + latitude + "And longitude = " + longitude + "´"
 
 try{
                 // informações sobre o BD ussado ,no caso hsqldb
     Class.forName("org.hsqldb.jdbcDriver");
                 // nome do usuário (login), senha e endereço url do BD
             String user = "sa";
             String password = "";
           String url = "jdbc:hsqldb:hsql://localhost";            
     conn = DriverManager.getConnection(url,user,password);
 
     Statement stm = conn.createStatement();
     ResultSet rs = stm.executeQuery(sql);
 
     // retorna o resultado da pesquisa
     if(rs.next())
         return rs.getString(1);
     else
         resturn null;
  }
  // Erro ao acessar o banco de dados
         catch(ClassNotFoundException e) {
             resp = "* ERRO: BANCO DE DADOS INACESSIVEL! ";
             // e.printStackTrace(); // Esta linha iria imprimir no console informações sobre o erro obtido
         }
         
         // Erro ao executar a consulta sql
         catch(SQLException e) {
             resp = "* ERRO: CONSULTA SQL INVÁLIDA!";
             // e.printStackTrace();
         }
      }
 
      // Finaliza a conexão com o banco de dados
      public void desconectar() throws SQLException {
         this.conn.close();
      }
 }



Classe CongurationProvider, essa clase não faz parte da API Location. Precisa ser implementada


import javax.microedition.location.Criteria;
import javax.microedition.location.LocationException;
import javax.microedition.location.LocationProvider;
import javax.microedition.location.Orientation;

public class ConfigurationProvider
{
    private static ConfigurationProvider INSTANCE = null;
    private static Criteria[] freeCriterias = null;
    private static String[] freeCriteriaNames = null;
    private static Criteria[] costCriterias = null;
    private static String[] costCriteriaNames = null;
    private Criteria criteria = null;
    private LocationProvider provider = null;

    // estático contendo critério pagos grátis

    static
    {
        // 1. pré-definição dos critérios grátis

        freeCriterias = new Criteria[2];
        freeCriteriaNames = new String[2];

        Criteria crit1 = new Criteria();
        crit1.setHorizontalAccuracy(25); // 25m
        crit1.setVerticalAccuracy(25); // 25m
        crit1.setPreferredResponseTime(Criteria.NO_REQUIREMENT);
        crit1.setPreferredPowerConsumption(Criteria.POWER_USAGE_HIGH);
        crit1.setCostAllowed(false);
        crit1.setSpeedAndCourseRequired(true);
        crit1.setAltitudeRequired(true);
        crit1.setAddressInfoRequired(true);

        freeCriterias[0] = crit1;
        freeCriteriaNames[0] = "High details, cost not allowed";

        Criteria crit2 = new Criteria();
        crit2.setHorizontalAccuracy(Criteria.NO_REQUIREMENT);
        crit2.setVerticalAccuracy(Criteria.NO_REQUIREMENT);
        crit2.setPreferredResponseTime(Criteria.NO_REQUIREMENT);
        crit2.setPreferredPowerConsumption(Criteria.POWER_USAGE_HIGH);
        crit2.setCostAllowed(false); // allowed to cost
        crit2.setSpeedAndCourseRequired(false);
        crit2.setAltitudeRequired(false);
        crit2.setAddressInfoRequired(false);

        freeCriterias[1] = crit2;
        freeCriteriaNames[1] = "Low details and power consumption, cost not allowed";

        // 2. pré-definição dos critérios pagos

        costCriterias = new Criteria[3];
        costCriteriaNames = new String[3];

        Criteria crit3 = new Criteria();
        crit3.setHorizontalAccuracy(25); // 25m
        crit3.setVerticalAccuracy(25); // 25m
        crit3.setPreferredResponseTime(Criteria.NO_REQUIREMENT);
        crit3.setPreferredPowerConsumption(Criteria.NO_REQUIREMENT);
        crit3.setCostAllowed(true);
        crit3.setSpeedAndCourseRequired(true);
        crit3.setAltitudeRequired(true);
        crit3.setAddressInfoRequired(true);

        costCriterias[0] = crit3;
        costCriteriaNames[0] = "High details, cost allowed";

        Criteria crit4 = new Criteria();
        crit4.setHorizontalAccuracy(500); // 500m
        crit4.setVerticalAccuracy(Criteria.NO_REQUIREMENT);
        crit4.setPreferredResponseTime(Criteria.NO_REQUIREMENT);
        crit4.setPreferredPowerConsumption(Criteria.NO_REQUIREMENT);
        crit4.setCostAllowed(true);
        crit4.setSpeedAndCourseRequired(true);
        crit4.setAltitudeRequired(true);
        crit4.setAddressInfoRequired(false);

        costCriterias[1] = crit4;
        costCriteriaNames[1] = "Medium details, cost allowed";

        // Least restrictive criteria (with default values)
        Criteria crit5 = null;

        costCriterias[2] = crit5;
        costCriteriaNames[2] = "Least restrictive criteria";
    }

    // construtor
    private ConfigurationProvider()
    {
        queryUI = new ProviderQueryUI();
    }

    // uso do padrão singleton
    public static ConfigurationProvider getInstance()
    {
        if (INSTANCE == null)
        {
            // Enable use of this class when Location API is supported.
            if (isLocationApiSupported())
            {
                INSTANCE = new ConfigurationProvider();
            }
            else
            {
                INSTANCE = null;
            }
        }

        return INSTANCE;
    }

    // checa o suporte a API
    public static boolean isLocationApiSupported()
    {
        String version = System.getProperty("microedition.location.version");
        return (version != null && !version.equals("")) ? true : false;
    }

    public LocationProvider getSelectedProvider()
    {
        return provider;
    }

    // procura o provedor de localização
    public void autoSearch(ProviderStatusListener listener)
    {
        try
        {
            for (int i = 0; i &lt freeCriterias.length; i++)
            {
                criteria = freeCriterias[i];

                provider = LocationProvider.getInstance(criteria);
                if (provider != null)
                {
                    // Location provider found, send a selection event.
                    listener.providerSelectedEvent();
                    return;
                }
            }

            if (confirmCostProvider())
            {
                for (int i = 0; i &lt costCriterias.length; i++)
                {
                    criteria = costCriterias[i];

                    provider = LocationProvider.getInstance(criteria);
                    if (provider != null)
                    {
                        // Location provider found, send a selection event.
                        listener.providerSelectedEvent();
                        return;
                    }
                }
            }
            else
            {
                showNoFreeServiceFound();
            }
        }
        catch (LocationException le)
        {
            showOutOfService();
        }
    }

    public Orientation getOrientation()
    {
        try
        {
            return Orientation.getOrientation();
        }
        catch (LocationException e)
        {
            return null;
        }
    }

    // checa se o indicador de direção é suportado
    public boolean isOrientationSupported()
    {
        try
        {
            // Test whether Orientation instance can be obtained.
            Orientation.getOrientation();
            return true;
        }
        catch (LocationException e)
        {
            return false;
        }
    }

    // chega os serviços grátis ligados
    public void showNoFreeServiceFound()
    {
        Alert alert = new Alert("Error", NO_FREE_SERVICE_SERVICE_MESSAGE, null,
                AlertType.ERROR);
        alert.setTimeout(Alert.FOREVER);
        TouristMIDlet.getDisplay().setCurrent(alert, searchForm);
        infoItem.setText(NOT_FOUND_MESSAGE);
    }

    // chega os serviços pagos ligados
    public synchronized boolean confirmCostProvider()
    {
        Alert alert = new Alert("Confimnation", COST_QUERY_MESSAGE, null,
                AlertType.CONFIRMATION);
        alert.addCommand(yesCmd);
        alert.addCommand(noCmd);
        alert.setTimeout(Alert.FOREVER);

        // Set the monitoring object to be this instance.
        final ProviderQueryUI hinstance = this;

        // Add a CommandLister as anomynous inner class
        alert.setCommandListener(new CommandListener()
        {
            /*
             * Event indicating when a command button is pressed.
             * 
             * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command,
             *      javax.microedition.lcdui.Displayable)
             */
            public void commandAction(Command command, Displayable d)
            {
                if (command == yesCmd)
                {
                    infoItem.setText(SEACHING_COST_PROVIDERS);
                    result = true;
                    synchronized (hinstance)
                    {
                        // Wake up the monitoring object
                        hinstance.notifyAll();
                    }
                }
                else if (command == noCmd)
                {
                    result = false;
                    infoItem.setText(NOT_FOUND_MESSAGE);
                    synchronized (hinstance)
                    {
                        // Wake up the monitoring object
                        hinstance.notifyAll();
                    }
                }

            }
        });

}



Abraço Elias.Lôgan-X
Texto revisto e atualizado em: agosto/2007

Abraço Elias.Lôgan-X


Liclopes

Liclopes

Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar