Administrador de ubicación de Android, obtener ubicación de GPS, si no hay GPS, luego llegar a la ubicación del proveedor de red

Estoy usando este código dado a continuación para obtener ubicaciones:

public Location getLocation() { try { mLocationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE); // getting GPS status boolean isGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); // getting network status boolean isNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { // no network provider is enabled } else { // First get location from Network Provider if (isNetworkEnabled) { mLocationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("Network", "Network"); if (mLocationManager != null) { location = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (location != null) { lat = location.getLatitude(); lng = location.getLongitude(); } } } //get the location by gps if (isGPSEnabled) { if (location == null) { mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("GPS Enabled", "GPS Enabled"); if (mLocationManager != null) {location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location != null) { lat = location.getLatitude(); lng = location.getLongitude(); } } } } } } catch (Exception e) { e.printStackTrace(); } return location; } 

Está funcionando correctamente, pero me gustaría obtener primero la ubicación del GPS y, en caso de que no esté disponible, el administrador de la ubicación debe consultar al proveedor de la red, lo cual me causa problemas.

Por favor, recomiéndame la buena manera de hacer esto.

Usted dice que primero necesita la ubicación del GPS si está disponible, pero lo que hizo primero es obtener la ubicación del proveedor de la red y luego del GPS. Esto obtendrá la ubicación de la red y del GPS si ambos están disponibles. Lo que puedes hacer es escribir estos casos en if..else if block. Similar a-

 if( !isGPSEnabled && !isNetworkEnabled) { // Can't get location by any way } else { if(isGPSEnabled) { // get location from GPS } else if(isNetworkEnabled) { // get location from Network Provider } } 

Por lo tanto, esto buscará la ubicación del GPS primero (si está disponible), de lo contrario, intentará obtener la ubicación del proveedor de la red.

EDITAR :

Para hacerlo mejor, publicaré un fragmento. Considera que está en try-catch :

 boolean gps_enabled = false; boolean network_enabled = false; LocationManager lm = (LocationManager) mCtx .getSystemService(Context.LOCATION_SERVICE); gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER); Location net_loc = null, gps_loc = null, finalLoc = null; if (gps_enabled) gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (network_enabled) net_loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (gps_loc != null && net_loc != null) { //smaller the number more accurate result will if (gps_loc.getAccuracy() > net_loc.getAccuracy()) finalLoc = net_loc; else finalLoc = gps_loc; // I used this just to get an idea (if both avail, its upto you which you want to take as I've taken location with more accuracy) } else { if (gps_loc != null) { finalLoc = gps_loc; } else if (net_loc != null) { finalLoc = net_loc; } } 

Ahora comprueba el finalLoc para null , si no, return . Puede escribir el código anterior en una función que devuelve la ubicación deseada ( finalLoc ). Creo que esto podría ayudar.

La forma recomendada de hacerlo es usar LocationClient :

Primero, defina los valores del intervalo de actualización de ubicación. Ajuste esto a sus necesidades.

 private static final int MILLISECONDS_PER_SECOND = 1000; private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS; private static final int FASTEST_INTERVAL_IN_SECONDS = 1; private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS; 

Haga que su Activity implemente GooglePlayServicesClient.ConnectionCallbacks , GooglePlayServicesClient.OnConnectionFailedListener y LocationListener .

 public class LocationActivity extends Activity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {} 

Luego, configure un LocationClient en el método onCreate() de su Activity :

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLocationClient = new LocationClient(this, this, this); mLocationRequest = LocationRequest.create(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setInterval(UPDATE_INTERVAL); mLocationRequest.setFastestInterval(FASTEST_INTERVAL); } 

Agregue los métodos requeridos a su Activity ; onConnected() es el método que se llama cuando se conecta el LocationClient . onLocationChanged() es donde recuperarás la ubicación más actualizada.

 @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.w(TAG, "Location client connection failed"); } @Override public void onConnected(Bundle dataBundle) { Log.d(TAG, "Location client connected"); mLocationClient.requestLocationUpdates(mLocationRequest, this); } @Override public void onDisconnected() { Log.d(TAG, "Location client disconnected"); } @Override public void onLocationChanged(Location location) { if (location != null) { Log.d(TAG, "Updated Location: " + Double.toString(location.getLatitude()) + "," + Double.toString(location.getLongitude())); } else { Log.d(TAG, "Updated location NULL"); } } 

Asegúrese de conectar / desconectar el LocationClient para que solo use batería extra cuando sea absolutamente necesario y para que el GPS no se ejecute indefinidamente. El LocationClient debe estar conectado para obtener datos del mismo.

 public void onResume() { super.onResume(); mLocationClient.connect(); } public void onStop() { if (mLocationClient.isConnected()) { mLocationClient.removeLocationUpdates(this); } mLocationClient.disconnect(); super.onStop(); } 

Obtener la ubicación del usuario. Primero intente usar el LocationClient ; si eso falla, retroceda al LocationManager .

 public Location getLocation() { if (mLocationClient != null && mLocationClient.isConnected()) { return mLocationClient.getLastLocation(); } else { LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); if (locationManager != null) { Location lastKnownLocationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (lastKnownLocationGPS != null) { return lastKnownLocationGPS; } else { return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } } else { return null; } } } 

utilice la API de fusión que el desarrollador de Google ha desarrollado con la fusión de un sensor GPS, un magnetómetro, un acelerómetro que también utiliza la ubicación de la red o Wifi para calcular o estimar la ubicación. También es capaz de proporcionar actualizaciones de ubicación también dentro del edificio con precisión.

 package com.example.ashis.gpslocation; import android.app.Activity; import android.location.Location; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * Location sample. * * Demonstrates use of the Location API to retrieve the last known location for a device. * This sample uses Google Play services (GoogleApiClient) but does not need to authenticate a user. * See https://github.com/googlesamples/android-google-accounts/tree/master/QuickStart if you are * also using APIs that need authentication. */ public class MainActivity extends Activity implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static final long ONE_MIN = 500; private static final long TWO_MIN = 500; private static final long FIVE_MIN = 500; private static final long POLLING_FREQ = 1000 * 20; private static final long FASTEST_UPDATE_FREQ = 1000 * 5; private static final float MIN_ACCURACY = 1.0f; private static final float MIN_LAST_READ_ACCURACY = 1; private LocationRequest mLocationRequest; private Location mBestReading; TextView tv; private GoogleApiClient mGoogleApiClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!servicesAvailable()) { finish(); } setContentView(R.layout.activity_main); tv= (TextView) findViewById(R.id.tv1); mLocationRequest = LocationRequest.create(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setInterval(POLLING_FREQ); mLocationRequest.setFastestInterval(FASTEST_UPDATE_FREQ); mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } } @Override protected void onResume() { super.onResume(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } } @Override protected void onPause() {d super.onPause(); if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { mGoogleApiClient.disconnect(); } } tv.setText(location + ""); // Determine whether new location is better than current best // estimate if (null == mBestReading || location.getAccuracy() < mBestReading.getAccuracy()) { mBestReading = location; if (mBestReading.getAccuracy() < MIN_ACCURACY) { LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); } } } @Override public void onConnected(Bundle dataBundle) { // Get first reading. Get additional location updates if necessary if (servicesAvailable()) { // Get best last location measurement meeting criteria mBestReading = bestLastKnownLocation(MIN_LAST_READ_ACCURACY, FIVE_MIN); if (null == mBestReading || mBestReading.getAccuracy() > MIN_LAST_READ_ACCURACY || mBestReading.getTime() < System.currentTimeMillis() - TWO_MIN) { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); //Schedule a runnable to unregister location listeners @Override public void run() { LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, MainActivity.this); } }, ONE_MIN, TimeUnit.MILLISECONDS); } } } @Override public void onConnectionSuspended(int i) { } private Location bestLastKnownLocation(float minAccuracy, long minTime) { Location bestResult = null; float bestAccuracy = Float.MAX_VALUE; long bestTime = Long.MIN_VALUE; // Get the best most recent location currently available Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); //tv.setText(mCurrentLocation+""); if (mCurrentLocation != null) { float accuracy = mCurrentLocation.getAccuracy(); long time = mCurrentLocation.getTime(); if (accuracy < bestAccuracy) { bestResult = mCurrentLocation; bestAccuracy = accuracy; bestTime = time; } } // Return best reading or null if (bestAccuracy > minAccuracy || bestTime < minTime) { return null; } else { return bestResult; } } @Override public void onConnectionFailed(ConnectionResult connectionResult) { } private boolean servicesAvailable() { int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (ConnectionResult.SUCCESS == resultCode) { return true; } else { GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0).show(); return false; } } } 

Si desea ejecutar dentro de un servicio en segundo plano y tomar los datos en primer plano, utilice el siguiente, se prueba y se verifica.

 public class MyService extends Service implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener { private static final int ASHIS = 1234; Intent intentForPendingIntent; HandlerThread handlerThread; Looper looper; GoogleApiClient mGoogleApiClient; private LocationRequest mLocationRrequest; private static final int UPDATE_INTERVAL = 1000; private static final int FASTEST_INTERVAL = 100; private static final int DSIPLACEMENT_UPDATES = 1; ; private Handler handler1; private Runnable runable1; private Location mLastLocation; private float waitingTime; private int waiting2min; private Location locationOld; private double distance; private float totalWaiting; private float speed; private long timeGpsUpdate; private long timeOld; private NotificationManager mNotificationManager; Notification notification; PendingIntent resultPendingIntent; NotificationCompat.Builder mBuilder; // Sets an ID for the notification int mNotificationId = 001; private static final String TAG = "BroadcastService"; public static final String BROADCAST_ACTION = "speedExceeded"; private final Handler handler = new Handler(); Intent intentforBroadcast; int counter = 0; private Runnable sendUpdatesToUI; @Nullable @Override public IBinder onBind(Intent intent) { Toast.makeText(MyService.this, "binder", Toast.LENGTH_SHORT).show(); return null; } @Override public void onCreate() { showNotification(); intentforBroadcast = new Intent(BROADCAST_ACTION); Toast.makeText(MyService.this, "created", Toast.LENGTH_SHORT).show(); if (mGoogleApiClient == null) { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } createLocationRequest(); mGoogleApiClient.connect(); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void showNotification() { mBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_media_play) .setContentTitle("Total Waiting Time") .setContentText(totalWaiting+""); Intent resultIntent = new Intent(this, trackingFusion.class); // Because clicking the notification opens a new ("special") activity, there's // no need to create an artificial back stack. PendingIntent resultPendingIntent = PendingIntent.getActivity( this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT ); mBuilder.setContentIntent(resultPendingIntent); NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); // Builds the notification and issues it. mNotifyMgr.notify(mNotificationId, mBuilder.build()); startForeground(001, mBuilder.getNotification()); } @Override public void onLocationChanged(Location location) { //handler.removeCallbacks(runable); Toast.makeText(MyService.this, "speed" + speed, Toast.LENGTH_SHORT).show(); timeGpsUpdate = location.getTime(); float delta = (timeGpsUpdate - timeOld) / 1000; if (location.getAccuracy() < 100) { speed = location.getSpeed(); distance += mLastLocation.distanceTo(location); Log.e("distance", "onLocationChanged: " + distance); //mLastLocation = location; //newLocation = mLastLocation; Log.e("location:", location + ""); //speed = (long) (distance / delta); locationOld = location; mLastLocation = location; diaplayViews(); } diaplayViews(); /*if (map != null) { map.addMarker(new MarkerOptions() .position(new LatLng(location.getLatitude(), location.getLongitude())) .title("Hello world")); }*/ } private void createLocationRequest() { mLocationRrequest = new LocationRequest(); mLocationRrequest.setInterval(UPDATE_INTERVAL); mLocationRrequest.setFastestInterval(FASTEST_INTERVAL); mLocationRrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRrequest.setSmallestDisplacement(DSIPLACEMENT_UPDATES); } private void methodToCalculateWaitingTime() { if (handler1 != null) { handler1.removeCallbacks(runable1); } Log.e("Here", "here1"); handler1 = new Handler(Looper.getMainLooper()); runable1 = new Runnable() { public void run() { Log.e("Here", "here2:" + mLastLocation.getSpeed()); if (mLastLocation != null) { diaplayViews(); if ((mLastLocation.getSpeed() == 0.0)) { increaseTime(); } else { if (waitingTime <= 120) { waiting2min = 0; } } handler1.postDelayed(this, 10000); } else { if (ActivityCompat.checkSelfPermission(MyService.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MyService.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } locationOld = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); mLastLocation = locationOld; } } }; handler1.postDelayed(runable1, 10000); } private void diaplayViews() { float price = (float) (14 + distance * 0.5); //textDistance.setText(waitingTime);a } private void increaseTime() { waiting2min = waiting2min + 10; if (waiting2min >= 120) { if (waiting2min == 120) { waitingTime = waitingTime + 2 * 60; } else { waitingTime = waitingTime + 10; } totalWaiting = waitingTime / 60; showNotification(); Log.e("waiting Time", "increaseTime: " + totalWaiting); } } @Override public void onDestroy() { Toast.makeText(MyService.this, "distroyed", Toast.LENGTH_SHORT).show(); if (mGoogleApiClient.isConnected()) { mGoogleApiClient.disconnect(); } mGoogleApiClient.disconnect(); } @Override public void onConnected(Bundle bundle) { Log.e("Connection_fusion", "connected"); startLocationUpdates(); } @Override public void onConnectionSuspended(int i) { } private void startLocationUpdates() { Location location = plotTheInitialMarkerAndGetInitialGps(); if (location == null) { plotTheInitialMarkerAndGetInitialGps(); } else { mLastLocation = location; methodToCalculateWaitingTime(); } } private Location plotTheInitialMarkerAndGetInitialGps() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return null; } LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRrequest, this); locationOld = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if ((locationOld != null)) { mLastLocation = locationOld; timeOld = locationOld.getTime(); } else { startLocationUpdates(); } return mLastLocation; } @Override public int onStartCommand(Intent intent, int flags, int startId) { onStart(intent, startId); Toast.makeText(MyService.this, "start command", Toast.LENGTH_SHORT).show(); sendUpdatesToUI = new Runnable() { public void run() { DisplayLoggingInfo(); handler.postDelayed(this, 10000); // 5 seconds } }; handler.postDelayed(sendUpdatesToUI, 10000); // 1 second Log.i("LocalService", "Received start id " + startId + ": " + intent); return START_NOT_STICKY; } @Override public void onStart(Intent intent, int startId) { sendUpdatesToUI = new Runnable() { public void run() { Log.e("sent", "sent"); DisplayLoggingInfo(); handler.postDelayed(this, 5000); // 5 seconds } }; handler.postDelayed(sendUpdatesToUI, 1000); // 1 second Log.i("LocalService", "Received start id " + startId + ": " + intent); super.onStart(intent, startId); } private void DisplayLoggingInfo() { Log.d(TAG, "entered DisplayLoggingInfo"); intentforBroadcast.putExtra("distance", distance); LocalBroadcastManager.getInstance(this).sendBroadcast(intentforBroadcast); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { } @Override public void onMapReady(GoogleMap googleMap) { } } 

Hice algunos cambios en el código anterior para buscar una ubicación corregida tanto por GPS como por Red durante aproximadamente 5 segundos y darme la mejor ubicación conocida.

 public class LocationService implements LocationListener { boolean isGPSEnabled = false; boolean isNetworkEnabled = false; boolean canGetLocation = false; final static long MIN_TIME_INTERVAL = 60 * 1000L; Location location; // The minimum distance to change Updates in meters private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 10 // The minimum time between updates in milliseconds private static final long MIN_TIME_BW_UPDATES = 1; // 1 minute protected LocationManager locationManager; private CountDownTimer timer = new CountDownTimer(5 * 1000, 1000) { public void onTick(long millisUntilFinished) { } public void onFinish() { stopUsingGPS(); } }; public LocationService() { super(R.id.gps_service_id); } public void start() { if (Utils.isNetworkAvailable(context)) { try { timer.start(); locationManager = (LocationManager) context .getSystemService(Context.LOCATION_SERVICE); isGPSEnabled = locationManager .isProviderEnabled(LocationManager.GPS_PROVIDER); isNetworkEnabled = locationManager .isProviderEnabled(LocationManager.NETWORK_PROVIDER); this.canGetLocation = true; if (isNetworkEnabled) { locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("Network", "Network"); if (locationManager != null) { Location tempLocation = locationManager .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (tempLocation != null && isBetterLocation(tempLocation, location)) location = tempLocation; } } if (isGPSEnabled) { locationManager.requestSingleUpdate( LocationManager.GPS_PROVIDER, this, null); locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("GPS Enabled", "GPS Enabled"); if (locationManager != null) { Location tempLocation = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER); if (tempLocation != null && isBetterLocation(tempLocation, location)) location = tempLocation; } } } catch (Exception e) { onTaskError(e.getMessage()); e.printStackTrace(); } } else { onOfflineResponse(requestData); } } public void stopUsingGPS() { if (locationManager != null) { locationManager.removeUpdates(LocationService.this); } } public boolean canGetLocation() { locationManager = (LocationManager) context .getSystemService(Context.LOCATION_SERVICE); isGPSEnabled = locationManager .isProviderEnabled(LocationManager.GPS_PROVIDER); // getting network status isNetworkEnabled = locationManager .isProviderEnabled(LocationManager.NETWORK_PROVIDER); return isGPSEnabled || isNetworkEnabled; } @Override public void onLocationChanged(Location location) { if (location != null && isBetterLocation(location, this.location)) { this.location = location; } } @Override public void onProviderDisabled(String provider) { } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public Object getResponseObject(Object location) { return location; } public static boolean isBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return true; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > MIN_TIME_INTERVAL; boolean isSignificantlyOlder = timeDelta < -MIN_TIME_INTERVAL; boolean isNewer = timeDelta > 0; // If it's been more than two minutes since the current location, // use the new location // because the user has likely moved if (isSignificantlyNewer) { return true; // If the new location is more than two minutes older, it must // be worse } else if (isSignificantlyOlder) { return false; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation .getAccuracy()); boolean isLessAccurate = accuracyDelta > 0; boolean isMoreAccurate = accuracyDelta < 0; boolean isSignificantlyLessAccurate = accuracyDelta > 200; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and // accuracy if (isMoreAccurate) { return true; } else if (isNewer && !isLessAccurate) { return true; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { return true; } return false; } } 

En la clase anterior, estoy registrando un oyente de ubicación tanto para el GPS como para la red, por lo que una o varias veces puede llamar a una llamada de retorno onLocationChanged y simplemente comparamos el nuevo arreglo de ubicación con el que ya tenemos y guardamos el el mejor.

Clase principal:

 public class AndroidLocationActivity extends Activity { Button btnGPSShowLocation; Button btnNWShowLocation; AppLocationService appLocationService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); appLocationService = new AppLocationService( AndroidLocationActivity.this); btnGPSShowLocation = (Button) findViewById(R.id.btnGPSShowLocation); btnGPSShowLocation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Location gpsLocation = appLocationService .getLocation(LocationManager.GPS_PROVIDER); if (gpsLocation != null) { double latitude = gpsLocation.getLatitude(); double longitude = gpsLocation.getLongitude(); Toast.makeText( getApplicationContext(), "Mobile Location (GPS): \nLatitude: " + latitude + "\nLongitude: " + longitude, Toast.LENGTH_LONG).show(); } else { showSettingsAlert("GPS"); } } }); btnNWShowLocation = (Button) findViewById(R.id.btnNWShowLocation); btnNWShowLocation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Location nwLocation = appLocationService .getLocation(LocationManager.NETWORK_PROVIDER); if (nwLocation != null) { double latitude = nwLocation.getLatitude(); double longitude = nwLocation.getLongitude(); Toast.makeText( getApplicationContext(), "Mobile Location (NW): \nLatitude: " + latitude + "\nLongitude: " + longitude, Toast.LENGTH_LONG).show(); } else { showSettingsAlert("NETWORK"); } } }); } public void showSettingsAlert(String provider) { AlertDialog.Builder alertDialog = new AlertDialog.Builder( AndroidLocationActivity.this); alertDialog.setTitle(provider + " SETTINGS"); alertDialog.setMessage(provider + " is not enabled! Want to go to settings menu?"); alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Intent intent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS); AndroidLocationActivity.this.startActivity(intent); } }); alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); alertDialog.show(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } } 

Siguiente clase:

 public class AppLocationService extends Service implements LocationListener { protected LocationManager locationManager; Location location; private static final long MIN_DISTANCE_FOR_UPDATE = 10; private static final long MIN_TIME_FOR_UPDATE = 1000 * 60 * 2; public AppLocationService(Context context) { locationManager = (LocationManager) context .getSystemService(LOCATION_SERVICE); } public Location getLocation(String provider) { if (locationManager.isProviderEnabled(provider)) { locationManager.requestLocationUpdates(provider, MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, this); if (locationManager != null) { location = locationManager.getLastKnownLocation(provider); return location; } } return null; } @Override public void onLocationChanged(Location location) { } @Override public void onProviderDisabled(String provider) { } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public IBinder onBind(Intent arg0) { return null; } } 

No olvides agregar tu manifiesto.

     

hay mejores formas de hacerlo, como se menciona en los sitios de desarrolladores de Android http://developer.android.com/guide/topics/location/strategies.html