Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onLocationChanged not called on some devices

Tags:

This is a question which has been asked numerous times but I could not find a solution that always works.

I am developing an application using the Fused location provider. In the onConnected() method, I am requesting for location updates and the application logic will be initiated once a location fix is generated and onLocationChanged() is called. (Please refer to my code below).

Problem onLocationChanged() method is never called on some devices. I use a Samsung Tab 2 and a Samsung Galaxy Grand for testing. This code works perfectly fine on the Tab 2 but does not work on Grand. By does not work, I mean that locationClient gets connected but onLocationChanged() is never called.

Earlier, I used the location manager for getting location and in that implementation, the same problem occurred. So, I tried implementing the fused location provider but I still get the same problem.

Can anyone help me out with this issue? Is there something I am missing here?

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

LocationClient locationclient;
LocationRequest lr;
Location loc1;
static String address;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);     

    locationclient = new LocationClient(this,this,this);
    locationclient.connect();        

}

@Override
public void onConnected(Bundle arg0) {
    // TODO Auto-generated method stub

    lr=LocationRequest.create();
    lr.setInterval(100);
    locationclient.requestLocationUpdates(lr, this);
    Log.d("LocationClient","On Connected");
}

@Override
public void onDisconnected() {
    // TODO Auto-generated method stub
    locationclient.disconnect();

}

@Override
public void onConnectionFailed(ConnectionResult arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onLocationChanged(Location loc) {
    // TODO Auto-generated method stub      

    // Application Logic        

    Log.d("LocationClient","Last Known Location LC:" + loc.getLatitude() + "," + loc.getLongitude());
}
}
like image 605
Rohit Avatar asked Aug 07 '13 17:08

Rohit


People also ask

When onLocationChanged is called in Android?

onLocationChanged. Called when the location has changed and locations are being delivered in batches. The default implementation calls through to onLocationChanged(android.

What is fused location provider client?

The fused location provider is a location API in Google Play services that intelligently combines different signals to provide the location information that your app needs.

Which method is used to register the listener receiving location updates?

Once a location request is in place you can start the regular updates by calling requestLocationUpdates() . Depending on the form of the request, the fused location provider either invokes the LocationCallback.


1 Answers

I observed same behavior on Galaxy Nexus and recognized two things causing onLocationChanged() to not being called. There are

  1. Corresponding location source is not enabled in System Settings. For PRIORITY_HIGH_ACCURACY the GPS satellites must be enabled, for PRIORITY_BALANCED_POWER_ACCURACY Wi-Fi & mobile network location must be enabled.

  2. Even for the enabled location sources there can be no valid location information available. For instance, PRIORITY_HIGH_ACCURACY source is enabled, but there is no (or not good) GPS reception (e.g. device is inside a building). Or PRIORITY_BALANCED_POWER_ACCURACY source is enabled, but both Wi-Fi and mobile data are switched off. In those cases location cannot be detected and onLocationChanged() will not be called.

To fix #1 I had to check whether required location sources are enabled even before connecting to Google Services API and if they are switched off, then I notified a user asked him/her to allow location access.

To solve #2 I decided to use LocationRequest.setExpirationDuration(). I set timeout at about 10 seconds, and immediately after calling requestLocationUpdates() I post a callback delayed by same 10 seconds. If delayed callback is called before requestLocationUpdates(), this means location cannot be detected due to reason #2. I do three retries and then show user an error message.

Android documentation is not great at this place, that's why I hope this helps.

like image 180
sergej shafarenka Avatar answered Sep 27 '22 17:09

sergej shafarenka