studio - La mejor manera de obtener la ubicación GPS del usuario en segundo plano en Android
obtener ubicacion gps android studio (13)
- Versión Kotlin
package com.ps.salestrackingapp.Services
import android.app.Service
import android.content.Context
import android.content.Intent
import android.location.Location
import android.location.LocationManager
import android.os.Bundle
import android.os.IBinder
import android.util.Log
class LocationService : Service() {
private var mLocationManager: LocationManager? = null
var mLocationListeners = arrayOf(LocationListener(LocationManager.GPS_PROVIDER), LocationListener(LocationManager.NETWORK_PROVIDER))
class LocationListener(provider: String) : android.location.LocationListener {
internal var mLastLocation: Location
init {
Log.e(TAG, "LocationListener $provider")
mLastLocation = Location(provider)
}
override fun onLocationChanged(location: Location) {
Log.e(TAG, "onLocationChanged: $location")
mLastLocation.set(location)
Log.v("LastLocation", mLastLocation.latitude.toString() +" " + mLastLocation.longitude.toString())
}
override fun onProviderDisabled(provider: String) {
Log.e(TAG, "onProviderDisabled: $provider")
}
override fun onProviderEnabled(provider: String) {
Log.e(TAG, "onProviderEnabled: $provider")
}
override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {
Log.e(TAG, "onStatusChanged: $provider")
}
}
override fun onBind(arg0: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.e(TAG, "onStartCommand")
super.onStartCommand(intent, flags, startId)
return Service.START_STICKY
}
override fun onCreate() {
Log.e(TAG, "onCreate")
initializeLocationManager()
try {
mLocationManager!!.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL.toLong(), LOCATION_DISTANCE,
mLocationListeners[1])
} catch (ex: java.lang.SecurityException) {
Log.i(TAG, "fail to request location update, ignore", ex)
} catch (ex: IllegalArgumentException) {
Log.d(TAG, "network provider does not exist, " + ex.message)
}
try {
mLocationManager!!.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL.toLong(), LOCATION_DISTANCE,
mLocationListeners[0])
} catch (ex: java.lang.SecurityException) {
Log.i(TAG, "fail to request location update, ignore", ex)
} catch (ex: IllegalArgumentException) {
Log.d(TAG, "gps provider does not exist " + ex.message)
}
}
override fun onDestroy() {
Log.e(TAG, "onDestroy")
super.onDestroy()
if (mLocationManager != null) {
for (i in mLocationListeners.indices) {
try {
mLocationManager!!.removeUpdates(mLocationListeners[i])
} catch (ex: Exception) {
Log.i(TAG, "fail to remove location listners, ignore", ex)
}
}
}
}
private fun initializeLocationManager() {
Log.e(TAG, "initializeLocationManager")
if (mLocationManager == null) {
mLocationManager = applicationContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
}
}
companion object {
private val TAG = "BOOMBOOMTESTGPS"
private val LOCATION_INTERVAL = 1000
private val LOCATION_DISTANCE = 0f
}
}
Esta pregunta ya tiene una respuesta aquí:
En mi aplicación de Android, quiero obtener la ubicación actual del usuario cada pocos minutos y actualizar mi servidor central utilizando el servicio web. Actualmente estoy usando Proporcionar ubicación fusionada para obtener la ubicación actual del usuario, ver link
ahora quiero saber cuál es la mejor manera de obtener la ubicación del usuario con frecuencia y llamar al servicio web.
a continuación está mi código que me da la ubicación actual del usuario: -
locationrequest = LocationRequest.create();
locationrequest.setInterval(10000);
locationclient.requestLocationUpdates(locationrequest,new com.google.android.gms.location.LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.i(TAG, "Last Known Location :" + location.getLatitude() + "," + location.getLongitude());
}
});
ahora desde donde tengo que llamar a este código. ¿Puedo usar esto en un servicio en segundo plano o en otro lugar?
Por favor proporcione su idea.
TIA
Bueno, cree un servicio de extensión de clase, este servicio contendrá su clase de escucha de ubicación (proveedor de ubicación fusionada) El propósito de este servicio es obtener la ubicación periódicamente, algo como esto
public class LocationGetter extends Service {
......
public class MyLocationListener implements GooglePlayServicesClient.ConnectionCallbacks,GooglePlayServicesClient.OnConnectionFailedListener,LocationListener, com.google.android.gms.location.LocationListener {
//your fused Location provider code
}
......
}
Luego, cree una clase que extienda el Broadcast Receiver, de modo que el propósito de este Broadcast Receiver sea verificar si el servicio está activo si no reinicia el servicio incluso durante el encendido / apagado del teléfono ...
registre el receptor en su actividad, escuche las transmisiones, anule el registro del receptor dependiendo de su necesidad ...
Con la ayuda de la API LocationServices de GoogleApiClient, podemos obtener la ubicación actual del usuario / dispositivo en un intervalo de tiempo específico. Esto se puede agregar a un servicio en segundo plano que actualiza la actividad cuando las devoluciones de llamada onLocationChanged
El servicio en segundo plano seguirá ejecutándose mientras la aplicación exista en la memoria y se adhiera al cajón de notificaciones. El servicio maneja las siguientes funcionalidades,
- Conexión a la API de Google Location Services
- Obtener la ubicación actual
- Compartir el resultado a la actividad
Servicio con oyente de ubicación
public class LocationMonitoringService extends Service implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
LocationListener {
...
...
...
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mLocationClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest.setInterval(10000); //10 secs
mLocationRequest.setFastestInterval(5000); //5 secs
int priority = LocationRequest.PRIORITY_HIGH_ACCURACY; //by default
//PRIORITY_BALANCED_POWER_ACCURACY, PRIORITY_LOW_POWER, PRIORITY_NO_POWER are the other priority modes
mLocationRequest.setPriority(priority);
mLocationClient.connect();
//Make it stick to the notification panel so it is less prone to get cancelled by the Operating System.
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/*
* LOCATION CALLBACKS
*/
@Override
public void onConnected(Bundle dataBundle) {
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.
Log.d(TAG, "== Error On onConnected() Permission not granted");
//Permission not granted by user so cancel the further execution.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, mLocationRequest, this);
Log.d(TAG, "Connected to Google API");
}
/*
* Called by Location Services if the connection to the
* location client drops because of an error.
*/
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "Connection suspended");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Failed to connect to Google API");
}
//to get the location change
@Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Location changed");
if (location != null) {
//Do something with the location details,
if (location != null) {
//call your API
callAPI(String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));
}
}
}
}
Vea el tutorial completo con el código fuente y la explicación en detalle >>
Para realizar un seguimiento de la ubicación cada 10 minutos (según los requisitos), siga este enlace, funciona bien sin ningún problema
https://github.com/safetysystemtechnology/location-tracker-background
Para recibir devolución de llamada en LocationChange
Definir una interfaz
public interface LocationCallback {
public void locationChanged(Location location);
}
Devolución de llamada en su actividad
public static LocationCallback callback;
public void getUserLocation() {
callback = new LocationCallback() {
@Override
public void locationChanged(Location location) {
Toast.makeText(getApplicationContext(), location.getLatitude() + "," + location.getLongitude(), Toast.LENGTH_SHORT).show();
}
};
Intent service_intent = new Intent(this, GPSService.class);
startService(service_intent);
}
Cambie el Método onLocationChange a
@Override
public void onLocationChanged(Location location) {
Log.e(TAG, "onLocationChanged: " + location);
MapsActivity.callback.locationChanged(location);
mLastLocation.set(location);
}
Puede archivarlo con un Administrador de servicios y alarmas, pero tenga cuidado con esto, porque si configura una alta prioridad, va a agotar la batería del teléfono, por otro lado, ¿realmente necesita notificar la ubicación cada minuto? Esto se debe a que la única forma de ver un cambio considerable en la ubicación del usuario es viajando en automóvil o en tren. Solo pregunto, porque eso dependerá de tu aplicación y del requisito del seguimiento.
Descargue el código fuente desde aquí ( Obtener la ubicación actual usando el servicio en segundo plano )
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="servicetutorial.service">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<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"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".GoogleService"></service>
</application>
</manifest>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#ffffff"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#3F51B5"
android:text="Location using service"
android:textColor="#ffffff"
android:textSize="20dp"
android:gravity="center"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="50dp">
<TextView
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="Latitude"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="@+id/tv_latitude"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="50dp">
<TextView
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="Longitude"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="@+id/tv_longitude"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="50dp">
<TextView
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="Address"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="@+id/tv_address"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="50dp">
<TextView
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="Area"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="@+id/tv_area"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="50dp">
<TextView
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="Locality"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="@+id/tv_locality"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:textSize="20dp"/>
</LinearLayout>
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn_start"
android:text="Get Location"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
MainActivity.java
package servicetutorial.service;
import android.*;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.preference.PreferenceManager;
import android.renderscript.Double2;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class MainActivity extends Activity {
Button btn_start;
private static final int REQUEST_PERMISSIONS = 100;
boolean boolean_permission;
TextView tv_latitude, tv_longitude, tv_address,tv_area,tv_locality;
SharedPreferences mPref;
SharedPreferences.Editor medit;
Double latitude,longitude;
Geocoder geocoder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_start = (Button) findViewById(R.id.btn_start);
tv_address = (TextView) findViewById(R.id.tv_address);
tv_latitude = (TextView) findViewById(R.id.tv_latitude);
tv_longitude = (TextView) findViewById(R.id.tv_longitude);
tv_area = (TextView)findViewById(R.id.tv_area);
tv_locality = (TextView)findViewById(R.id.tv_locality);
geocoder = new Geocoder(this, Locale.getDefault());
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
medit = mPref.edit();
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (boolean_permission) {
if (mPref.getString("service", "").matches("")) {
medit.putString("service", "service").commit();
Intent intent = new Intent(getApplicationContext(), GoogleService.class);
startService(intent);
} else {
Toast.makeText(getApplicationContext(), "Service is already running", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(), "Please enable the gps", Toast.LENGTH_SHORT).show();
}
}
});
fn_permission();
}
private void fn_permission() {
if ((ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION))) {
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION
},
REQUEST_PERMISSIONS);
}
} else {
boolean_permission = true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_PERMISSIONS: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
boolean_permission = true;
} else {
Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();
}
}
}
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
latitude = Double.valueOf(intent.getStringExtra("latutide"));
longitude = Double.valueOf(intent.getStringExtra("longitude"));
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1);
String cityName = addresses.get(0).getAddressLine(0);
String stateName = addresses.get(0).getAddressLine(1);
String countryName = addresses.get(0).getAddressLine(2);
tv_area.setText(addresses.get(0).getAdminArea());
tv_locality.setText(stateName);
tv_address.setText(countryName);
} catch (IOException e1) {
e1.printStackTrace();
}
tv_latitude.setText(latitude+"");
tv_longitude.setText(longitude+"");
tv_address.getText();
}
};
@Override
protected void onResume() {
super.onResume();
registerReceiver(broadcastReceiver, new IntentFilter(GoogleService.str_receiver));
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
}
GoogleService.java
package servicetutorial.service;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by deepshikha on 24/11/16.
*/
public class GoogleService extends Service implements LocationListener{
boolean isGPSEnable = false;
boolean isNetworkEnable = false;
double latitude,longitude;
LocationManager locationManager;
Location location;
private Handler mHandler = new Handler();
private Timer mTimer = null;
long notify_interval = 1000;
public static String str_receiver = "servicetutorial.service.receiver";
Intent intent;
public GoogleService() {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mTimer = new Timer();
mTimer.schedule(new TimerTaskToGetLocation(),5,notify_interval);
intent = new Intent(str_receiver);
// fn_getlocation();
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
private void fn_getlocation(){
locationManager = (LocationManager)getApplicationContext().getSystemService(LOCATION_SERVICE);
isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnable && !isNetworkEnable){
}else {
if (isNetworkEnable){
location = null;
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000,0,this);
if (locationManager!=null){
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location!=null){
Log.e("latitude",location.getLatitude()+"");
Log.e("longitude",location.getLongitude()+"");
latitude = location.getLatitude();
longitude = location.getLongitude();
fn_update(location);
}
}
}
if (isGPSEnable){
location = null;
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,0,this);
if (locationManager!=null){
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location!=null){
Log.e("latitude",location.getLatitude()+"");
Log.e("longitude",location.getLongitude()+"");
latitude = location.getLatitude();
longitude = location.getLongitude();
fn_update(location);
}
}
}
}
}
private class TimerTaskToGetLocation extends TimerTask{
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
fn_getlocation();
}
});
}
}
private void fn_update(Location location){
intent.putExtra("latutide",location.getLatitude()+"");
intent.putExtra("longitude",location.getLongitude()+"");
sendBroadcast(intent);
}
}
Agregar esta dependencia
compile ''com.google.android.gms:play-services:9.4.0''
He intentado con mi código y he tenido éxito, prueba esto
package com.mobeyosoft.latitudelongitude;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
/**
* Created by 5943 6417 on 14-09-2016.
*/
public class LocationService extends Service
{
public static final String BROADCAST_ACTION = "Hello World";
private static final int TWO_MINUTES = 1000 * 60 * 1;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
Context context;
Intent intent;
int counter = 0;
@Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
context=this;
}
@Override
public void onStart(Intent intent, int startId) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
}
@Override
public IBinder onBind(Intent intent){
return null;
}
protected 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 > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
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;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
@Override
public void onDestroy() {
// handler.removeCallbacks(sendUpdatesToUI);
super.onDestroy();
Log.v("STOP_SERVICE", "DONE");
locationManager.removeUpdates(listener);
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
@Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
public class MyLocationListener implements LocationListener{
public void onLocationChanged(final Location loc)
{
Log.i("**********", "Location changed");
if(isBetterLocation(loc, previousBestLocation)) {
loc.getLatitude();
loc.getLongitude();
Toast.makeText(context, "Latitude" + loc.getLatitude() + "/nLongitude"+loc.getLongitude(),Toast.LENGTH_SHORT).show();
intent.putExtra("Latitude", loc.getLatitude());
intent.putExtra("Longitude", loc.getLongitude());
intent.putExtra("Provider", loc.getProvider());
sendBroadcast(intent);
}
}
public void onProviderDisabled(String provider)
{
Toast.makeText( getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show();
}
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
}
Ninguna de las respuestas restantes usan:
com.google.android.gms.location.FusedLocationProviderClient
Cuál es el proveedor de ubicación fusionada y el punto de entrada principal para interactuar con el proveedor de ubicación fusionada de Google, y es muy difícil encontrar un buen ejemplo. Esto fue lanzado a mediados de 2017 por Google.
Las API de ubicación de los servicios de Google Play son preferibles a las API de ubicación del marco Android (android.location)
Si actualmente está utilizando las API de ubicación del marco de Android, le recomendamos encarecidamente que cambie a las API de ubicación de los servicios de Google Play lo antes posible.
Para que pueda usar la API de ubicación de Google, primero agregue esto a su
build.gradle
compile ''com.google.android.gms:play-services:11.0.0''
Entonces puedes usar esta clase
Wherebouts.java
:
import android.location.Location;
import android.os.Looper;
import android.util.Log;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
/**
* Uses Google Play API for obtaining device locations
* Created by alejandro.tkachuk
* [email protected]
* www.calculistik.com Mobile Development
*/
public class Wherebouts {
private static final Wherebouts instance = new Wherebouts();
private static final String TAG = Wherebouts.class.getSimpleName();
private FusedLocationProviderClient mFusedLocationClient;
private LocationCallback locationCallback;
private LocationRequest locationRequest;
private LocationSettingsRequest locationSettingsRequest;
private Workable<GPSPoint> workable;
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
private Wherebouts() {
this.locationRequest = new LocationRequest();
this.locationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
this.locationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
this.locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(this.locationRequest);
this.locationSettingsRequest = builder.build();
this.locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult); // why? this. is. retarded. Android.
Location currentLocation = locationResult.getLastLocation();
GPSPoint gpsPoint = new GPSPoint(currentLocation.getLatitude(), currentLocation.getLongitude());
Log.i(TAG, "Location Callback results: " + gpsPoint);
if (null != workable)
workable.work(gpsPoint);
}
};
this.mFusedLocationClient = LocationServices.getFusedLocationProviderClient(MainApplication.getAppContext());
this.mFusedLocationClient.requestLocationUpdates(this.locationRequest,
this.locationCallback, Looper.myLooper());
}
public static Wherebouts instance() {
return instance;
}
public void onChange(Workable<GPSPoint> workable) {
this.workable = workable;
}
public LocationSettingsRequest getLocationSettingsRequest() {
return this.locationSettingsRequest;
}
public void stop() {
Log.i(TAG, "stop() Stopping location tracking");
this.mFusedLocationClient.removeLocationUpdates(this.locationCallback);
}
}
Desde su Actividad, puede usarlo así, pasando un objeto
Workable
.
Un objeto viable no es más que un objeto personalizado de devolución de llamada.
Wherebouts.instance().onChange(workable);
Al usar una devolución de llamada como Workable, escribirás un código relacionado con la interfaz de usuario en tu Actividad y dejarás el trabajo de trabajar con GPS en una clase auxiliar, como Wherebouts.
new Workable<GPSPoint>() {
@Override
public void work(GPSPoint gpsPoint) {
// draw something in the UI with this new data
}
};
Por supuesto, deberá solicitar los permisos correspondientes al sistema operativo Android para que su aplicación lo use. Puede leer la siguiente documentación para obtener más información al respecto o investigar un poco.
- Referencia de Android https://developer.android.com/training/location/index.html
- Dónde http://calculistik.com/Wherebouts.java
- GPSPoint http://calculistik.com/GPSPoint.java
- Funcionable http://calculistik.com/Workable.java
Otorgue el permiso requerido ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION después de iniciar el servicio
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.location.LocationListener;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnCanceledListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import java.util.concurrent.TimeUnit;
/**
* Created by Ketan Ramani on 05/11/18.
*/
public class BackgroundLocationUpdateService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
/* Declare in manifest
<service android:name=".BackgroundLocationUpdateService"/>
*/
private final String TAG = "BackgroundLocationUpdateService";
private final String TAG_LOCATION = "TAG_LOCATION";
private Context context;
private boolean stopService = false;
/* For Google Fused API */
protected GoogleApiClient mGoogleApiClient;
protected LocationSettingsRequest mLocationSettingsRequest;
private String latitude = "0.0", longitude = "0.0";
private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingsClient;
private LocationCallback mLocationCallback;
private LocationRequest mLocationRequest;
private Location mCurrentLocation;
/* For Google Fused API */
@Override
public void onCreate() {
super.onCreate();
context = this;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
StartForeground();
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
@Override
public void run() {
try {
if (!stopService) {
//Perform your task here
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (!stopService) {
handler.postDelayed(this, TimeUnit.SECONDS.toMillis(10));
}
}
}
};
handler.postDelayed(runnable, 2000);
buildGoogleApiClient();
return START_STICKY;
}
@Override
public void onDestroy() {
Log.e(TAG, "Service Stopped");
stopService = true;
if (mFusedLocationClient != null) {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
Log.e(TAG_LOCATION, "Location Update Callback Removed");
}
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void StartForeground() {
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
String CHANNEL_ID = "channel_location";
String CHANNEL_NAME = "channel_location";
NotificationCompat.Builder builder = null;
NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationManager.createNotificationChannel(channel);
builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
builder.setChannelId(CHANNEL_ID);
builder.setBadgeIconType(NotificationCompat.BADGE_ICON_NONE);
} else {
builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
}
builder.setContentTitle("Your title");
builder.setContentText("You are now online");
Uri notificationSound = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(notificationSound);
builder.setAutoCancel(true);
builder.setSmallIcon(R.drawable.ic_logo);
builder.setContentIntent(pendingIntent);
Notification notification = builder.build();
startForeground(101, notification);
}
@Override
public void onLocationChanged(Location location) {
Log.e(TAG_LOCATION, "Location Changed Latitude : " + location.getLatitude() + "/tLongitude : " + location.getLongitude());
latitude = String.valueOf(location.getLatitude());
longitude = String.valueOf(location.getLongitude());
if (latitude.equalsIgnoreCase("0.0") && longitude.equalsIgnoreCase("0.0")) {
requestLocationUpdate();
} else {
Log.e(TAG_LOCATION, "Latitude : " + location.getLatitude() + "/tLongitude : " + location.getLongitude());
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onConnected(@Nullable Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10 * 1000);
mLocationRequest.setFastestInterval(5 * 1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
mLocationSettingsRequest = builder.build();
mSettingsClient
.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.e(TAG_LOCATION, "GPS Success");
requestLocationUpdate();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
int REQUEST_CHECK_SETTINGS = 214;
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult((AppCompatActivity) context, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sie) {
Log.e(TAG_LOCATION, "Unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.e(TAG_LOCATION, "Location settings are inadequate, and cannot be fixed here. Fix in Settings.");
}
}
}).addOnCanceledListener(new OnCanceledListener() {
@Override
public void onCanceled() {
Log.e(TAG_LOCATION, "checkLocationSettings -> onCanceled");
}
});
}
@Override
public void onConnectionSuspended(int i) {
connectGoogleClient();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
mSettingsClient = LocationServices.getSettingsClient(context);
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
connectGoogleClient();
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
Log.e(TAG_LOCATION, "Location Received");
mCurrentLocation = locationResult.getLastLocation();
onLocationChanged(mCurrentLocation);
}
};
}
private void connectGoogleClient() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int resultCode = googleAPI.isGooglePlayServicesAvailable(context);
if (resultCode == ConnectionResult.SUCCESS) {
mGoogleApiClient.connect();
}
}
@SuppressLint("MissingPermission")
private void requestLocationUpdate() {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
}
En actividad
Comienza el servicio :
startService(new Intent(this, BackgroundLocationUpdateService.class));
Parada de servicio :
stopService(new Intent(this, BackgroundLocationUpdateService.class));
En fragmento
Comienza el servicio :
getActivity().startService(new Intent(getActivity().getBaseContext(), BackgroundLocationUpdateService.class));
Parada de servicio :
getActivity().stopService(new Intent(getActivity(), BackgroundLocationUpdateService.class));
Tienes que crear el servicio. Ese servicio debe implementar LocationListener. Luego, debe usar AlarmManager para llamar al servicio repetidamente con cierto límite de tiempo.
Espero que este te ayude :)
Uso: GCM Network Manager
Ejecute esto para iniciar una tarea periódica que se ejecutará incluso después de reiniciar:
PeriodicTask task = new PeriodicTask.Builder()
.setService(MyLocationService.class)
.setTag("periodic")
.setPeriod(30L)
.setPersisted(true)
.build();
mGcmNetworkManager.schedule(task);
luego, en onRunTask () obtenga la ubicación actual y úsela (en este ejemplo, el evento se envía al final para que la IU sepa que se encontró la ubicación)
public void getLastKnownLocation() {
Location lastKnownGPSLocation;
Location lastKnownNetworkLocation;
String gpsLocationProvider = LocationManager.GPS_PROVIDER;
String networkLocationProvider = LocationManager.NETWORK_PROVIDER;
try {
locationManager = (LocationManager) App.get().getSystemService(Context.LOCATION_SERVICE);
lastKnownNetworkLocation = locationManager.getLastKnownLocation(networkLocationProvider);
lastKnownGPSLocation = locationManager.getLastKnownLocation(gpsLocationProvider);
if (lastKnownGPSLocation != null) {
Log.i(TAG, "lastKnownGPSLocation is used.");
this.mCurrentLocation = lastKnownGPSLocation;
} else if (lastKnownNetworkLocation != null) {
Log.i(TAG, "lastKnownNetworkLocation is used.");
this.mCurrentLocation = lastKnownNetworkLocation;
} else {
Log.e(TAG, "lastLocation is not known.");
return;
}
LocationChangedEvent event = new LocationChangedEvent();
event.setLocation(mCurrentLocation);
EventHelper.publishEvent(event);
} catch (SecurityException sex) {
Log.e(TAG, "Location permission is not granted!");
}
return;
}
MyLocationService en su conjunto:
public class MyLocationService extends GcmTaskService {
private static final String TAG = MyLocationService.class.getSimpleName();
private LocationManager locationManager;
private Location mCurrentLocation;
public static final String TASK_GET_LOCATION_ONCE="location_oneoff_task";
public static final String TASK_GET_LOCATION_PERIODIC="location_periodic_task";
private static final int RC_PLAY_SERVICES = 123;
@Override
public void onInitializeTasks() {
// When your package is removed or updated, all of its network tasks are cleared by
// the GcmNetworkManager. You can override this method to reschedule them in the case of
// an updated package. This is not called when your application is first installed.
//
// This is called on your application''s main thread.
startPeriodicLocationTask(TASK_GET_LOCATION_PERIODIC,
30L, null);
}
@Override
public int onRunTask(TaskParams taskParams) {
Log.d(TAG, "onRunTask: " + taskParams.getTag());
String tag = taskParams.getTag();
Bundle extras = taskParams.getExtras();
// Default result is success.
int result = GcmNetworkManager.RESULT_SUCCESS;
switch (tag) {
case TASK_GET_LOCATION_ONCE:
getLastKnownLocation();
break;
case TASK_GET_LOCATION_PERIODIC:
getLastKnownLocation();
break;
}
return result;
}
public void getLastKnownLocation() {
Location lastKnownGPSLocation;
Location lastKnownNetworkLocation;
String gpsLocationProvider = LocationManager.GPS_PROVIDER;
String networkLocationProvider = LocationManager.NETWORK_PROVIDER;
try {
locationManager = (LocationManager) App.get().getSystemService(Context.LOCATION_SERVICE);
lastKnownNetworkLocation = locationManager.getLastKnownLocation(networkLocationProvider);
lastKnownGPSLocation = locationManager.getLastKnownLocation(gpsLocationProvider);
if (lastKnownGPSLocation != null) {
Log.i(TAG, "lastKnownGPSLocation is used.");
this.mCurrentLocation = lastKnownGPSLocation;
} else if (lastKnownNetworkLocation != null) {
Log.i(TAG, "lastKnownNetworkLocation is used.");
this.mCurrentLocation = lastKnownNetworkLocation;
} else {
Log.e(TAG, "lastLocation is not known.");
return;
}
LocationChangedEvent event = new LocationChangedEvent();
event.setLocation(mCurrentLocation);
EventHelper.publishEvent(event);
} catch (SecurityException sex) {
Log.e(TAG, "Location permission is not granted!");
}
return;
}
public static void startOneOffLocationTask(String tag, Bundle extras) {
Log.d(TAG, "startOneOffLocationTask");
GcmNetworkManager mGcmNetworkManager = GcmNetworkManager.getInstance(App.get());
OneoffTask.Builder taskBuilder = new OneoffTask.Builder()
.setService(MyLocationService.class)
.setTag(tag);
if (extras != null) taskBuilder.setExtras(extras);
OneoffTask task = taskBuilder.build();
mGcmNetworkManager.schedule(task);
}
public static void startPeriodicLocationTask(String tag, Long period, Bundle extras) {
Log.d(TAG, "startPeriodicLocationTask");
GcmNetworkManager mGcmNetworkManager = GcmNetworkManager.getInstance(App.get());
PeriodicTask.Builder taskBuilder = new PeriodicTask.Builder()
.setService(MyLocationService.class)
.setTag(tag)
.setPeriod(period)
.setPersisted(true)
.setRequiredNetwork(Task.NETWORK_STATE_CONNECTED);
if (extras != null) taskBuilder.setExtras(extras);
PeriodicTask task = taskBuilder.build();
mGcmNetworkManager.schedule(task);
}
public static boolean checkPlayServicesAvailable(Activity activity) {
GoogleApiAvailability availability = GoogleApiAvailability.getInstance();
int resultCode = availability.isGooglePlayServicesAvailable(App.get());
if (resultCode != ConnectionResult.SUCCESS) {
if (availability.isUserResolvableError(resultCode)) {
// Show dialog to resolve the error.
availability.getErrorDialog(activity, resultCode, RC_PLAY_SERVICES).show();
}
return false;
} else {
return true;
}
}
Agregue también estos 2 al AndroidManifest.xml:
<manifest...
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application...
<service
android:name=".api.location.MyLocationService"
android:exported="true"
android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">
<intent-filter>
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" />
</intent-filter>
</service>
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.GeomagneticField;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.widget.Toast;
public class LocationService extends Service {
private static final int MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
Context mContext;
private boolean isGpsEnabled = false;
private boolean isNetworkEnabled = false;
private GeomagneticField geoField;
private double latitude = 0.0;
private double longitude = 0.0;
@Override
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
if (locationManager == null) {
locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
}
getCurrentLocation();
}
private void getCurrentLocation() {
try {
assert locationManager != null;
isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
ex.printStackTrace();
}
if (!isGpsEnabled && !isNetworkEnabled) {
showSettingsAlert();
}
listener = new MyLocationListener();
try {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, listener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, listener);
} catch (SecurityException e) {
e.printStackTrace();
}
}
private void showSettingsAlert() {
Toast.makeText(mContext, "GPS is disabled in your device. Please Enable it ?", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
return true;
}
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > MINUTES;
boolean isSignificantlyOlder = timeDelta < -MINUTES;
boolean isNewer = timeDelta > 0;
if (isSignificantlyNewer) {
return true;
} else if (isSignificantlyOlder) {
return false;
}
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider());
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
@Override
public void onDestroy() {
super.onDestroy();
locationManager.removeUpdates(listener);
}
private void setupFinalLocationData(Location mLocation) {
if (mLocation != null) {
geoField = new GeomagneticField(
Double.valueOf(mLocation.getLatitude()).floatValue(),
Double.valueOf(mLocation.getLongitude()).floatValue(),
Double.valueOf(mLocation.getAltitude()).floatValue(),
System.currentTimeMillis()
);
latitude = mLocation.getLatitude();
longitude = mLocation.getLongitude();
//Update latitude and longtitude in SharedPreference...
}
}
public class MyLocationListener implements LocationListener {
public void onLocationChanged(final Location loc) {
if (isBetterLocation(loc, previousBestLocation)) {
setupFinalLocationData(loc);
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}