Google Maps returning Latitude and Longitude as zero and problems when placing the Marker

1

I'm trying to use Google Maps, and set a location on it (pulling the user's Latitude and Longitude). It pulls and displays in a Toast, but it does not setta this in the onMapReady or Marker method, and if I put a Log in onResume (), it shows as zero.

public class LocationHomeFragment extends BaseFragment implements MvpView, OnMapReadyCallback {
    private static final String ARG_PARAM1 = "Title";

    private static final int PERM_LOCAL = 2;
    private GoogleMap mMap;
    private double[] pos;
    private FusedLocationProviderClient mFusedLocationClient;

    public static Fragment newInstance(String title) {
        LocationHomeFragment fragment = new LocationHomeFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, title);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_location_home, container, false);
        ButterKnife.bind(this, view);

        SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map_localizacao_home);
        if (mapFragment != null) {
            mapFragment.getMapAsync(this);
        }
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
    //  AQUI ELE PUXA COMO ZERO PARA AMBOS
        pos = mostraPosicao();
        Log.i("LOG", "onResume(): Lat -> " + pos[0]);
        Log.i("LOG", "onResume(): Lng -> " + pos[1]);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//            //  permisao aceita
            mostraPosicao();
            Log.i("LOG", "Aceitou");
            CommonUtils.toast(getContext(), "Aceitou");
        } else {
            Log.i("LOG", "Recusou");
            CommonUtils.toast(getContext(), "Recusou");
        }

        if (requestCode == PERM_LOCAL) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                mostraPosicao();
            } else {
                Log.i("LOG", "else1");
            }
        } else {
            Log.i("LOG", "else2");
        }
    }

    public double[] mostraPosicao() {
        double[] d = new double[2];
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
        if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, PERM_LOCAL);
        } else {
            mFusedLocationClient.getLastLocation().addOnSuccessListener(getActivity(), new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    if (location != null) {
                        d[0] = location.getLatitude();
                        Toast.makeText(getActivity(), "Latitude: " + String.valueOf(location.getLatitude()), Toast.LENGTH_SHORT).show();
                        Log.i("LOG", "Latitude: " + location.getLatitude());
                        d[1] = location.getLongitude();
                        Toast.makeText(getActivity(), "Longitude: " + location.getLongitude(), Toast.LENGTH_SHORT).show();
                        Log.i("LOG", "Longitude: " + location.getLongitude());
                    } else {
                        Log.i("LOG", "Localização vindo nula");
                    }
                }

            });
        }

        return d;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        Log.i("LOG", "MapReady");

        googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
            @Override
            public void onMapLoaded() {
                LatLng posicao = new LatLng(-23.6179537, -46.688076);
                Log.i("LOG", "Lat: " + pos[0]);
                Log.i("LOG", "Lng: " + pos[1]);
//                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(posicao, 13));
                mMap.addMarker(new MarkerOptions()
                        .position(posicao)
                        .title("Local")
                        .snippet("Endereço do local")
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.bigpin)));
                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(posicao, 13));
            }
        });

    }
}
    
asked by anonymous 19.02.2018 / 15:42

2 answers

1

The problem you have there is that both onSuccess(Location location) and onMapReady(GoogleMap googleMap) are asynchronous, ie onSuccess can be executed before onMapReady or vice versa. When you run pos = mostraPosicao(); on onResume , the pos variable will point to the same reference as the d variable, which is an empty two-position array. Why is it empty? Because onSuccess(Location location) is asynchronous and has not been called yet. That's why Logs of onResume will set 0.

One solution is:

public class LocationHomeFragment extends BaseFragment implements MvpView, OnMapReadyCallback {
    private static final String ARG_PARAM1 = "Title";

    private static final int PERM_LOCAL = 2;
    private GoogleMap mMap;
    private double[] pos;
    private FusedLocationProviderClient mFusedLocationClient;

    public static Fragment newInstance(String title) {
        LocationHomeFragment fragment = new LocationHomeFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, title);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_location_home, container, false);
        ButterKnife.bind(this, view);

        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
    //  AQUI ELE PUXA COMO ZERO PARA AMBOS
        pos = mostraPosicao();
        Log.i("LOG", "onResume(): Lat -> " + pos[0]);
        Log.i("LOG", "onResume(): Lng -> " + pos[1]);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//            //  permisao aceita
            mostraPosicao();

            Log.i("LOG", "Aceitou");
            CommonUtils.toast(getContext(), "Aceitou");
        } else {
            Log.i("LOG", "Recusou");
            CommonUtils.toast(getContext(), "Recusou");
        }

        if (requestCode == PERM_LOCAL) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                mostraPosicao();
            } else {
                Log.i("LOG", "else1");
            }
        } else {
            Log.i("LOG", "else2");
        }
    }

    public double[] mostraPosicao() {
        double[] d = new double[2];
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
        if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, PERM_LOCAL);
        } else {
            mFusedLocationClient.getLastLocation().addOnSuccessListener(getActivity(), new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    if (location != null) {
                        d[0] = location.getLatitude();
                        Toast.makeText(getActivity(), "Latitude: " + String.valueOf(location.getLatitude()), Toast.LENGTH_SHORT).show();
                        Log.i("LOG", "Latitude: " + location.getLatitude());
                        d[1] = location.getLongitude();
                        Toast.makeText(getActivity(), "Longitude: " + location.getLongitude(), Toast.LENGTH_SHORT).show();
                        Log.i("LOG", "Longitude: " + location.getLongitude());
                        pos = d;
                        SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map_localizacao_home);
                        if (mapFragment != null) {
                            mapFragment.getMapAsync(this);
                        }
                    } else {
                        Log.i("LOG", "Localização vindo nula");
                    }
                }

            });
        }

        return d;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        Log.i("LOG", "MapReady");

        googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
            @Override
            public void onMapLoaded() {
                LatLng posicao = new LatLng(-23.6179537, -46.688076);
                Log.i("LOG", "Lat: " + pos[0]);
                Log.i("LOG", "Lng: " + pos[1]);
//                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(posicao, 13));
                mMap.addMarker(new MarkerOptions()
                        .position(posicao)
                        .title("Local")
                        .snippet("Endereço do local")
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.bigpin)));
                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(posicao, 13));
            }
        });

    }
}

What I did was move the call

SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map_localizacao_home);

if (mapFragment != null) {
    mapFragment.getMapAsync(this);
}

into the onSucess(Location location) method.

I recommend you refactor this code!

Abs.

    
20.02.2018 / 04:25
1

The action of adding the Marker to the map is only valid / possible after the map is ready ( onMapReady() ) and the location has been obtained ( onSuccess() ).

As both map creation and localization are asynchronous procedures, it is not known which order they are terminated in.

To ensure that both are available when adding the Marker it should be added either in the onMapReady() method, if the location has already been obtained, or in the onSuccess() method, if the map is already ready.

Declare an attribute to save the location:

Location myLocation;

Type a method to add Marker:

private void addMyPositionMarker(Location location){

    LatLng posicao = new LatLng(location.getLatitude(), location.getLongitude());
    mMap.addMarker(new MarkerOptions()
            .position(posicao)
            .title("Local")
            .snippet("Endereço do local")
            .icon(BitmapDescriptorFactory.fromResource(R.drawable.bigpin)));
    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(posicao, 13));
}

In the onSuccess() method, save the obtained location and call the addMyPositionMarker() method, if the map is already available:

mFusedLocationClient.getLastLocation().addOnSuccessListener(getActivity(), new OnSuccessListener<Location>() {
    @Override
    public void onSuccess(Location location) {

    myLocation = location;
    if(mMap != null){
        addMyPositionMarker(location);
    }
});

In method onMapReady() call method addMyPositionMarker() , if location is already available:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    Log.i("LOG", "MapReady");
    if(myLocation != null){
        addMyPositionMarker(myLocation);
    }
}
    
20.02.2018 / 16:07