Nesta postagem acessaremos o Sensor de Localização de dispositivos móveis através de uma aplicação desenvolvida com Delphi XE5.

Neste tutorial daremos prosseguimento a nossa série de desenvolvimento de aplicações de exemplos utilizando Delphi XE5 para acessar funcionalidades de dispositivos móveis com poucas linhas de código. Nele faremos acesso ao sensor de localização do dispositivo fazendo com que a sua localização seja plotada no mapas através de integração com o Google Maps.

 Iniciando o Delphi e preparando a aplicação

Iniciaremos o Delphi XE5 e criaremos um Novo Projeto Móvel através do menu File–> New Project –> Delphi Projects –> Mobile Projects. Adotaremos o modelo de aplicação em branco (Blank Application).

Novo Delphi Mobile Project

Feito isso salvaremos nosso projeto através do menu File –> Save All. Chamaremos a Unit de frmLocalizacaoUnt e o projeto chamaremos de prjLocalizeMe.

Agora vamos inserir em nossa aplicação os componentes que farão com que ela fique funcional. Vamos adicionar 2 Label’s, 1 WebBrowser, 1 ToolBar, 1 Switch e um LocationSensor. Então teremos

  • ToolBar1
    • Align –> alTop
  • Label1
    • Text –> Localização
  • Label2
    • Align –> alBotton
    • Text –> www.landersongomes.vivaitaocara.com.br
  • WebBrowser1
    • Align –> alClient
  • LocationSensor1
    • Distance –> 50

Ao final do processo acima nossa tela de design ficará semelhante à figura abaixo.

Layout da Aplicação LocalizeMe

Ativando e desativando o sensor

O objeto Switch1, não alteramos nenhuma de suas propriedades… mas será ele o nosso “interruptor” para ligar e desligar o Sensor de Localização LocationSensor1.  Para o Switch1 vamos codificar seu evento OnSwitch, que seria o seu ativar/desativar propriamente dito, esse é o código:

procedure TForm1.Switch1Switch(Sender: TObject);
begin
LocationSensor1.Active := Switch1.IsChecked;
if LocationSensor1.Active = False then
    begin
      Label2.Text := 'landersongomes.vivaitaocara.com.br';
      WebBrowser1.Navigate(Label2.Text);
    end;
end;

 

Note que atribuímos ao Sensor de Localização (LocationSensor1) atividade ou não de acordo com a ativação ou não do Switch, assim sendo, ativado o Switch ativamos consequentemente o Sensor. Em seguida, apenas por estética, verificamos se o sensor está inativo, caso esteja, passamos o endereço do meu blog para a propriedade Text do Label2 e em seguida, passamos ela como URL para o WebBrowser1 Navegar. Então se o sensor estiver desativado, o WebBrowser1 abrirá meu blog.

Ajuda do GoogleMaps

Já configuramos o comportamento da aplicação quando o sensor estiver desligado, agora vamos configurá-la para o funcionamento com o sensor ligado dando-lhe a funcionalidade de exibir nossa posição no Mapa.

Antes de mais nada precisamos pegar uma linha com o GoogleMaps, será a linha que passaremos para nossa aplicação conseguir “desenhar” o mapa, e nossa aplicação por sua vez passará para o GoogleMaps a localização  do ponto que queremos desenhar. É bem simples, veja a linha:

https://maps.google.com/?q=%s,%s&&t=h&&z=13&&hl=pt-BR&&output=embed

Basicamente, chamamos o GoogleMaps, informamos a ele a parte do mapa que queremos, representada na linha por: “?q=%s,%s”, cada um dos “%s” será trocado por sua respectiva coordenada a ser fornecida pelo sensor quando ativado. O restante são variáveis capazes de mudar o comportamento do mapa:

&t=h –> indica o tipo do mapa, nesse caso híbrido.

&z=13 –> indica que nosso mapa será exibido com 13 de zoom.

&output=embed –> quer dizer que nosso mapa estará embarcado no navegador, sem exibir recursos específicos de tela do GoogleMaps.

Atualizar a Localização e Exibir o Mapa

Para exibirmos a localização, trataremos o evento OnLocationChanged, que é acionado sempre que sensor se movimenta superando o limite estabelecido em sua propriedade Distance, que em nosso caso setamos para 50 metros.  Passaremos nesse evento a linha do Google citada na sessão anterior e receberemos as coordenadas por parte do LocationSensor1, veja como ficará o código a ser chamado no evento:

procedure TForm1.LocationSensor1LocationChanged(Sender: TObject; const OldLocation, NewLocation: TLocationCoord2D);

const
  Navegar : string = 'https://maps.google.com/?q=%s,%s&&t=h&&z=13&&hl=pt-BR&&output=embed';

begin
  Label2.Text := Format(navegar, [ Format('%2.6f', [NewLocation.Latitude]), Format('%2.6f', [NewLocation.Longitude])]);
  WebBrowser1.Navigate(Format(navegar, [Format('%2.6f', [NewLocation.Latitude]), Format('%2.6f', [NewLocation.Longitude])]));
end;

Com isso já temos o necessário para rodar a aplicação. Apenas explicando o conteúdo do código adicionado:

Declaramos a constante Navegar do tipo string e atribuímos a ela a linha que pegamos “emprestada” do GoogleMaps. Em seguida usamos a função Format encadeadamente, uma vez passando valores do tipo Float, Latitude e Longitude do NewLocation passado no Evento sempre que a localização mudar. Utilizamos aí o formato de 2 casas inteiras e 6 casas decimais expressas pela string ‘%2.6f’, assim forçamos as coordenadas a serem exibidas sob essa formatação.

Exibimos esse resultado na propriedade Text do Label2, este conteúdo é a url a qual o Webbrowser1 logo em seguida recebe como parâmetro informando o destino da sua navegação.

Executando a aplicação percebemos que a mesma já funciona, entretanto pode ocorrer de o mapa não estar representando sua real localização.

Aplicação não marca no mapa

O ponto chave da localização

Certamente, se você está no Brasil, perceberá que o separado de decimais e inteiros adotados no aqui é a vírgula(“,”), porém quando passamos as coordenadas com vírgula o GoogleMaps não consegue entender, uma vez que seus servidores estão em solo norte-americanos e lá o separador decimal é o ponto (“.”).

Para resolvermos esse impasse basta setarmos o separador decimal dentro de nossa aplicação para ponto “.”, sendo assim vamos inserir imediatamente após o “begin” da codificação do evento OnLocationChanged  essa linha FormatSettings.DecimalSeparator := ‘.’; .

Com isso devemos salvar nossa aplicação e executá-la novamente para conferir o resultado.

LocalizeMe em Execução

A chave para que a aplicação realmente funcione no Brasil é termos o Separador de decimal alterado… simples assim, fazendo isso o exemplo postado pela Embarcadero em vídeo, ou o exemplo que acompanha o Delphi XE5 disponibilizado em sua “Welcome Page” funcionarão perfeitamente.

39 Replies to “Sensor de Localização de Dispositivos Móveis com Delphi XE5”

    1. Bruno boa tarde. Na verdade nesse exemplo não usamos componente mas sim a url do googlemaps, para traçar rota, faça o procedimento no navegador e depois copie essa url para o exemplo, trocando os fatores variáveis “origem” e “destino”. Vai funcionar!

    1. Bem Bruno… não sei se você tentou fazer algo… mas basicamente seria o seguinte: abrir o browser e acessar o Google Maps… fazer sua pesquisa de rota, daí você clica para exibir o link da pesquisa de rotas, no meu caso ficou assim:
      https://maps.google.com/?saddr=Pimenta-MG&&daddr=Itaocara-RJ&&t=h&&z=13&&hl=pt-BR

      note que temos as variáveis saddr e daddr com valores de “Pimenta Minas Gerais” e “Itaocara” respectivamente esses valores serão substituídos por strings a serem passadas por seu aplicativo.

      Tente fazer isso!

      1. Olá, não estou conseguindo visualizar o exemplo que fez para o Bruno, mostrando como traçar rotas. Preciso fazer um app que receba um determinado endereço e exiba no mapa e também traçe rotas entre dois endereços.
        Pode me ajudar? Obrigado

        1. Olá Francisco, o para traçar rotas, vá até o maps normal pelo computador, trace uma de exemplo. Daí você pega o conteúdo da barra de endereços no seu navegador e adapta transformando seus pontos destino e partida em variáveis. Esse é o conceito, veja se resolve!
          Se não sinalize aqui.

          Abraço.

  1. Olá landerson.
    Parabéns pelo exemplo. A questão é que fiz um teste aqui e o meu mapa fica atualizando constantemente, impossibilitando a visualização do local referenciado. Mudei as propriedades do componente Location, mas não consegui estabilizar. Sabe o que pode ser ?
    Obrigado.

  2. Boa noite camarada, gostaria de saber o seguinte, teria como implementar para um lugar em especifico, e esse lugar tendo varios andares, estou pretendendo criar um GPS para supermercados, faculdades etc. Sabe me dizer como posso tratar essas questoes de andares? O Delphi tem esse requisito?
    Desde ja agradeço, fique na paz!

    1. Olá Leonardo… coisa linda essa que você quer hein?! Já vi em cinema rsrs. Brincadeiras a parte acredito que seja possível sim uma vez que os dispositivos conseguem informar altitude e elevação de terreno… mas te sendo bem sincero nem imagino como proceder. Muita pesquisa aí no seu caminho… é o que vejo para você.

      Um abraço.

  3. Bom dia Landerson, tentei trabalhar com este sensor e tem hora que funciona e tem hora que não, na verdade eu precisava somente que me retornasse o nome da cidade onde estou, sabe como fazer isto?

    1. Boa tarde Fabio. O sensor depende muito do aparelho para fixar a real posição do mesmo.
      Sinceramente a sua questão só conseguiria resolver com uma profunda pesquisa… talvez você consiga algo dando uma pesquisada na api do Google Maps.
      Lembro-me de ter visto situação semelhante a descrita por você a muito tempo atrás num exemplo do Marco Cantù (http://blog.marcocantu.com/blog/google_map_delphi_server.html), como falei faz muito tempo… mas quem sabe consiga evoluir a partir daí.

      Abraço.

        1. Marcio bem vindo e obrigado pela participação!
          O resultado que você está obtendo sendo JSON, tem seu “valor” já expresso em string, logo você deve ler o JSON e pegar o JSON.VALUE passando ele para sua url prefixada nas posições desejadas.
          Faça uso da função: Format() deve resolver tudo por aí!
          Abraço e mais uma vez obrigado pela participação!

  4. Olá, estou com um problema muito grave no android, porém, acredito que alguém poderá me ajudar. Já desenvolvi uma aplicação, e meu problema é quando o celular desliga a tela automanticamente (tempo de duração da luz de fundo). Assim que a tela se apaga, caso tenha um Showmessage, ou qualquer tela de mensagem aguardando clicar em OK, o sistema trava. O que pode ser isto? uso xe5 up2

    1. Olá Juan… seja bem vindo! Dê uma estudada no componente LocationSensor, ele tem a propriedade Started que retorna se ele está em funcionamento. (Boolean)
      (http://docwiki.embarcadero.com/Libraries/XE7/en/System.Sensors.TCustomLocationSensor.Started) Ele é ativado chamando o método Start.

      Vale a leitura para um melhor entendimento: http://docwiki.embarcadero.com/Libraries/XE7/en/System.Sensors.Components.TLocationSensor

      Apenas lembrando que o componente passou por um grande amadurecimento desde a postagem, na versão XE7 ele está com muito mais recursos disponíveis.

      Abração e boa sorte aí!

    1. Olá José Luís, seja bem vindo! Olha possível acredito que seja sim, porém não tenho a mínima idéia de como seria implementar tal funcionalidade.
      Lembrando que o OI MAPAS é assim, então por isso acredito que seja possível.
      Lamento não poder ser mais eficiente que isso, mas realmente passa bem longe qualquer idéia de como fazê-lo.

      De qualquer forma reitero as boas vindas e muito obrigado por sua participação.

  5. Ola, estou usando o Xe7, compilei aplicação porém a mesma não utiliza o GPS, mesmo ele estando ativo, ela nao usa os recursos. Sera que tem que usar o tal intent pra interagir

  6. Landerson, primeiraramente obrigado pela atenção, com o conteúdo do seu blog estou praticamente terminando meu app (comercial)..Landerson, sobre a string do google, você tem um exemplo de como decodificar ela “quebrar” em rua, numero, bairro, cep ? a partir da localização gostaria destes dados.

    Agradeço desde já atenção.

    1. Olá Jefferson… Eu nunca cheguei a fazer nada nesse sentido, tentarei retomar com novos exemplos a partir de novembro, tentarei abordar essa situação!
      Até lá, ou até a próxima!

    1. Olá David obrigado por sua participação e seja bem vindo!
      Até o presente momento não tentei fazer ainda, entretanto tenho em mente alguns novos exemplos a partir do próximo mês e colocarei esse na lista de para novas postagens.

      Até a próxima e mais uma vez obrigado!

    1. Olá Jose Renato, nunca tentei nada nesse sentido pretendo dá uma analisada na questão após a Conference, chegando a alguma solução posto aqui.
      Mas o bom e velho Delta S/Delta T deve resolver.

      Obrigado por sua participação e até a próxima!

  7. Olá Landerson, belo artigo !!
    Verifiquei em um comentário acima que você não havia tido contato com trabalho com mapas offline. Continua sem ter ainda contato ? Você comentou sobre o OiMapas, ele é feito em Delphi ?
    Obrigado.

  8. Olá Landerson, primeiramente parabéns pelo post, Testei em minha aplicação e funcionou perfeitamente, inclui rotas com deslocamento gerado por OldLocation e NewLocation.

    Tenho uma dúvida em relação ao WebBrowser, para cada vez que é atualizado Location, será aberto novamente o WebBrowser, gerando um delay muito grande e trafego de rede alto também.

    haveria uma forma de atualizar somente a localização no mapa sem ter que abrir a URL toda vez ?

Deixe um comentário