Fórum LBS e a API Location - Exemplo #18746
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)
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)
Classe do editor de marcos/pontos de interesse (landmark)
Classe que cuida das ações sobre os marcos (landmark)
Código para uso no desktop, por exemplo com um GPS ligado ao computador via bluetooth
Código da classe do servlet (servidor web) que receberá as coordenadas (dados gps) e realizará a consulta
Classe do servlet
Classe CongurationProvider, essa clase não faz parte da API Location. Precisa ser implementada
Abraço Elias.Lôgan-X
Texto revisto e atualizado em: agosto/2007
Abraço Elias.Lôgan-X
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 < 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 < 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 < 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
Curtir tópico
+ 0
Responder
Clique aqui para fazer login e interagir na Comunidade :)