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

Asked

Viewed 125 times

1

I’m trying to use Google Maps, and settar a location in it (pulling the user’s Latitude and Longitude). It pulls and displays on a Toast, but it does not Setta this in the onMapReady method and not in Marker, 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));
            }
        });

    }
}

2 answers

1

Adding Marker to map action is only valid/possible after map is ready(onMapReady()) and the location to be obtained(onSuccess()).

As both the creation of the map and the obtaining of the location are asynchronous procedures it is not known which order in which they are terminated.

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

Declare an attribute to store the location:

Location myLocation;

Write 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 method onSuccess() save the obtained location and call the method addMyPositionMarker(), 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 the method onMapReady() call the method addMyPositionMarker(), if the location is already available:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    Log.i("LOG", "MapReady");
    if(myLocation != null){
        addMyPositionMarker(myLocation);
    }
}
  • I tested, but anyway it pulls like 0 both Latitude and Longitude, and while allowing, it still automatically does not move the camera to the indicated location

  • It may be the case that there is no "last known location", mainly in the use of an emulator. In this situation, first run an application that uses your location, such as Google Maps. To avoid this situation you must use a Locationrequest in conjunction with Fusedlocationclient, using the method mFusedLocationClient.requestLocationUpdates(). On the other hand your code is very "confusing" and the problem may be "hidden" because of this.

  • Wonderful... I’ll try. But anyway, thank you very much!

1

The problem you have there is that both the method onSuccess(Location location) and the onMapReady(GoogleMap googleMap) are asynchronous, i.e., onSuccess can be executed before the onMapReady or the other way around. When you perform pos = mostraPosicao(); in the onResume, the variable pos will point to the same reference as the variable d, which is an empty two position array. Why is it empty? Because the onSuccess(Location location) is asynchronous and has not been called yet. That’s why the onResume will print 0.

A 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 apartment onSucess(Location location).

I recommend refactoring this code!

Abs.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.