Il fornitore di località fuso non sembra utilizzare il ricevitore GPS

Android 4.3 su Moto G, Android 4.4.2 su Nexus 7 2012, Android 4.4.2 su Nexus 5. Android Studio 0.4.

Non voglio ricevere gli aggiornamenti regolari di posizione, voglio solo una posizione precisa quando l'utente preme un button.

  • java.lang.VerifyError IllformsdLocaleException
  • ADB Nessuna periferica trovata
  • Come eseguire il codice OpenCV senza OpenCv Manager
  • Come disabilitare / abilitare i pulsanti positivi negativi di dialogo?
  • android SDK manager, mostra solo il pacchetto installato
  • GridLayout vs TableLayout
  • Ho seguito questo esempio: https://developer.android.com/training/location/retrieve-current.html

    Nel file manifesto:

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

    Verifico che i Servizi Play sono disponibili utilizzando GooglePlayServicesUtil.isGooglePlayServicesAvailable

    Nell'attività principale:

     //in activity onCreate method mLocationClient = new LocationClient(this, this, this); @Override protected void onStart() { mLocationClient.connect(); super.onStart(); } @Override protected void onStop() { mLocationClient.disconnect(); super.onStop(); } //in button onclick method mCurrentLocation = mLocationClient.getLastLocation(); 

    Non ho una carta SIM. Se abilisco Wifi, talvolta ottengo una posizione esatta. Altre volte mCurrentLocation è nullo.

    Se disattivo Wifi allora mCurrentLocation è sempre nullo.

    Sto testando fuori in diverse posizioni sempre con una chiara visione del cielo. Ho aspettato tre minuti in each luogo.

    Non vedo mai l'icona GPS visualizzata sulla barra di notifica di Android nella parte superiore dello schermo.

    Ho queste impostazioni di posizione: immettere qui la descrizione dell'immagine

    Un'applicazione Test GPS riesce a utilizzare GPS con successo all'interno dello stesso dispositivo con disabilitato Wi-Fi in modo che il GPS funzioni: immettere qui la descrizione dell'immagine

    La logging per gli aggiornamenti di località, come ad esempio https://developer.android.com/training/location/receive-location-updates.html , non funziona. Metodo registrato mai chiamato.

    Che cosa sto facendo di sbagliato?

  • WifiManager.getConfiguredNetworks restituisce sempre l'elenco vuoto
  • BLE 4.0 per get i dati di trasmissione dal dispositivo al telefono
  • Modificare il formato della string di date in android
  • setTextAppearance deprecata nel livello API 23
  • Come faccio a analizzare JSON da un HTTPResponse Java?
  • Ignora OnItemSelectedListener che scatta sulla creazione
  • 12 Solutions collect form web for “Il fornitore di località fuso non sembra utilizzare il ricevitore GPS”

    L'ho risolto. Il problema era che "Lascia che le applicazioni di Google accedano alla tua posizione" è stata distriggersta: immettere qui la descrizione dell'immagine

    Quando lo accendo ottiene le letture GPS e quando è fuori non lo faccio.

    L'ho lasciato per due motivi:

    1. Sto sviluppando un'app per essere utilizzato per un sacco di dispositivi in ​​un'azienda e voglio che sia necessaria una configuration manuale minima

    2. Lo schermo dice chiaramente "Questa impostazione influenza solo le applicazioni Google". So che Play Services è un software Google ma non credo che Google si aspetta che un utente finale lo capisca.

    Allora ho ottenuto l'aggiornamento di Android 4.4.2 e la pagina delle impostazioni di posizione è cambiata. Sembra che posso distriggersre la function Google Reporting Location e ricevere ancora le letture GPS dal fornitore di località fuso: immettere qui la descrizione dell'immagine

    Quindi forse Google ha capito che l'ambiente era confuso e migliorato. In entrambi i casi, avrei risparmiato molto tempo se avessi 4.4.2 pochi giorni fa.

    Il problema è con getLastLocation() perché utilizza una posizione memorizzata nella cache. Ho avuto lo stesso problema che ho anche cercato di utilizzare questo approccio semplice. Dal momento che ho commutato ad ascoltare gli aggiornamenti (e fermandosi dopo il primo aggiornamento successivo automaticamente).

    Questo è il mio codice che funziona.

    In primo luogo, il controllo della disponibilità in Application (non essenziale, può essere in Attività e senza tenere il risultato):

     public class MainApp extends Application { public static enum PlayServices { NOT_CHECKED, AVAILABLE, UNAVAILABLE }; public static PlayServices mPlayServices = PlayServices.NOT_CHECKED; @Override public void onCreate() { super.onCreate(); if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) { MainApp.mPlayServices = MainApp.PlayServices.AVAILABLE; } } } 

    Poi, sull'attività:

     public class MainActivity extends SherlockFragmentActivity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener { 

    Nella sua onCreate() :

     if (MainApp.mPlayServices != MainApp.PlayServices.UNAVAILABLE) { mLocationClient = new LocationClient(this, this, this); mLocationRequest = LocationRequest.create(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setInterval(5000); mLocationRequest.setNumUpdates(1); mLocationRequest.setFastestInterval(1000); mUpdatesRequested = false; MainApp.prefs.edit().putBoolean(MainApp.KEY_LOCATION_UPDATES_REQUESTED, mUpdatesRequested) .commit(); } 

    Il resto della class MainActivity :

     @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d(this.getClass().getSimpleName(), "onActivityResult(" + requestCode + ", " + resultCode + ")"); // Decide what to do based on the original request code switch (requestCode) { case MainApp.PLAY_CONNECTION_FAILURE_RESOLUTION_REQUEST: /* * If the result code is Activity.RESULT_OK, try * to connect again */ switch (resultCode) { case Activity.RESULT_OK: // here we want to initiate location requests! mLocationClient = new LocationClient(this, this, this); break; } break; } } @Override public void onConnected(Bundle dataBundle) { Log.d(this.getClass().getSimpleName(), "onConnected()"); Log.d(this.getClass().getSimpleName(), "Google Play Services are available."); MainApp.mPlayServices = MainApp.PlayServices.AVAILABLE; if (!mUpdatesRequested) { LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); boolean gps_enabled = false; try { gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); } catch (Exception ex) { } boolean network_enabled = false; try { network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER); } catch (Exception ex) { } // don't start listeners if no provider is enabled MainApp.locEnabled = gps_enabled || network_enabled; if (!MainApp.locEnabled) { // we have access to PlayServices, but user has disabled location visibility --> alert him alertLocationOff(); } else { mLocationClient.requestLocationUpdates(mLocationRequest, this); mUpdatesRequested = true; } } } @Override public void onDisconnected() { Log.d(this.getClass().getSimpleName(), "onDisconnected()"); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.d(this.getClass().getSimpleName(), "onConnectionFailed()"); Log.d(this.getClass().getSimpleName(), "Google Play Services not available."); MainApp.mPlayServices = MainApp.PlayServices.UNAVAILABLE; /* * Google Play services can resolve some errors it detects. * If the error has a resolution, try sending an Intent to * start a Google Play services activity that can resolve * error. */ if (connectionResult.hasResolution()) { try { // Start an Activity that tries to resolve the error connectionResult.startResolutionForResult(this, MainApp.PLAY_CONNECTION_FAILURE_RESOLUTION_REQUEST); /* * Thrown if Google Play services canceled the original * PendingIntent */ } catch (IntentSender.SendIntentException e) { // Log the error e.printStackTrace(); } } else { /* * If no resolution is available, display a dialog to the * user with the error. */ GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), this, 0).show(); } } @SuppressLint("NewApi") @Override public void onLocationChanged(Location location) { Log.d(this.getClass().getSimpleName(), "onLocationChanged(), location=" + location); if (location != null) { boolean present = true; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { present = Geocoder.isPresent(); } if (present) { (new ExtractLocationTask(this)).execute(location); } else { Log.e(this.getClass().getSimpleName(), "Geocoder not present"); MainApp.mPlayServices = MainApp.PlayServices.UNAVAILABLE; } } } private class ExtractLocationTask extends AsyncTask<Location, Void, Boolean> { Context mContext; public ExtractLocationTask(Context context) { super(); mContext = context; } @Override protected Boolean doInBackground(Location... params) { Log.d(getClass().getSimpleName(), "ExtractLocationTask.onPreExecute()"); boolean found = false; try { Geocoder geoCoder_local = new Geocoder(mContext, Locale.getDefault()); Geocoder geoCoder_en = new Geocoder(mContext, Locale.ENGLISH); List<Address> addresses_local = geoCoder_local.getFromLocation(params[0].getLatitude(), params[0].getLongitude(), 10); List<Address> addresses_en = geoCoder_en.getFromLocation(params[0].getLatitude(), params[0].getLongitude(), 10); if (addresses_local != null && addresses_local.size() > 0) { // do what you want with location info here // based on mLocationRequest.setNumUpdates(1), no need to call // removeLocationUpdates() MainApp.locEnabled = true; mUpdatesRequested = false; MainApp.prefs.edit() .putBoolean(MainApp.KEY_LOCATION_UPDATES_REQUESTED, mUpdatesRequested).commit(); found = true; } } catch (IOException e) { Log.e(this.getClass().getSimpleName(), "Exception: ", e); } return found; } @Override protected void onPostExecute(Boolean found) { Log.d(getClass().getSimpleName(), "ExtractLocationTask.onPostExecute()"); if (found) { // update UI etc. } else if (!mUpdatesReRequested) { mLocationClient.requestLocationUpdates(mLocationRequest, (LocationListener) mContext); mUpdatesRequested = true; mUpdatesReRequested = true; } } } 

    Spero che questo ti aiuterà a farlo funzionare!

    Il provider di località non sveglia il GPS finché alcuni dei client chiedono (sottoscrivi) la posizione di precisione elevata (come descritto negli esempi forniti da altri utenti). L'applicazione di test GPS non utilizza provider di localizzazione ma utilizza un vecchio modo "diretto" per get la posizione.

    C'è anche un meccanismo di scadenza, che rimuove le informazioni sull'ultima posizione dopo un po 'di tempo se si ritiene che sia stante.

    Riepilogando tutto è davvero ansible che LP (Location Provider) non abbia nulla da darti.

    Penso che tu stia testando la tua applicazione in Indoor, non funziona.

    e il codice di stream ..

     public void setUpLocationClientIfNeeded() { createLocReq(); if (mLocationClient == null) { mLocationClient = new LocationClient(getApplicationContext(), this, // ConnectionCallbacks this); // OnConnectionFailedListener } } private void createLocReq() { if (mLocationRequest == null) { // Create a new global location parameters object mLocationRequest = LocationRequest.create(); // Set the update interval mLocationRequest.setInterval(LocationServices.UPDATE_INTERVAL_IN_MILLISECONDS); // Use high accuracy mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // Set the interval ceiling to one minute mLocationRequest.setFastestInterval(LocationServices.FAST_INTERVAL_CEILING_IN_MILLISECONDS); mLocationClient = new LocationClient(getApplicationContext(), this, this); mLocationClient.connect(); } } public void updateLocation(Location location) { if (lastTrackedLat == 0.0) { lastTrackedLat = location.getLatitude(); } if (lastTrackedLng == 0.0) { lastTrackedLng = location.getLongitude(); } currentLat = location.getLatitude(); currentLng = location.getLongitude(); } @Override public void onLocationChanged(Location location) { if (location != null) { this.location = location; updateLocation(location); } } public Location getLocation() { // mLocationClient.getLastLocation(); return location; } 

    Secondo i documenti

    Questo metodo fornisce un modo semplificato per get la posizione. È particolarmente adatto per applicazioni che non richiedono una posizione precisa e che non vogliono mantenere logiche aggiuntive per gli aggiornamenti di localizzazione.

    quindi può o non restituire una posizione altamente precisa.

    Il GPS può richiedere un po 'di tempo per bloccarsi in modo da call getLastLocation può o non può restituire una posizione

    è meglio richiedere aggiornamenti di località dopo aver ottenuto una posizione appena smettere di richiedere gli aggiornamenti della posizione.

    Anche guardando il codice fornito stai aspettando che LocationClient connetta prima di tentare di get una posizione? Questo certamente darà una posizione nulla perché non è connesso per get la posizione ancora.

    quello che dovresti fare è nel tuo onConnected get l'ultima posizione lì, esempio

     public void onConnected(Bundle connectionHint) { Location location = mLocationClient.getLastLocation(); } 

    come si dice in quell'esempio onConnected è Called by Location Services when the request to connect the client finishes successfully. At this point, you can request the current location or start periodic updates Called by Location Services when the request to connect the client finishes successfully. At this point, you can request the current location or start periodic updates

    Tutto quello che devi fare è aggiungere una properties; di priorità all'object di richiesta come questo.

     public void onConnected(Bundle arg0) { locationrequest = LocationRequest.create(); locationrequest.setInterval(1000); locationrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationclient.requestLocationUpdates(locationrequest, this); } 

    Forse utilizzare una variabile booleana per consentire all'utente di avere opzioni per forzare il GPS come

     boolean forceGPS=false; . . .//make the user choose to change the value of the boolean . . public void onConnected(Bundle arg0) { locationrequest = LocationRequest.create(); locationrequest.setInterval(1000); if(forceGPS==true) { locationrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); } locationclient.requestLocationUpdates(locationrequest, this); } 

    Senza una sim card, il coarse location provider non ha modo di conoscere la posizione grossolana, a less che non sia in grado di trovare una networking WiFi mappata da Google.

    Richiedere l'ultima posizione conosciuta potrebbe provocare una posizione obsoleta e in quanto tale è piuttosto inutile. Immagino che questa sia la posizione che è stata registrata l'ultima volta che un'applicazione ha chiesto un aggiornamento della posizione.

    Utilizzo il seguente codice per get una posizione recente:

      Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_COARSE); criteria.setAltitudeRequired(false); criteria.setSpeedRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(false); final LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); .... LocationListener listener = new LocationListener() { @Override public void onLocationChanged(Location lastKnownLocation) { .... } // rest of interface } manager.requestSingleUpdate(criteria, listener, null); 

    L'ultima chiamata assicura che noi richiediamo la posizione corrente , non la posizione in cui è stato in grado di trovare una quantità sconosciuta di tempo prima.

    Potresti provare a modificarlo a Criteria.ACCURACY_FINE per get il GPS sparato. Tieni presente che se il GPS non ha avuto una correzione per un bel po ', mentre potrebbe richiedere più di alcuni minuti prima che sia effettivamente in grado di get una correzione. Mi aspetto nel tempo che vedresti l'icona GPS che indica che sta aspettando una correzione.

    Cosa c'è nel metodo OnConnected ?

    In questo metodo è necessario creare l'object LocationRequest con PRIORITY_HIGH_ACCURACY priorità.

     @Override public void onConnected(Bundle dataBundle) { mLocationRequest = LocationRequest.create(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationClient.requestLocationUpdates(mLocationRequest, fusedListener); } 

    Prova questo:

     public final static int MINACCURACY = 50; private LocationManager lm; private LocationListener listener; private void foundLoc(double x, double y) { // do something with x,y Log.v("DEBUG", x + "," + y); } public void findMe(View v) { lm = (LocationManager) getSystemService(LOCATION_SERVICE); listener = new LocationListener() { @Override public void onLocationChanged(Location location) { if(location.getAccuracy() < MINACCURACY) { foundLoc(location.getLatitude(), location.getLongitude()); lm.removeUpdates(listener); } } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } }; lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0, listener); } 

    MINACCURACY è in metri. In questo modo, premendo il button (che chiama il metodo findMe), il GPS è abilitato, la tua posizione viene trovata con una precisione minima, il metodo foundLoc ottiene i dati e l'ascoltatore termina (che a sua volta distriggers il GPS).

    Ci sono due cose che succedono qui che ti causano a volte get null e, a volte, get una posizione.

    In primo luogo, stai creando una nuova istanza di LocationClient nel metodo onClick , che non è la stessa istanza in cui si sta chiamando connect() in in onStart() . Ciò creerà comportmenti imprevedibili in cui talvolta il client avrà abbastanza tempo per connettersi prima di restituire un risultato da LocationClient.getLastLocation() e talvolta non lo farà.

    In secondo luogo, è necessario proteggere la chiamata a LocationClient.getLastLocation() con una chiamata a LocationClient.isConnected() . Dice quanto segue in LocationClient.isConnected() docs: https://developer.android.com/reference/com/google/android/gms/location/LocationClient.html#isConnected ()

    Controlla se il client è attualmente connesso al servizio, in modo che le richieste di altri methods abbiano successo. Le applicazioni devono proteggere le azioni del client causate dall'utente con una chiamata a questo metodo.

    Poiché l'utente sta triggersndo il codice onClick() toccando il button, dovresti call questo metodo prima di tentare di get l'ultima posizione.

    Quindi, il tuo codice dovrebbe essere simile a questo:

     LocationClient mLocationClient; Location mCurrentLocation; @Override protected void onCreate() { ... mLocationClient = new LocationClient(this, this, this); ... } @Override protected void onStart() { mLocationClient.connect(); super.onStart(); } @Override protected void onStop() { mLocationClient.disconnect(); super.onStop(); } public void onClick(View v) { ... if (mLocationClient.isConnected()) { // You should get a valid location here mCurrentLocation = mLocationClient.getLastLocation(); } } 

    Ciò dovrebbe dare a LocationClient un tempo abbastanza lungo per connettersi e darvi una posizione valida, che dovrebbe sperare includere i dati GPS.

    Dal momento che nessuno ha condiviso questo collegamento, ho trovato che questa è la documentazione più utile http://developer.android.com/guide/topics/location/strategies.html

    "Potresti prevedere che la correzione più recente della posizione sia la più accurata. Tuttavia, poiché l'accuratezza di una correzione di posizione varia, la correzione più recente non è sempre la cosa migliore: dovresti includere la logica per la scelta delle correzioni di località in base a diversi criteri. i criteri inoltre variano a seconda dei casi di utilizzo dell'applicazione e del test sul field ".

    La tua scommessa migliore è mantenere un ascoltatore di località fino a quando l'attività è in primo piano e select la posizione più memorizzata nella cache quando viene premuto il button. Potrebbe essere necessario mostrare un filatore o qualcosa e distriggersre il button mentre attende che venga visualizzato una misura accurata.

    Preferisco utilizzare il servizio che implementa LocationListener per get la posizione corrente quasi precisa. Di solito faccio i passi seguenti:

    1. Inizializza LocationManager e richiama requestLocationUpdates sia per GPS_PROVIDER che NETWORK_PROVIDER in onCreate()
    2. Ricall getLastKnownLocation sia per GPS_PROVIDER che NETWORK_PROVIDER e utilizzare getTime() per conoscere l'ultima posizione più recente.
    3. Trasmissione dell'ultima posizione (se è vecchia di <30 sec) (opzionale)
    4. Nel frattempo, quando viene chiamata onLocationChanged confronto la posizione recentemente aggiornata con l'ultima posizione migliore (se presente) e controlla il livello di precisione.
    5. Se la precisione delta <MIN_ACCURACY (variabile utente), utilizzala come posizione migliore
    6. Trasmetta la posizione migliore corrente
    7. Deve rimuovere LocationManager locationManager.removeUpdates(this);
    8. Chiamata stopSelf (); (puoi anche interrompere il servizio da onDestroy dell'attività)

    EDIT:

    OK … Il metodo più alto stava utilizzando l'API della posizione, sotto che ho codificato utilizzando il fornitore fuso (GooglePlayServices). Ho testato sul mio Nexus 5 (Android 4.4.2), NO SIM, NO WIFI … e sto ottenendo risultati.

    Modifica 2: ho anche testato su Android 2.3.3 LG Optimus (No SIM e Wifi) e ci sono voluti circa 5 minuti per get la chiusura (utilizzando Fused Provided), ma mi stavo trovando immediatamente l'icona della posizione.

     public class HomeActivity extends FragmentActivity implements ActionBar.OnNavigationListener, GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener { private LocationClient locationClient; private LocationRequest locationRequest; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); // ... int resp = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (resp == ConnectionResult.SUCCESS) { locationClient = new LocationClient(this, this, this); locationClient.connect(); } else { Toast.makeText(this, "Google Play Service Error " + resp, Toast.LENGTH_LONG).show(); } } @Override public void onConnected(Bundle connectionHint) { if (locationClient != null && locationClient.isConnected()) { locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(100); locationClient.requestLocationUpdates(locationRequest, this); } } @Override public void onLocationChanged(Location location) { try { if (location != null) { LatLng gps = new LatLng(location.getLatitude(), location.getLongitude()); Log.v("JD", "My Location: " + gps.toString()); } } catch (Exception e) { Log.d("JD", "onLocationChanged", e); } } } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.