How to get the current location of the android device?

10

I'm developing an android application that needs to get the current location of the device (Latitude, Longitude) and use this data in google maps ... how can I do this? If you help me get only the latitude and longitude coordinates, it will be a great help ... Obfuscated

    
asked by anonymous 21.04.2016 / 15:58

4 answers

7

I'll try to summarize. If you want to understand more about each step I quote, I recommend reading this document . >.

First step - Configuration

Add the dependency in Gradle:

dependencies {
   compile 'com.google.android.gms:play-services:8.1.0'
}

Add permission on AndroidManifest.xml

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

and / or

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

Making use of GoogleApiClient

First, you need to instantiate the GoogleApiClient class, because it will be through it that we will access services that exist in Google Services, such as the Location Service.

I created an activity to demonstrate how this happens:

public class LocationActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

private GoogleApiClient googleApiClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    googleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this) //Be aware of state of the connection 
            .addOnConnectionFailedListener(this) //Be aware of failures
            .build();

    //Tentando conexão com o Google API. Se a tentativa for bem sucessidade, o método onConnected() será chamado, senão, o método onConnectionFailed() será chamado.
    googleApiClient.connect();

}

@Override
protected void onStop() {
    super.onStop();
    pararConexaoComGoogleApi();
}

public void pararConexaoComGoogleApi() {
    //Verificando se está conectado para então cancelar a conexão!
    if (googleApiClient.isConnected()) {
        googleApiClient.disconnect();
    }
}

/**
 * Depois que o método connect() for chamado, esse método será chamado de forma assíncrona caso a conexão seja bem sucedida.
 *
 * @param bundle
 */
@Override
public void onConnected(Bundle bundle) {
    //Conexão com o serviços do Google Service API foi estabelecida!
}

/**
 * Esse método é chamado quando o client está temporariamente desconectado. Isso pode acontecer quando houve uma falha ou problema com o serviço que faça com que o client seja desligado.
 * Nesse estado, todas as requisições e listeners são cancelados.
 * Não se preocupe em tentar reestabelecer a conexão, pois isso acontecerá automaticamente.
 * As aplicações devem desabilitar recursos visuais que estejam relacionados com o uso dos serviços e habilitá-los novamente quando o método onConnected() for chamado, indicando reestabelecimento da conexão. 
 */
@Override
public void onConnectionSuspended(int i) {
    // Aguardando o GoogleApiClient reestabelecer a conexão.
}

/**
 * Método chamado quando um erro de conexão acontece e não é possível acessar os serviços da Google Service.
 *
 * @param connectionResult
 */
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    //A conexão com o Google API falhou! 
    pararConexaoComGoogleApi();
   }
}

If the connection is established successfully, then we can use API services.

Adding the Location Service API

It's simple to start using the Location Service API through the client we created. Just add the API reference during instantiation of GoogleApiClient like this:

googleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

Now we can use the location API when the client establishes the connection. We will do this through the LocationServices.FusedLocationApi class:

Capturing Last Known Location

In the LocationServices.FusedLocationApi class, we can capture the last location identified in this way in our onConnected() method (since it is the method called when the connection was established):

@Override
    public void onConnected(Bundle bundle) {
        //Google API connection has been done successfully
        Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
    }

Do you want latitude and longitude? Just call the methods Location.getLatitude() and Location.getLongitude() .

Anything to say!

    
22.04.2016 / 15:42
4
  

Also read this post about Geolocation on Android

First of all, you should add in manifest of your application:

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

Class usage example:

LocationResult locationResult = new LocationResult(){
    @Override
    public void gotLocation(Location location){
        //Usar a localizacao aqui!
    }
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);

MyLocation class:

import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class MyLocation {
    Timer timer1;
    LocationManager lm;
    LocationResult locationResult;
    boolean gps_enabled=false;
    boolean network_enabled=false;

    public boolean getLocation(Context context, LocationResult result)
    {
        //É usado o callback LocationResult para passar as coordenadas para o codigo do usuario.
        locationResult=result;
        if(lm==null)
            lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

        //se o provedor de localizacao nao estiver habilitado, teremos uma excecao.
        try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
        try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}

        //Codigo para nao tentar fazer a leitura sem provedor de localizacao disponivel
        if(!gps_enabled && !network_enabled)
            return false;

        if(gps_enabled)
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
        if(network_enabled)
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
        timer1=new Timer();
        timer1.schedule(new GetLastLocation(), 20000);
        return true;
    }

    LocationListener locationListenerGps = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerNetwork);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    LocationListener locationListenerNetwork = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerGps);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    class GetLastLocation extends TimerTask {
        @Override
        public void run() {
             lm.removeUpdates(locationListenerGps);
             lm.removeUpdates(locationListenerNetwork);

             Location net_loc=null, gps_loc=null;
             if(gps_enabled)
                 gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
             if(network_enabled)
                 net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

             //se tiver os dois valores, usar o mais atualizado
             if(gps_loc!=null && net_loc!=null){
                 if(gps_loc.getTime()>net_loc.getTime())
                     locationResult.gotLocation(gps_loc);
                 else
                     locationResult.gotLocation(net_loc);
                 return;
             }

             if(gps_loc!=null){
                 locationResult.gotLocation(gps_loc);
                 return;
             }
             if(net_loc!=null){
                 locationResult.gotLocation(net_loc);
                 return;
             }
             locationResult.gotLocation(null);
        }
    }

    public static abstract class LocationResult{
        public abstract void gotLocation(Location location);
    }
}
  

If this answer does not match the expected result, read this   topic, from SOen itself.

    
22.04.2016 / 15:17
2

I recommend reading this post link has a good explanation of how to do this as there are many important things that you should know about before implementing.

But for a small example following what is in this link I passed: Download the sample project link

Copy the ILastLocationFinder interface and the LocationFinder class for your project

Then implement the following in your activity:

locationFinder = new LocationFinder(this);

locationFinder.setChangedLocationListener(new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {           
        //TODO o seu código aqui
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
});

Location location = locationFinder.getLastBestLocation(10000, 1000000);

if (location != null) {
    locationFinder.cancel();
    //TODO o seu código aqui
}
    
22.04.2016 / 15:09
2

With the 11.0.0 version of the Google Play services SDK , obtaining the user's location has still become simpler. You no longer need to manually manage your Google Play service connection through GoogleApiClient.

Last location.

To get the device's last location just get the FusedLocationProviderClient with LocationServices.getFusedLocationProviderClient() and use the getLastLocation() method.

private FusedLocationProviderClient mFusedLocationClient;
protected Location mLastLocation;

@SuppressWarnings("MissingPermission")
private void getLastLocation() {
mFusedLocationClient.getLastLocation()
    .addOnCompleteListener(this, new OnCompleteListener<Location>() {
        @Override
        public void onComplete(@NonNull Task<Location> task) {
            if (task.isSuccessful() && task.getResult() != null) {

                //obtém a última localização conhecida
                mLastLocation = task.getResult();

            } else {

                //Não há localização conhecida ou houve uma excepção
                //A excepção pode ser obtida com task.getException()
            }
        }
    });
}

Do not forget that ACCESS_FINE_LOCATION is required in AndroidManifest.xml and eventually ( targetSdkVersion >= 23 ) handle it at runtime.

Location monitoring

A little more work, mainly due to the verification of the device settings, but simpler thanks to the changes introduced in version 11.0.0.

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_CHECK_SETTINGS = 0;
    private TextView textView;
    private FusedLocationProviderClient mFusedLocationClient;
    private LocationRequest mLocationRequest;
    private SettingsClient mSettingsClient;
    private LocationSettingsRequest mLocationSettingsRequest;
    private LocationCallback mLocationCallback;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView)findViewById(R.id.textView);

        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        mSettingsClient = LocationServices.getSettingsClient(this);

        //LocationResquest com as definições requeridas
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(10 * 1000)        // 10 seconds, in milliseconds
                .setFastestInterval(1 * 1000); // 1 second, in milliseconds
        //Construção dum LocationSettingsRequest com as definições requeridas
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        mLocationSettingsRequest = builder.build();

        //Callback a ser chamado quando houver alterações na localização
        mLocationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                super.onLocationResult(locationResult);

                Location currentLocation = locationResult.getLastLocation();
                handleCurrentLocation(currentLocation);
            }
        };
    }

    //Inicia o processo de pedido de actualizações de localização
    private void startLocationUpdates() {
        // Verifica se as definições do dispositivo estão configuradas para satisfazer
        // as requeridas pelo LocationSettingsRequest.
        mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
            .addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
                @Override
                public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                    // Todas as definições do dispositivo estão configuradas para satisfazer as requeridas.
                    // Inicia o pedido de actualizações de localização

                    //noinspection MissingPermission
                    mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                            mLocationCallback, Looper.myLooper());
                }
            })
            .addOnFailureListener(this, new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    int statusCode = ((ApiException) e).getStatusCode();
                    switch (statusCode) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            // As definições do dispositivo não satisfazem as requeridas.
                            //Mas podem ser alteradas pelo utilizador.
                            try {
                                // Mostra um dialog chamando startResolutionForResult(),
                                // o resultado deverá ser verificado em onActivityResult().
                                ResolvableApiException rae = (ResolvableApiException) e;
                                rae.startResolutionForResult(MainActivity.this,
                                                             REQUEST_CHECK_SETTINGS);
                            } catch (IntentSender.SendIntentException sie) {
                                Log.i("Location", "PendingIntent unable to execute request.");
                            }
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            // As definições do dispositivo não satisfazem as requeridas,
                            // não havendo forma de as resolver.
                            String errorMessage = "As definições do dispositivo não " +
                                    "satisfazem as requeridas, altere-as nas Configurações";
                            Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_LONG)
                                 .show();
                    }
                }
            });
    }

    @Override
    public void onResume() {
        super.onResume();
        if (checkPermissions()) {
            startLocationUpdates();
        } else if (!checkPermissions()) {
            //Não implementado, apenas necessário se targetSdkVersion >= 23
            requestPermissions();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        mFusedLocationClient.removeLocationUpdates(mLocationCallback);
    }

    private boolean checkPermissions() {
        int permissionState = ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION);
        return permissionState == PackageManager.PERMISSION_GRANTED;
    }

    private void handleCurrentLocation(Location currentLocation) {
        textView.setText(currentLocation.toString());
    }    
}

For simplicity, the run-time permission request was not implemented (only required if targetSdkVersion >= 23 ).
ACCESS_FINE_LOCATION is required in AndroidManifest.xml .

References:

16.06.2017 / 00:22