I've been looking online for the past couple of weeks about this and it seems I'm not asking the right questions so posting one here. Thanks in advance for any info.
Using Android v7.1 and Google Maps API v2 I want to show a user's location on a map fragment. My question is: why does the default current location marker (blue circle in example image below) often not align with the marker I manually draw to show the user's location (green circle)? The code redraws the green marker when location is changed, so I am trying to figure out why the green marker is not being redrawn as often as the default current location marker moves.
Do I simply need to update the frequency/displacement that my LocationCallback()
is getting called? Currently it is set at 500ms, with displacement of 2 meters. If this is the case, will that have significant impact on battery?
I've experimented with using onLocationChanged()
instead of the fused location api's LocationCallback()
, but then my manual marker doesn't get updated if the user doesn't have an internet connection.
I realize I've got something off in my code, but I guess my understanding isn't good enough that I'm managing to figure it out by myself. Thanks again in advance for any insight.
Relevant code and example image:
From MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapFragment);
mapFragment.getMapAsync(this);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
mLastLocation = locationResult.getLastLocation();
mapManager.updateLocation(mLastLocation); //this is where the green marker is drawn
}
};
}
@Override
public void onConnectionSuspended(int i) {}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {}
@Override
protected void onResume() {
super.onResume();
mapState = new MapState(this);
if (mapFragment == null) {
mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapFragment);
mapFragment.getMapAsync(this);
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mapManager.mMap = googleMap;
mapManager.mMap.setOnMapLongClickListener(this);
mapState = new MapState(this);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mapManager.mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mapManager.mMap.setMyLocationEnabled(true);
}
CameraPosition position = mapState.getSavedCameraPosition();
if (position != null) {
CameraUpdate update = CameraUpdateFactory.newCameraPosition(position);
mapManager.mMap.setMapType(mapState.getSavedMapType());
}
}
protected synchronized void buildGoogleApiClient() {
//https://stackoverflow.com/questions/37102240/cannot-resolve-symbol-mgoogleapiclient-android-studio
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
private void setupAndRequestLocationPermissions() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(500);
mLocationRequest.setFastestInterval(500);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setSmallestDisplacement(2); //10 meters
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback,
null);
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
setupAndRequestLocationPermissions();
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission was granted.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mapManager.mMap.setMyLocationEnabled(true);
} else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
}}
From manifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Example image: