How to get the current location of android device?

Asked

Viewed 16,860 times

10

I am 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 coordinates of latitude and longitude will be of great help... Obgrigado

4 answers

7


I will try to summarize. If you want to understand more deeply every step I quote, I recommend reading this document.

First step - Configuration

Add dependency to Gradle:

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

Add permission to 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, we need to instantiate the Googleapiclient class, because it is through it that we will access the services that exist in Google Services, such as Location Service.

I created a 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 successfully established, we may then use API.

Adding the Location Service API

It is simple to use the Location Service API through the client that we created. Just add the reference of this API during the instantiation of Googleapiclient thus:

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

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

Capturing the Last Identified Location

Through class LocationServices.FusedLocationApi we can capture the last identified location in this way in our method onConnected() (because it’s 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);
    }

Want latitude and longitude? Just call the methods Location.getLatitude() and Location.getLongitude().

Anything comment!

4

Read also this post about Geolocation on Android

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

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

Example of class usage:

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 meet the expected result, read this topic, by Soen himself.

3

With the version 11.0.0 of Google Play services SDK obtaining the user’s location has become even simpler. Now it is no longer necessary to manually manage the connection to the Google Play service through Googleapiclient.

Last location.

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

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()
            }
        }
    });
}

Don’t forget that permission is required ACCESS_FINE_LOCATION in the Androidmanifest.xml and, eventually(targetSdkVersion >= 23), deal with it at runtime.

Location Monitoring(Location updates)

A little more work, mainly due to the verification of the settings of the device, however 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());
    }    
}

To simplify was not implemented the request for permission at runtime(only necessary if targetSdkVersion >= 23).
Permission is required ACCESS_FINE_LOCATION in the Androidmanifest.xml.

References:

2

I recommend reading this post http://android-developers.blogspot.com.br/2011/06/deep-dive-into-location.html has a good explanation of how to do this, because there are dives important things you should know before implementing.

But for a small example following what is in this link I passed: Download the sample project https://code.google.com/archive/p/android-protips-location/source/default/source

Copy the Ilastlocationfinder interface and Locationfinder class to 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
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.