-4

I'm a student currently learning and try to play around with google map api. Right now, I'm facing a problem with the getting the location lat, long. Yesterday, I can use it just fine, but suddenly I cannot use it anymore today. The code is kinda long, because I wanted to show that the app asked for permission for the location to be turn on before using the apps but I don't think I get it correctly. I don't think the app starts like how I wanted it to start.

The process should be, from previous activity intent to this MapsActivity will prompt the request permission to open location, and once the location is on, the google map marker will update to the current location.

Right now, the apps just keeps on crashing.

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    FusedLocationProviderClient mFusedLocationClient;
    LocationRequest mLocationRequest;
    LocationCallback mLocationCallback;
    double mLocationLat, mLocationLong;

    LocationSettingsRequest.Builder mLocationSettingsBuilder;
    SettingsClient client;
    Task<LocationSettingsResponse> task;
    private static final int REQUEST_CHECK_SETTINGS = 0x1;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

        setSupportActionBar(toolbar);
        //toolbar.setTitle("AskForMech : Maps");
        //toolbar.setLogo(R.drawable.ic_launcher);

        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(MapsActivity.this);

        mLocationCallback = new LocationCallback(){
            @Override
            public void onLocationResult(LocationResult locationResult) {
                if(locationResult==null){
                    return;
                } else {
                    mLocationLat = locationResult.getLastLocation().getLatitude();
                    mLocationLong = locationResult.getLastLocation().getLongitude();
                }
            }
        };

        setLocationRequestSettings();

    }

    public void getLocation(){ //error is here
        LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        mLocationLat = location.getLatitude();
        mLocationLong = location.getLongitude();
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        getLocation(); //error is here
        LatLng pos = new LatLng(mLocationLat, mLocationLong);
        mMap.addMarker(new MarkerOptions().position(pos).title("You!"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(pos));
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(pos, 18.00f));
    }

    @Override
    protected void onResume() {
        super.onResume();
        //startLocationUpdate();
         requestLocationUpdate();
    }

    @Override
    protected void onPause() {
        super.onPause();

        if(mFusedLocationClient != null){

            mFusedLocationClient.removeLocationUpdates(mLocationCallback);
            Toast.makeText(MapsActivity.this, "Listener is removed.", Toast.LENGTH_SHORT).show();
        }
    }

    private void requestLocationUpdate(){
        mLocationSettingsBuilder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
        client = LocationServices.getSettingsClient(MapsActivity.this);

        task = client.checkLocationSettings(mLocationSettingsBuilder.build());

        task.addOnSuccessListener(MapsActivity.this, new OnSuccessListener<LocationSettingsResponse>() {
            @Override
            public void onSuccess(LocationSettingsResponse locationSettingsResponse) {

                startLocationUpdate();
            }
        });

        task.addOnFailureListener(MapsActivity.this, new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {

                if(e instanceof ResolvableApiException){
                    try{

                        ResolvableApiException resolvable = (ResolvableApiException) e;
                        resolvable.startResolutionForResult(MapsActivity.this, REQUEST_CHECK_SETTINGS);

                    }catch(IntentSender.SendIntentException sendEx) {

                    }
                }
            }
        });
    }

    private void setLocationRequestSettings(){

        mLocationRequest = LocationRequest.create();
        mLocationRequest.setInterval(3000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    private void startLocationUpdate(){
            // Here, thisActivity is the current activity
            if (ContextCompat.checkSelfPermission(MapsActivity.this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {

                if (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this,
                        Manifest.permission.ACCESS_FINE_LOCATION)) {

                    showExplanation();

                } else {
                    ActivityCompat.requestPermissions(MapsActivity.this,
                            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                            0);

                }
            } else {

                mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null);
                Toast.makeText(MapsActivity.this, "Location permission was granted!", Toast.LENGTH_SHORT).show();
            }
        }

    private void showExplanation(){
        AlertDialog.Builder builder = new AlertDialog.Builder(MapsActivity.this);

        builder.setTitle("Requires Location Permission.");
        builder.setMessage("This app needs location permission to get the location information.");
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                ActivityCompat.requestPermissions(MapsActivity.this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        0);
            }
        });

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Toast.makeText(MapsActivity.this, "Sorry, this function cannot be used until permission is granted.",Toast.LENGTH_SHORT).show();
            }
        });
        builder.show();
    }
}
Parth Lotia
  • 753
  • 1
  • 7
  • 25
HeatKai C
  • 65
  • 1
  • 9

1 Answers1

1

you should use the callback method onLocationChanged() instead of getLastKnownLocation (). Indeed, getLastKnownLocation() can return null (see here)

I prefer to use onLocationChanged() that is called once a location change is detected. It turns out that it works great for me.

If you have any trouble to implement a LocationListener, take a look at this post : https://stackoverflow.com/a/42218626/3780625

Best

Maxouille
  • 2,729
  • 2
  • 19
  • 42