简体   繁体   中英

How to get location using Fused Location Provider in android using Network?

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.


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();


}

}

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:

在此处输入图片说明

If you enter mode then you get:

在此处输入图片说明

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM