studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android geolocation locationmanager

para - manual de programacion android pdf



La devolución de llamada OnLocationChanged nunca se llama (11)

Estoy tratando de obtener la ubicación actual de los usuarios utilizando el LocationManager . He investigado mucho y parece que no puedo encontrar a nadie con el mismo problema. La devolución de llamada OnLocationChanged nunca parece ser llamada. A continuación se muestra mi código y el logcat.

protected LocationListener locationListener; protected LocationManager locationManager; protected Context context;

Mi método OnCreate()

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.v(TAG, "IN ON CREATE"); this.context = getActivity(); registerLocationUpdates(); }

Mi método registerLocationUpdates

void registerLocationUpdates() { Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_LOW); criteria.setPowerRequirement(Criteria.POWER_LOW); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); locationManager = (LocationManager)getActivity().getSystemService(LOCATION_SERVICE); provider = locationManager.getBestProvider(criteria, true); // Cant get a hold of provider if (provider == null) { Log.v(TAG, "Provider is null"); showNoProvider(); return; } else { Log.v(TAG, "Provider: " + provider); } locationListener = new MyLocationListener(); locationManager.requestLocationUpdates(provider, 1L, 1f, locationListener); // connect to the GPS location service Location oldLocation = locationManager.getLastKnownLocation(provider); if (oldLocation != null) { Log.v(TAG, "Got Old location"); latitude = Double.toString(oldLocation.getLatitude()); longitude = Double.toString(oldLocation.getLongitude()); waitingForLocationUpdate = false; getNearbyStores(); } else { Log.v(TAG, "NO Last Location found"); } }

Mi LocationListener

private class MyLocationListener implements LocationListener { public void onLocationChanged(Location location) { latitude = Double.toString(location.getLatitude()); longitude = Double.toString(location.getLongitude()); Log.v(TAG, "IN ON LOCATION CHANGE"); if (waitingForLocationUpdate) { getNearbyStores(); waitingForLocationUpdate = false; } locationManager.removeUpdates(this); } public void onStatusChanged(String s, int i, Bundle bundle) { Log.v(TAG, "Status changed: " + s); } public void onProviderEnabled(String s) { Log.e(TAG, "PROVIDER DISABLED: " + s); } public void onProviderDisabled(String s) { Log.e(TAG, "PROVIDER DISABLED: " + s); } }

Mis permisos en el AndroidManifest

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

Y finalmente el logcat después de ejecutar mi aplicación.

01-25 09:43:10.963: VERBOSE/NearbyListFragment(3060): IN ON CREATE 01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders 01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders 01-25 09:43:10.973: VERBOSE/LocationManagerService(1329): getProviders 01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): Provider: gps 01-25 09:43:10.983: DEBUG/LocationManager(3060): requestLocationUpdates: provider = gps, listener = co.fusionweb.dealsplus.app.NearbyItems$NearbyListFragment$MyLocationListener@46ef4680 01-25 09:43:10.983: DEBUG/GpsLocationProvider(1329): setMinTime 1 01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): NO Last Location found 01-25 09:43:10.983: VERBOSE/LocationManagerService(1329): _requestLocationUpdates: listener = Receiver{47421e68 Listener android.os.BinderProxy@47421a68} 01-25 09:43:11.003: VERBOSE/countingFragment(3060): IN ON CREATE VIEW 01-25 09:43:11.003: WARN/GpsLocationProvider(1329): Duplicate add listener for co.fusionweb.dealsplus 01-25 09:43:11.013: VERBOSE/ScrollListener(3060): In Constructor 01-25 09:43:11.013: VERBOSE/ScrollListener(3060): Scrolling 01-25 09:43:11.033: DEBUG/GpsLocationProvider(1329): startNavigating 01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_time_out(standalone = 60, agps = 89) 01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_accuracy(accuracy = 50) 01-25 09:43:11.043: VERBOSE/lib_locapi(1329): persist.radio.agps.mode: [] 01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_position mode, client = 1, interval = 1, mode = 1 01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl called: client = 1, ioctl_type = 2 01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_ioctl 01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [96] 01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet 01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [28] 01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_api_sync_ioctl: select_id = 0, loc_ioctl returned 0 01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet 01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [80] 01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): Callback received: 80 (cb_id=0x5310000 handle=1) 01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [28] 01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl result: client = 1, ioctl_type = 2, SUCCESS 01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_start 01-25 09:43:11.043: DEBUG/locapi_rpc_glue(1329): loc_start_fix 01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [44] 01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet 01-25 09:43:11.053: DEBUG/RPC(1329): read RPC packet size: [28] 01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet 01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet size: [80] 01-25 09:43:11.113: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1) 01-25 09:43:11.113: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned 01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_SESSION_BEGIN 01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: update status 01-25 09:43:11.113: VERBOSE/GpsLocationProvider(1329): reportStatus status: 1 01-25 09:43:11.113: DEBUG/GpsLocationProvider(1329): Acquiring wakelock 01-25 09:43:11.123: DEBUG/RPC(1329): written RPC packet size: [28] 01-25 09:43:11.183: DEBUG/PowerManagerService(1329): New lightsensor value:40, lcdValue:77 01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet 01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet size: [80] 01-25 09:43:11.273: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1) 01-25 09:43:11.273: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned 01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_ENGINE_ON 01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: update status 01-25 09:43:11.273: VERBOSE/GpsLocationProvider(1329): reportStatus status: 3

Y las partes de la ubicación del SDK de Android del logcat siguen repitiéndose. He intentado todo lo que puedo pensar y he visto en google y stackoverflow. También como nota, he podido hacer que funcione en un dispositivo 2.3 utilizando requestSingleUpdate que está disponible en API 9 y siguiendo la guía A Deep Dive into Location, pero necesito que funcione en 2.1 o 2.2 y superior utilizando el antiguo SDK. Si tiene alguna sugerencia o le gustaría saber más, por favor hágamelo saber. Gracias por adelantado.


Como escribió Steve Blackwell, tu configuración es buena. Lo que puedes intentar es entender si el 100% tiene una señal fija de GPS. He instalado una buena aplicación GPS Tester (de Play Store) y te mostrará si tienes una solución o no y a qué satélites estás conectado y cuál es la potencia de la conexión. Esta fue la razón por la que mi OnLocationChanged () nunca llamó. Intenté ejecutarlo desde un edificio: /

¡buena suerte!


Como respondió Phan Van Linh , probablemente es porque estás dentro de un edificio. Aquí hay una explicación sobre cómo simular el GPS para el emulador. Además, existe this aplicación que se burla de los datos del GPS.


El proveedor de GPS se deshabilitará cuando el dispositivo esté en baja potencia o use el modo de ahorro de energía, en ese caso no podemos recibirlo onLocationChanged

El proveedor de GPS casi nunca devuelve la ubicación si se queda dentro de la casa o el edificio (solo funciona bien en exteriores)

Por lo tanto, en mi aplicación GPS_PROVIDER y NETWORK_PROVIDER para recibir onLocationChanged() mejor

https://developer.android.com/guide/topics/location/strategies.html#Updates

Para solicitar actualizaciones de ubicación del proveedor de GPS, use GPS_PROVIDER en lugar de NETWORK_PROVIDER. También puede solicitar actualizaciones de ubicación tanto del GPS como del proveedor de ubicación de red llamando a requestLocationUpdates () dos veces, una para NETWORK_PROVIDER y una para GPS_PROVIDER.


Experimenté un problema similar. Tenía los permisos solicitados para el servicio correctamente, pero no llegó ninguna actualización. Resultó que todo lo que tenía que hacer era simplemente esperar. Mientras buscaba el problema en Internet, tenía la aplicación en ejecución y, después de unos minutos, comenzó a recibir actualizaciones. Luego, incluso cuando eliminé la aplicación y la ejecuté de nuevo, las actualizaciones se produjeron de manera instantánea. Supongo que es una cuestión del sistema, una optimización, tal vez debido al hecho de que el dispositivo no se movió en absoluto (por cierto, no es un dispositivo de mierda). , es pixel).


Me enfrenté a la misma cuestión. Obtuve getLastKnownLocation como nulo. El problema se resolvió cuando reinicié tanto el dispositivo como el servicio de ubicación en el dispositivo.


Parece que la configuración debería funcionar, ya que no es así, yo haría que su ejemplo sea lo más simple posible para solucionar problemas. Yo haría que su solicitud se vea como

requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

De esta manera obtienes TODAS las actualizaciones posibles. Y comente la parte sobre cómo obtener la última ubicación conocida. No es necesario todavía.

Luego, en onLocationChanged() , solo tiene

Log.v(TAG, "IN ON LOCATION CHANGE, lat=" + latitude + ", lon=" + longitude);

Comenta el resto para que mantengas activo a tu oyente. Esto debería darle un flujo de actualizaciones en un dispositivo real. En el emulador, deberá usar DDMS, y obtendrá una actualización de GPS cada vez que presione enviar.


Reemplazo

LocationManager.GPS_PROVIDER

con

LocationManager.NETWORK_PROVIDER

resuelto mi problema

Aquí está el fragmento de código de mi administrador de ubicación

LocationManager locationManager = (LocationManager) getActivity().getSystemService(LOCATION_SERVICE);

// Verificar permisos de ubicación, Marshmallow y superiores

if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), 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. Toast.makeText(getActivity(), "Not Enough Permission", Toast.LENGTH_SHORT).show(); return; }

// Obtener la ubicación actual para empezar

Location myLocation = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER); currentLatitude = myLocation.getLatitude(); currentLongitude = myLocation.getLongitude();

// Solicitar la actualización de la ubicación utilizando LocationManager.NETWORK_PROVIDER

locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, MapFragment.this);


Si está intentando con NETWORK_PROVIDER, es realmente difícil de probar:

  • en emulador: nunca trabajar
  • en el dispositivo real: solo funciona getLastKnownLocation (), para recibir onLocationChanged (), tiene que usar datos móviles y salir al exterior con el riesgo de perder el teléfono del ladrón: P

Supongo que la razón es que solo la ubicación del proveedor de la red no solo es su dispositivo, y el proveedor de la red nunca se mueve, por lo que el onLocationChanged () nunca llama. Puede ocurrir solo cuando se cambia entre datos móviles y wifi y viceversa. Por favor, corríjame si estoy equivocado.

Así que sugiero utilizar GPS_PROVIDER para experimentar antes de considerar el rendimiento y el uso de la batería. Funciona bien tanto en emuladores como en dispositivos reales. Para las mejores prácticas: https://developer.android.com/guide/topics/location/strategies.html

Me tomó varias horas probar con NETWORK_PROVIDER sin ningún resultado, así que espero que mi sugerencia sea de utilidad.


Tuve el mismo problema (onLocationChanged () nunca llamado con NETWORK_PROVIDER) en mi dispositivo real (M, targetSDK 23 de la aplicación) hasta que lo reinicié.


Tuve la misma situación, pensé que había cometido un error en mi código, por lo que el método onlocationchage no se llama, finalmente resolví esto.

Step 1 : Close your application and Open Google Map Application. Step 2 : Touch the location finder button or icon over the Google Map app then It will show, currently where you are located. Step 3 : Now Run your app and check onlocationchage will call.


LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); if (manager != null) { List<String> providers = manager.getAllProviders(); for (String provider : providers) { manager.requestLocationUpdates(provider, TIME_BW_UP, DISTANCE_BW_UP, locationListener); } }