What I am trying to do:
I am trying to develop an app that only requires the user's location at the start of one activity. So only when the user is within the activity, the location gets updated either by network or GPS. Accordingly, the user may choose an indoor map.
What is my problem:
However, I find that the app is always using the history location, and never updates the location. I suspect there must be something wrong with my
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
But I am not sure where the problem is.
Related code snippet:
In my Activity
, I have:
locationDetector = new LocationDetector(MapSelectionActivity.this);
// try to get the current location
if (locationDetector.checkLocationServiceAvailability()) {
location = locationDetector.getLocation();
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
Log.d("MapSelectionActivity", latitude + " " + longitude);
//locationDetector.stopLocalization(); // stop the localization to save the energy
} else { // if no location service, requires the user to turn GPS on
locationDetector.showSettingsAlert();
}
My LocationDetector
class is as follows:
public final class LocationDetector implements LocationListener {
private final Context mContext;
private boolean isNetworkEnabled = false;
private boolean isGPSEnabled = false;
private boolean canGetLocation = false;
private Location location;
private String providerUsed;
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 0 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = (long) (1000 * 60 * 0.5); // 0.5 minute
// Declaring a Location Manager
protected LocationManager locationManager;
// constructor
public LocationDetector(Context context) {
this.mContext = context;
locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
}
// NOTE call checkLocationServiceAvailability(); first before calling this!
public Location getLocation() {
// I SUSPECT SOMETHING IS WRONG HERE
if (isNetworkEnabled) { // use network
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("LocationDetector", "Using Network");
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
providerUsed = "Network";
} else if (isGPSEnabled) { // use GPS
if (location == null) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("LocationDetector", "Using GPS");
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
}
providerUsed = "GPS";
} else { // neither the network nor the GPS is on
providerUsed = null;
Toast.makeText(mContext, "Location service is unavaliable", Toast.LENGTH_SHORT).show();
}
return location;
}
// call this to restart requesting the detecting
public void startLocalization() {
if (locationManager != null) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
}
}
// call this to stop the detecting to save power
public void stopLocalization() {
if (locationManager != null) {
locationManager.removeUpdates(LocationDetector.this);
}
}
// check location service availability
public boolean checkLocationServiceAvailability() {
// check GPS on or off
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// check Internet access
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
isNetworkEnabled = true;
} else {
isNetworkEnabled = false;
}
if (isGPSEnabled || isNetworkEnabled) {
canGetLocation = true;
} else {
canGetLocation = false;
}
return canGetLocation;
}
public String getLocationProvider() {
return providerUsed;
}
// show alert dialog to direct the users to the settings
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// make it uncancellable
alertDialog.setCancelable(false);
// Setting Dialog Title
alertDialog.setTitle("Forgot to turn GPS on?");
// Setting Dialog Message
alertDialog.setMessage("Currently there is no Internet access.\n\nLocalization requires GPS when Internet is unavailiable.\n\nDo you want to enable GPS so as to proceed?");
// On pressing Settings button
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
Toast.makeText(mContext, "After enabling GPS, press the physical 'Back' button to return", Toast.LENGTH_LONG).show();
}
});
// on pressing cancel button
alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
Toast.makeText(mContext, "No location service, please choose map manually", Toast.LENGTH_LONG).show();
}
});
// Showing Alert Message
alertDialog.show();
}
@Override
public void onLocationChanged(Location _location) {
// IT NEVER GETS CALLED
location = _location;
// update the text view
MapSelectionActivity.coordinatesTextView.setText("(" + Math.round(location.getLatitude() * 1000) / 1000.0 + ", " + Math.round(location.getLongitude() * 1000) / 1000.0 + ")");
// update the marker on Google Maps
MapSelectionActivity.googleMap.clear();
MapSelectionActivity.googleMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())).title("I am here!"));
MapSelectionActivity.googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15)); // 15 is the approporiate zooming level
// re-suggest the map
int recommendedMapSequenceNumber = MapSelectionActivity.mapDatabase.getMapSequenceNumber(location.getLatitude(), location.getLongitude());
MapSelectionActivity.recommendedMapTextView.setTextColor(Color.parseColor("red"));
if (recommendedMapSequenceNumber == -1) { // the so-called nearest is still too far
Toast.makeText(mContext, "Please manually select one to proceed", Toast.LENGTH_LONG).show();
MapSelectionActivity.recommendedMapTextView.setText("No recommended maps");
MapSelectionActivity.autoSelectButton.setEnabled(false);
} else { // suggest a map
Toast.makeText(mContext, "One suitable map found", Toast.LENGTH_SHORT).show();
MapSelectionActivity.recommendedMapTextView.setText(MapSelectionActivity.mapDatabase.getMapName(recommendedMapSequenceNumber));
}
Toast.makeText(mContext, "New location detected", Toast.LENGTH_SHORT).show();
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
I never see the Toast
in onLocationChanged()
, which means that it never gets called!
Also from the map, I can see the position is not updated.
(1000 * 60 * 0.5)
this will be actually 30 seconds, you need change it to(1000 * 60 * 5)
for 5 minutes interval, However this is not the actual problem. – DuchessGPS_PROVIDER
, because they are quite OK for theNETWORK_PROVIDER
? – Epilepticif (locationManager != null) { location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); }
and try executing your code once again. – DuchessgetLastKnownLocation(LocationManager.NETWORK_PROVIDER)
, which is never refreshed, since the prefered provider is GPS - right? – EpilepticLocationServices.FusedLocationApi
to make your requests. It should save you some time and effort. – Trentontrepan