Fused location provider doesn't seem to use GPS receiver
Fused location provider doesn't seem to use GPS receiver
Android 4.3 on Moto G, Android 4.4.2 on Nexus 7 2012, Android 4.4.2 on Nexus 5. Android Studio 0.4.
I don't want to receive regular location updates, I just want an accurate location when the user presses a button.
I have followed this example: https://developer.android.com/training/location/retrieve-current.html
In manifest file:
I check that Play Services are available using GooglePlayServicesUtil.isGooglePlayServicesAvailable
In main activity:
//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();
I have no SIM card. If I enable Wifi then sometimes I get an accurate location. Other times mCurrentLocation is null.
If I disable Wifi then mCurrentLocation is always null.
I am testing outside in several locations always with a clear view of the sky. I waited three minutes in each location.
I never see the GPS icon appear on the Android notification bar at the top of the screen.
I have these location settings:
A GPS Test app manages to use GPS successfully indoors on the same device with Wi-Fi disabled so GPS is working:
Registering for location updates, as at https://developer.android.com/training/location/receive-location-updates.html, doesn't work either. Registered method never called.
What am I doing wrong?
Answer by vinay Maneti for Fused location provider doesn't seem to use GPS receiver
I think your are testing your application in Indoor , it doesn't works..
and code flow..
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; }
Answer by tyczj for Fused location provider doesn't seem to use GPS receiver
According to the docs
This method provides a simplified way to get location. It is particularly well suited for applications that do not require an accurate location and that do not want to maintain extra logic for location updates.
so it may or may not return a highly accurate location.
GPS can take a while to lock on so calling getLastLocation
may or may not return a location
you are better off requesting location updates then after you get a location just stop requesting location updates.
Also looking at you code you provided are you waiting for the LocationClient
to connect before trying to get a location? That will certainly give you a null location since it is not connected to get the location yet.
what you should be doing is in your onConnected
get the last location there, example
public void onConnected(Bundle connectionHint) { Location location = mLocationClient.getLastLocation(); }
as it says in that example onConnected is 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
Answer by user1993392 for Fused location provider doesn't seem to use GPS receiver
Without a sim card the coarse location provider
has no way to know the coarse position, unless it is able to find a WiFi network that has been mapped by Google.
Requesting the last known location may result in a outdated location, and as such is rather useless. I guess this is the position that was recorded the last time some app requested a location update.
I use the following code to get a recent location:
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);
The last call ensures that we request the current location, not the location it was able to find an unknown amount of time before.
You might try to change it to Criteria.ACCURACY_FINE
in order to get the GPS fired up. Be aware that if the GPS didn't have a fix for quite some while it may take more than several minutes before it is actually capable of getting a fix. I'd expect in the mean time that you'd see the GPS icon indicating it is waiting for a fix.
Answer by Andrew for Fused location provider doesn't seem to use GPS receiver
Location provider won't wake up GPS until some of clients ask (subscribe) for high precision location (as described in examples given by other users). GPS test app doesn't use location provider but uses old "direct" way of obtaining location.
Also there is expiry mechanism, which removes information about last location after some time if it is believed to be stale.
Summing up all above it is really possible that LP(Location Provider) has nothing to give you.
Answer by c0m3tx for Fused location provider doesn't seem to use GPS receiver
Try this:
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
is in meters. This way, on button press (which calls the findMe method), the GPS is enabled, your location is found with a minimum accuracy, the method foundLoc gets the data and the listener terminates (which, in turn, disables GPS).
Answer by Saran for Fused location provider doesn't seem to use GPS receiver
The problem is with getLastLocation()
because it uses a cached location. I had the same problem as I also tried to use this simple approach. Since, I have switched to listening to updates (and stopping after 1st successfull update automatically).
This is my code that works.
First, the check for availability in Application (not essential, can be in Activity and without keeping of result):
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; } } }
Then, on to the Activity:
public class MainActivity extends SherlockFragmentActivity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
In its 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(); }
The rest of the MainActivity
class:
@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 { 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 addresses_local = geoCoder_local.getFromLocation(params[0].getLatitude(), params[0].getLongitude(), 10); List 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; } } }
I hope this will help you get it to work!
Answer by Tamal for Fused location provider doesn't seem to use GPS receiver
I prefer to use Service that implements LocationListener
to get current near-accurate location. I normally take following steps:
- Initialize
LocationManager
and callrequestLocationUpdates
for bothGPS_PROVIDER
andNETWORK_PROVIDER
inonCreate()
- Call
getLastKnownLocation
for bothGPS_PROVIDER
andNETWORK_PROVIDER
and usegetTime()
to know last newer location. - Broadcast last location (if it's <30 sec old) (optional)
- In the meantime, when
onLocationChanged
is called I compare newly updated location with last best location (if any) and check accuracy level. - If accuracy delta < MIN_ACCURACY (user variable), use it as best location
- Broadcast current best location
- Must remove LocationManager
locationManager.removeUpdates(this);
- Call stopSelf(); (you can also stop service from activity's
onDestroy
)
EDIT:
OK...Above method was using Location API, below I have coded using Fused Provider (GooglePlayServices). I have tested on my Nexus 5 (Android 4.4.2), NO SIM, NO WIFI...and I'm getting results.
Edit 2: I have also tested on Android 2.3.3 LG Optimus (No SIM & Wifi) and it took about 5 min to get lock (using Fused Provided), but I was getting location icon instantly.
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); } } }
Answer by user1639673 for Fused location provider doesn't seem to use GPS receiver
What's on the "OnConnected" method?
In this method you should create the "LocationRequest" object with "PRIORITY_HIGH_ACCURACY" priority.
@Override public void onConnected(Bundle dataBundle) { mLocationRequest = LocationRequest.create(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationClient.requestLocationUpdates(mLocationRequest, fusedListener); }
Answer by Sean Barbeau for Fused location provider doesn't seem to use GPS receiver
There are two things going on here that are causing you to sometimes get null
, and sometimes get a location.
First, you're creating a new instance of the LocationClient
in the onClick
method, which is not the same instance you're calling connect()
on in onStart()
. This will create unpredictable behavior where sometimes the client will have enough time to connect before returning a result from LocationClient.getLastLocation()
, and sometimes it won't.
Second, you should guard the call to LocationClient.getLastLocation()
with a call to LocationClient.isConnected()
. It says the following in the LocationClient.isConnected()
docs: https://developer.android.com/reference/com/google/android/gms/location/LocationClient.html#isConnected()
Checks if the client is currently connected to the service, so that requests to other methods will succeed. Applications should guard client actions caused by the user with a call to this method.
Since the user is triggering the onClick()
code by tapping on the button, you should call this method before trying to get the last location.
So, your code should look like this:
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(); } }
This should give the LocationClient
a long enough time to connect and give you a valid location, which should hopefully include GPS data.
Answer by Eric Woodruff for Fused location provider doesn't seem to use GPS receiver
Since no one has shared this link, I found this to be the most helpful documentation http://developer.android.com/guide/topics/location/strategies.html
"You might expect that the most recent location fix is the most accurate. However, because the accuracy of a location fix varies, the most recent fix is not always the best. You should include logic for choosing location fixes based on several criteria. The criteria also varies depending on the use-cases of the application and field testing."
Your best bet is to keep a location listener going as long as the activity is in the foreground and select the most accurate cached location when the button is pressed. You may need to show a spinner or something and disable the button while it waits for an accurate measurement to show up.
Answer by cja for Fused location provider doesn't seem to use GPS receiver
I solved it. The problem was that "Let Google apps access your location" was turned off:
When I turn it on I get GPS readings and when it's off I don't.
I had left it off for two reasons:
I'm developing an app to be used to lots of devices at a company and I want minimum manual configuration to be necessary
The screen says clearly "This setting affects Google apps only." I know that Play Services is Google software but I didn't think Google would expect an end user to understand that.
Then I got the Android 4.4.2 update and the location settings page has changed. It appears that I can have Google Location Reporting turned off and still get GPS readings from the fused location provider:
So maybe Google realised that the setting was confusing and improved it. Either way, I'd have saved a lot of time if I'd got 4.4.2 a few days ago.
Answer by Sujal Mandal for Fused location provider doesn't seem to use GPS receiver
All you need to do is to add a priority property to the request object like this.
public void onConnected(Bundle arg0) { locationrequest = LocationRequest.create(); locationrequest.setInterval(1000); locationrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationclient.requestLocationUpdates(locationrequest, this); }
Maybe use a boolean variable to let the user have options to force GPS like
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); }
Answer by Imran Khan Saifi for Fused location provider doesn't seem to use GPS receiver
STEPS TO GET LAST KNOWN LOCATION :-- ------------------------------------- ------------------------------------- 1. First check for availability of Google Play Services :-- int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (resultCode == ConnectionResult.SUCCESS) return true 2. Creating google api client object:- GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API).build(); 3. After creating connect, OnConnected Method of ConnectionCallbacks Interface called where we get location As :-- Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient );
Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72
0 comments:
Post a Comment