ubicacion studio posicionamiento obtener mapas geolocalizacion direccion crear android gps location-provider fusedlocationproviderapi

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 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.


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) { } } }