4

I have been trying to get location (lat/lon) using Fused Location Api in andriod. My code works fine when both wifi and gps are on. If I turn off the gps then i don't get any location update.

I am using BALANCED_POWER_ACCURACY for location request. I have added Access_FINE_Location permission in manifest and using play services version 9.2.1 in my build.gradle file.
I am testing on real devices(Samsung SM0G360H API 19 and Samsung SM-G361 API 21). Both give the same results.
Can anyone tell me how exactly Fused Location Api works?
How can i get location updates while gps is off but network connection is on?
My code:

public class LocationUpdateusingFused extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,LocationListener{



TextView txtOutputLat, txtOutputLon;
Location mLastLocation;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
String lat, lon;

Intent batteryStatus;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fleet_layout);

    txtOutputLat = (TextView) findViewById(R.id.textView);
    txtOutputLon = (TextView) findViewById(R.id.textView2);


    buildGoogleApiClient();
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    mLocationRequest.setMaxWaitTime(5000);
    mLocationRequest.setInterval(10000); // Update location every second

    try {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);


        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);
    }
    catch (SecurityException e)
    {
        Log.e("LocatonUpdate",e+" ");
    }
    if (mLastLocation != null) {
        lat = String.valueOf(mLastLocation.getLatitude());
        lon = String.valueOf(mLastLocation.getLongitude());

    }
    updateUI();
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onLocationChanged(Location location) {
    lat = String.valueOf(location.getLatitude());
    lon = String.valueOf(location.getLongitude());
    Log.e("LocationChanged",location.getSpeed()+" "+location.getAccuracy()+" "+location.getBearing()+" "+location.getProvider()+" "+location.getAltitude()
    );

    updateUI();
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    buildGoogleApiClient();
}

@Override
protected void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mGoogleApiClient.disconnect();
}
void updateUI() {
    txtOutputLat.setText(lat);
    txtOutputLon.setText(lon);
}
synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();


}

}

Alvi
  • 767
  • 8
  • 20
  • Did you check the locations settings? Also setInterval(10000) is 10 sec. Not that it matters. – masp Sep 18 '16 at 07:27
  • thanks for mentioning location settings but i want to get location update only using network i.e. location service will be off. I was able to do so using normal LocationService but fused provider is not working with location service being off. Can you give me any info on this? – Alvi Sep 18 '16 at 08:47
  • You disabled location services? Why and which setting exactly on your 21 samsung? If you don't want the app to use gps, you can change the permissions and use only ACCESS_COARSE_LOCATION. You can still use the fused provider with PRIORITY_BALANCED_POWER_ACCURACY. First the algorithm checks the network provider and then goes for gps if available. – masp Sep 18 '16 at 09:14
  • I can get updates from either provider by keeping the location services on. But i am trying to reduce battery usage and get location update just using network. Is it possible to get so while location services off? – Alvi Sep 18 '16 at 11:11
  • In location settings it asks for Mode, right? What do you use there? If you close everything your app doesn't get updates. Only last known location probably. Also your end goal is an energy efficient algorithm. Well that's why google gave us the Fused provider. Before that you had to do it by yourself. Here https://developer.android.com/training/location/change-location-settings.html#location-request there are enough options you can use. And read again my previous comment to disable gps. – masp Sep 18 '16 at 11:22
  • have you found any solution – M.Yogeshwaran Oct 14 '16 at 14:55
  • No, Have to keep the location service on to work in all devices – Alvi Oct 15 '16 at 04:54

1 Answers1

3

Sorry for a rather long delay in trying to answer your question. I have been fighting with the whole location problem myself so I will provide you with things I noticed and learned after "much hardship". Hope you still need an answer of sorts.

I cannot remember how the API level 19 settings look like but in general all location settings from API lvl 15 and up (plus minus some options here and there) have been set to conform with the FusedLocationProviderAPI logic. What I mean by that is; you HAVE to have the location setting on at all times to get any kind of location updates, as the setting/toggle controls the general location. Hopefully this answers your main question.

To provide some more information. As masp mentions in one of the comments you can control what the provider actually uses through the permissions and constants of the Fused Location API.

For permissions you have to choose between ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION. The difference is (I quote):

If you are using both NETWORK_PROVIDER and GPS_PROVIDER, then you need to request only the ACCESS_FINE_LOCATION permission, because it includes permission for both providers. Permission for ACCESS_COARSE_LOCATION allows access only to NETWORK_PROVIDER.

And then we have the FusedLocationProviderAPI constants where things get a bit more complicated. Also from API lvl 21 and up we have this:

enter image description here

If you enter mode then you get:

enter image description here

I won't go more into the constants. They have been tested in the accepted answer of this question. I suggest you have a gander. I need to mention, though, that no matter what you do with these, the mode in settings takes precedence. You can ask for the GPS in the app but if the user says battery saving in the settings then that is that.

The last thing I should probably mention is that, if you set the permission to ACCESS_COARSE_LOCATION then expect horrendous accuracy (shown also in the test I linked above). My suggestion is to use ACCESS_FINE_LOCATION and then play around with the Fused Location constants and the intervals (setInterval and setFastestInterval)

Hope this helps a little even if rather late.

Community
  • 1
  • 1
MadDim
  • 543
  • 6
  • 22