1

I have a simple App which currently simply asks for necessary permissions and in case GPS is OFF, you get an AlertDialog asking you if you want to switch it ON. After accepting, being taken to GPS options, enabling it, and going back to my App, I'd like to update location and here I get lost.

In other words, I'm trying to do what's stated here: https://stackoverflow.com/a/43396965/7060082

Unfortunately I can't manage to get it done and the example is a bit complicated for me to understand. Here is a piece of my code showing the relevant bits:

    private void checkGPS() {
        manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(R.string.GPS_error)
                    .setCancelable(false)
                    .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                        public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                            Intent gps = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                            startActivityForResult(gps, 1);
                            getLatLon();
                        }
                    })
                    .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() {
                        public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                            dialog.cancel();
                        }
                    });
            final AlertDialog alert = builder.create();
            alert.show();
        } else {
            getLatLon();
        }

    }

    private void getLatLon() {
        //manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        String provider = manager.getBestProvider(criteria, false);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            manager.getLastKnownLocation(provider);

            if (location != null) {
                Toast.makeText(this, "This is my location: " + location.getLongitude() + ", " + location.getLatitude(), Toast.LENGTH_SHORT).show();

            } else {
               // manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
                manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);


                //location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

                /*
                double longitude = location.getLongitude();
                double latitude = location.getLatitude();
                Toast.makeText(this, "This is my location: " + longitude + ", " + latitude, Toast.LENGTH_SHORT).show();
            */
            }
        }
    }

    @Override
    public void onLocationChanged(Location l) {
        location = l;
        double longitude = location.getLongitude();
        double latitude = location.getLatitude();
        Toast.makeText(this, "This is my location: " + longitude + ", " + latitude, Toast.LENGTH_SHORT).show();

    }

After asking for ACCESS_FINE_LOCATION permission (which is also stated on the manifest) I call checkGPS(). As said before, let's you enable or not the GPS. If enabled, I call getLatLon(). If there is a lastKnownLocation, good, if not...

Here I get lost. I call requestLocationUpdates and then do nothing waiting for onLocationChanged to recieve a location update and execute the rest of the code. Am I doing it right? The result is me clicking the button, switching GPS on. Click on the button again and nothing happens.

Any help with this will help. Many thanks for your time.

Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
afarre
  • 512
  • 6
  • 18

3 Answers3

1

I've developed fused location api demo application and utility pack here.

General Utilities

Try it if useful for you. To get location using fused location api, you just have to write following snippet...

new LocationHandler(this)
    .setLocationListener(new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        // Get the best known location
    }
}).start();

And if you want to customise it, simply find documentation here...

https://github.com/abhishek-tm/general-utilities-android/wiki/Location-Handler

I've written a sample code according to your need, this will handle GPS enable/disable dialog internally, try this one...

import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;

import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;

import in.teramatrix.utilities.service.LocationHandler;
import in.teramatrix.utilities.util.MapUtils;

/**
 * Lets see how to use utilities module by implementing location listener.
 *
 * @author Khan
 */

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, LocationListener {

    private GoogleMap map;
    private Marker marker;
    private LocationHandler locationHandler;

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

        // Obtaining an instance of map
        FragmentManager manager = getSupportFragmentManager();
        SupportMapFragment mapFragment = (SupportMapFragment) manager.findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        this.locationHandler = new LocationHandler(this)
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(5000)
                .setFastestInterval(10000)
                .setLocationListener(this);
    }

    @Override
    public void onMapReady(GoogleMap map) {
        this.map = map;
        this.locationHandler.start();
    }

    @Override
    public void onLocationChanged(Location location) {
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        if (marker == null) {
            marker = MapUtils.addMarker(map, latLng, R.drawable.ic_current_location);
            map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14), 500, null);
        } else {
            marker.setPosition(latLng);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (locationHandler != null) {
            locationHandler.stop();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == LocationHandler.REQUEST_LOCATION) {
            locationHandler.start();
        }
    }
}

Hope it will help you.

User
  • 4,023
  • 4
  • 37
  • 63
0

Your current code doesn't wait for the user to make a choice before calling getLatLon() in the case where GPS is disabled.

You will need to add a onActivityResult() override that will be called when the user goes back to your app.

First, remove the call to getLatLon() in the checkGPS() method for the case where GPS is disabled:

private void checkGPS() {
    manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(R.string.GPS_error)
                .setCancelable(false)
                .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                    public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                        Intent gps = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivityForResult(gps, 1);
                        //Remove this:
                        //getLatLon();
                    }
                })
                .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() {
                    public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                        dialog.cancel();
                    }
                });
        final AlertDialog alert = builder.create();
        alert.show();
    } else {
        getLatLon();
    }
}

Then, add the onActivityResult() override, check the setting again, and if it's now enabled then call getLatLon():

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        getLatLon();
    }
}
Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
0

after some time busy with other projects, got back to this one and I removed the getLatLon(); function from the checkGPS(); function and that's it, code is fine. I was using the emulator to check if this was working, but I forgot that the emulator has a fixed value for the latitude and longitude, so you get no updates like a real mobile phone, and thus it looked as if it was not working properly.

Sort of a newby mistake. Regardless, thanks for your offers. Was interesting looking at different ways of doing the same thing.

Sartox

afarre
  • 512
  • 6
  • 18