quinta-feira, 23 de maio de 2019

Android – Apresentando a classe LocationManager


 Caro amigo leitor, neste artigo irei apresentar algumas funcionalidades da classe “LocationManager” do Sistema Android, nos permitindo obter facilmente informações sobre posições geográficas através da latitude, longitude, entre outros atributos. Podemos utilizar o GPS, Wi-fi ou qualquer plano de dados como exemplo de “provedores de localização”. Para este artigo estarei utilizando o próprio Wi-fi para obter estes dados. Criarei um pequeno exemplo abrangendo todos os passos para utilizar corretamente esta classe.

Criando o Exemplo

Iniciaremos um projeto do zero clicando em “File/New/New Project...” definindo um nome qualquer, como por exemplo: “LocatioManager”. Defina a API 23 (Android 6) como SDK mínimo e uma “Activity” em branco. Teremos a estrutura básica conforme ilustra a Imagem 01.
Figura 01: Projeto Inicial.

Configurando o “AndroidManifest.xml”

Faremos duas implementações neste arquivo de configuração, sendo a primeira para acesso as permissões de localização pela rede (android.permission.ACCESS_COARSE_LOCATION) e a segunda para acessar a localização pela rede e GPS do dispositivo (android.permission.ACCESS_FINE_LOCATION). Abaixo demonstrarei todas as informações necessárias. Listagem 01.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   
package="exemplo.locationmanager" >


    <
uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <
uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <
application
       
android:allowBackup="true"
       
android:icon="@mipmap/ic_launcher"
       
android:label="@string/app_name"
       
android:supportsRtl="true"
       
android:theme="@style/AppTheme" >
        <
activity android:name=".MainActivity" >
            <
intent-filter>
                <
action android:name="android.intent.action.MAIN" />
                <
category android:name="android.intent.category.LAUNCHER" />
            </
intent-filter>
        </
activity>
    </
application>
</
manifest>
Listagem 01.

Criando o Lay-out
O nosso lay-out será composto de um “Button” para obter a localização através do objeto “LocationManager” seguido de quatro “TextViews” com os seguinte dados: Latitude, Longitude, Data/Hora e Precisão. Confira estes detalhes na Imagem 02.
Figura 02: Layout proposto.


Teremos o XML correspondente abaixo: (Listagem 02)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   
xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:id="@+id/activity_main"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
android:orientation="vertical"
   
android:paddingLeft="@dimen/activity_horizontal_margin"
   
android:paddingRight="@dimen/activity_horizontal_margin"
   
android:paddingTop="@dimen/activity_vertical_margin"
   
android:paddingBottom="@dimen/activity_vertical_margin"
   
tools:context="exemplo.locationmanager.MainActivity"
   
android:weightSum="1">

    <
Button
       
android:text="Obter Localização"
       
android:id="@+id/btnObterLocalizacao"
       
android:layout_width="222dp"
       
android:layout_height="wrap_content"
       
android:onClick="ObterLocalização"
       
android:gravity="center_vertical|center_horizontal|center"
       
android:layout_gravity="center"/>

    <
LinearLayout
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:orientation="horizontal">
        <
TextView
           
android:text="Latitude:"
           
android:textStyle="bold"
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:layout_marginTop="16dp"
           
android:id="@+id/txtlbLatitude" />
        <
TextView
           
android:text="0.00"
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:layout_marginTop="16dp"
            
android:id="@+id/txtLatitude" />
    </
LinearLayout>

    <
LinearLayout
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:orientation="horizontal">
        <
TextView
           
android:text="Longitude:"
           
android:textStyle="bold"
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:layout_marginTop="16dp"
           
android:id="@+id/txtlbLongitude" />
        <
TextView
           
android:text="0.00"
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:layout_marginTop="16dp"
           
android:id="@+id/txtLongitude" />
    </
LinearLayout>

    <
LinearLayout
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:orientation="horizontal">
        <
TextView
           
android:text="Data/Hora:"
           
android:textStyle="bold"
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:layout_marginTop="16dp"
           
android:id="@+id/txtlbDataHora" />
        <
TextView
           
android:text="99/99/9999 99:99:99"
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:layout_marginTop="16dp"
           
android:id="@+id/txtDataHora" />
    </
LinearLayout>

    <
LinearLayout
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:orientation="horizontal">
        <
TextView
           
android:text="Precisão:"
           
android:textStyle="bold"
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:layout_marginTop="16dp"
           
android:id="@+id/txtlbPrecisao" />
        <
TextView
           
android:text="0.00"
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:layout_marginTop="16dp"
           
android:id="@+id/txtPrecisao" />
    </
LinearLayout>
</
LinearLayout>
Listagem 02.

Para o layout utilizei como padrão o tipo “LinearLayout” com orientação “Vertical”, seguindo dos componentes “TextViews” para cada tipo de informação desejada.

Codificando o Exemplo

O exemplo terá como base o Método “ObterLocalização” o qual será invocado no evento “OnClick” do “Button” para setar as propriedades: Latitude, Longitude, Data/Hora e Precisão.
Primeiramente deveremos importar algumas bibliotecas essenciais para o bom funcionamento, segue abaixo:

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.text.SimpleDateFormat;

Teremos algumas, tais como: “location.Location”, “location.LocationListener” e “location.LocationManager” que servirão diretamente à nossa classe LocationManager. Usaremos também outras para suporte a compatibilidade de aplicativos (“support.v4.app.ActivityCompat” e “support.v7.app.AppCompatActivity”), etc ... Não entrarei em maiores detalhes, pois as outras já foram abordadas em artigos anteriores.

public class MainActivity extends AppCompatActivity
{
   
@Override
   
protected void onCreate(Bundle savedInstanceState)
    {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main);
    }

O método “OnCreate” irá instanciar e inflar nosso lay-out.


   
public void ObterLocalizacao(View v)
    {
        LocationManager locationManager = (LocationManager) getSystemService(Context.
LOCATION_SERVICE);

Instanciaremos indiretamente a classe “LocationManager” a recuperando através do método “getSystemService (Context.LOCATION_SERVICE)”


if (ActivityCompat.checkSelfPermission(this,   Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&

ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
   
return;
}

Aproveitaremos também para realizar uma verificação de permissão de acesso com o método “CheckSelfPermission”, o qual irá analisar se a permissão foi realizada com sucesso no arquivo “AndroidManifest”.


locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, new LocationListener()
{

A interface LocationListener” recebe como parâmetro o tipo de provedor (no nosso caso usaremos a internet) que nos obriga a implementar os seguintes métodos: (“OnStatusChanged”, o qual será disparado quando o Status da localização for alterado, “OnProviderEnabled”, o qual indica se o Provider está Habilitado, “OnProviderDisabled” indicando se o mesmo está desabilitado e por último o “OnLocationChanged” que abordarei logo abaixo).

   
@Override
   
public void onStatusChanged(String arg0, int arg1, Bundle arg2)
    {
        
//Método disparado quando o status for alterado
   
}

    @Override
   
public void onProviderEnabled(String arg0)
    {
       
//Método indica o Provider Habilitado
   
}

   
@Override
   
public void onProviderDisabled(String arg0)
    {
       
//Método indica o Provider Desabilitado
   
}

   
@Override
   
public void onLocationChanged(Location location)
    {
      TextView latitude = (TextView) findViewById(R.id.
txtLatitude);
      TextView longitude = (TextView) findViewById(R.id.
txtLongitude);
      TextView datahora = (TextView) findViewById(R.id.
txtDataHora);
      TextView precisao = (TextView) findViewById(R.id.
txtPrecisao);

     
if (location != null)
      {
       latitude.setText(String.valueOf(location.getLatitude()));
       longitude.setText(String.valueOf(location.getLongitude()));
       precisao.setText(String.valueOf(location.getAccuracy()));
       SimpleDateFormat data =
new SimpleDateFormat("dd / MM / yyyy HH: mm: ss");
       datahora.setText(data.format(location.getTime()));
      }
    }
   },
null);
  }
}

Recebemos via parâmetro o objeto “location”, criaremos as variáveis do tipo “TextView” para receber os dados e através de uma verificação se este objeto está nulo. Setaremos os valores usando os métodos “getLatitude()” para obter a Latitude, “getLongitude()” para obter a Longitude, “getAccuracy()” para obter a precisão e “getTime()” para obter a Data e Hora.
Teremos um resultado idêntico ao da Figura 03.

 
Figura 03: Informações Geográficas.

Conclusões

Procurei neste artigo explorar de uma forma prática o uso da classe “LocationManager”, seguido de um pequeno exemplo de sua utilização no dia-a-dia. Usei como provedor o próprio Wi-fi, ressaltando que também poderíamos ter utilizado qualquer plano de dados, ou o próprio GPS do telefone celular, tablet.
Fica aí a dica, um abraço e até o mês que vem!

Referências

https://developer.android.com/reference/android/location/LocationManager.html

Sobre o autor

Thiago Cavalheiro Montebugnoli adora aprender novas tecnologias. Formado pela Faculdade de Tecnologia de Botucatu – SP (FATEC), já desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco de Dados SQL Server e Firebird. Como experiências profissionais mais recentes, possui em seu currículo sua atuação no Centro de Processamento de Dados da Prefeitura Municipal de Itaí-SP e atualmente compõe a equipe da Coordenadoria Tecnologia da Informação no IFSP – Instituto Federal do Estado de São Paulo em Avaré. Além disso, é colunista mensal da Revista The Club Megazine e é consultor Técnico do The Club. Possui as seguintes certificações: MCP - Microsoft Certified Professional, MCTS - Microsoft Certified Technology Specialist, MCAD - Microsoft Certified Application Developer e  MCSD - Microsoft Certified Solution Developer.