Google Maps API v2 default marker not aligned with manually drawn marker in LocationCallback()

142 Views Asked by At

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:

example google map image

0

There are 0 best solutions below