In my application, I tried to search the coarse location of the android device using the networkProvider. I only use the networkProvider in my location manager, but it won't work if I don't turn on the GPS sensor on.
Is the networkprovider supposed to give a coarse location no matter the GPS sensor is on or off?
Here's my code.
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
if(isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
Log.e("Network","suc");
else
Log.e("Network", "fail");
if (!isNetworkEnabled) {
} else {
this.isGetLocation = true;
if (isNetworkEnabled) {
Log.e("GpsInfo", "isNetworkEnabled true");
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
Log.e("GpsInfoClass", "Location manager not NULL");
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
lat = location.getLatitude();
lon = location.getLongitude();
Log.e("GpsInfoClass", lon + ", " + lat );
}else{
Log.e("GpsInfoClass", "Location NULL");
}
}else{
Log.e("GpsInfo", "Location Manager is null");
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
In my log, it prints Network(tag) fail(log).
What this mean is that,
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
always returns false, if the GPS sensor is off. Why is this happening? What am I missing about getting coarse locations?
Is the networkprovider supposed to give a coarse location no matter the GPS sensor is on or off?
No, the GPS radio has nothing to do with getting Network Location.
However, you need to have your Location Settings set to either Power Saving or High Accuracy.
Using this code to show a Toast with the current enabled providers:
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Toast.makeText(context, "GPS Enabled: " + isGpsEnabled + " Network Location Enabled: " + isNetworkEnabled, Toast.LENGTH_LONG).show();
Here is what it shows for GPS only and Power Saving:
So, you can see that this call:
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Returns false for the GPS Only setting, since that disables Network Location.
And, it returns true for the Power Saving setting.
It would also return true for High Accuracy as well, since that enables both GPS and Network Location.
GPS sensor only needed for exact location. If you create a Criteria and give it to locationManager, system automatically selects best provider and tries get coordinates.
Example;
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria locationMode = new Criteria();
locationMode.setBearingRequired(false);
locationMode.setSpeedRequired(true);
locationMode.setAccuracy(Criteria.ACCURACY_MEDIUM);
locationManager.requestSingleUpdate(locationMode, new LocationListener() {#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}, null);
}
Related
I have followed this tutorial http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial/ for showing popup if GPS in not enabled and getting users current location.
And here is the broadcast receiver which listens to the GPS enabled disabled condition
private BroadcastReceiver mGpsSwitchStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
gps = new GPSTracker(getActivity());
if(gps.canGetLocation()){
Log.d("Your Location", "latitude:" + gps.getLatitude() + ", longitude: " + gps.getLongitude());
Toast.makeText(getActivity(), "GPS Switch", Toast.LENGTH_SHORT).show();
if(gps.getLatitude() != 0 && gps.getLongitude() != 0 ){
final CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(gps.getLatitude(),gps.getLongitude())) // Sets the center of the map to selected place
.zoom(15) // Sets the zoom
.build(); //
gMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
Toast.makeText(getActivity(), "GPS Switch Lat: "+gps.getLatitude()+" Long: "+gps.getLongitude(), Toast.LENGTH_SHORT).show();
}
} else {
if(!gps.isSettingDialogShown())
gps.showSettingsAlert();
}
}
}
};
When I enable the GPS via settings dialog or from drop down menu. GPSTracker class gets the location service and checks for the user's current location in this code fragment
public Location getLocation() {
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network Enabled");
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS", "GPS Enabled");
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (SecurityException e) {
e.printStackTrace();
}
return location;
}
Problem:
Firstly I don't know why broadcast receiver, receives the action two times and secondly when in normal mode lat lng value in receiver remains zero but in debugging sometimes it returns the value of users current location.
Can you please help what I am doing wrong?
If you don't need to work with Gps and Network Locations separately. I recommend to use FusedLocationProvider. BroadcastReceiver is probably working twice because it works for both gps and network location services
I'm writing a GPS Tracker which I use for getting the location of the device every minute. I use both GPS_PROVIDER and NET_PROVIDER to get the location, but sometimes, the location is not getting updated even though I'm moving the device for a long time.
So I'm thinking:
If the location is not changing for a period of time with a certain provider, switch to another provider and check for new location again.
Is this correct?
Here's my getLocation code:
public Location getLocation(Context context) {
this.mContext = context;
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled) {
// no network provider is enabled
this.canGetLocation = false;
Log.d("DMCAILOCATION","DMCAILOCATION: can not get location");
} else {
this.canGetLocation = true;
//=======================
Location location=null;
Location locationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location locationNet = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Log.d("DMCAILOCATION","DMCAILOCATION: locationGPS:"+locationGPS + "locationNet:"+ locationNet );
if ( locationGPS != null ) {
location= locationGPS;
latitude = location.getLatitude();
longitude = location.getLongitude();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
getLocationnet();
Log.d("DMCAILOCATION","DMCAILOCATION: get by gps");
}
else {
location= locationNet; locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
latitude = location.getLatitude();
longitude = location.getLongitude();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
getLocationgps();
Log.d("DMCAILOCATION","DMCAILOCATION: get by net");
}
Log.i("DMCAILOCATION","NetLocationTime:" + locationNet.getTime() + "locationGPS.getTime(): " +locationGPS.getTime());
Log.d("DMCAILOCATION","DMCAILOCATION: LAT: "+latitude+", "+longitude);
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
I have a Service which is running every minute and is supposed to constantly track location. The Service implements LocationListener. I feel like I'm not understanding this correctly though because I'm not actually using the LocationListener methods:
onLocationChanged
onProviderEnabled
onProviderDisabled
etc
I have those methods in my Class but I don't actually do anything with them. All I'm doing is every time my service runs I call LocationManager.getLastKnownLocation for both GPS and Network Provider depending on which ones are available.
This is what my code looks like:
Service runs every minute:
Intent i = new Intent(context, GPSTracker.class);
PendingIntent pi = PendingIntent.getService(context, 0, i, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if(isOn) {
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), POLL_INTERVAL, pi);
} else {
alarmManager.cancel(pi);
pi.cancel();
}
I handle the Intent:
protected void onHandleIntent(Intent intent) {
Log.i(TAG, "In onHandleIntent!");
Location currentLocation = getLocation(this);
if(currentLocation == null) {
saveLocation(-8.0, -8.0, "nothing", "nothing", "nothing");
} else {
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(this, Locale.getDefault());
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1);
String city = addresses.get(0).getLocality();
String country = addresses.get(0).getCountryCode();
String state = addresses.get(0).getAdminArea();
saveLocation(currentLocation.getLatitude(), currentLocation.getLongitude(), city, state, country);
} catch (IOException e) {
e.printStackTrace();
}
}
}
And getLocation() does the real work:
public Location getLocation(Context context) {
try {
locationManager = (LocationManager) context
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
Something doesn't seem right though. For one, like I said I don't use any LocationListener methods, and also it doesn't seem to be very accurate. When I test on my phone sitting at my computer desk it gets it spot on every time. However, today I had this running on my phone once at work and another time when I was walking down the street and the locations it got for these places was like a mile away from both of them. Weirdly, it got the exact same wrong location for both of these places. These were both with Network providers as I didn't have my GPS on.
What am I doing wrong, and if I'm not doing anything wrong, how can I get this to be more accurate?
getLastKnownLocation () will provide the last known location(not the current location).The location could be out-of-date, if the device was turned off and moved to another location.
You need to use LocationClient to get the current location using Google Location Service. It simple to integrate. You need to create a instance to LocationClient and connect. There are callback method when the connection is established.Once connected you can retrieve the current location from mLocationClient.getLastLocation() (Returns the best most recent location currently available).
check this link https://developer.android.com/training/location/retrieve-current.html
As your concern is to get more accurate result then you should use GPS. You can simply add a GPS enable button to ask the user for turning on the GPS.
gpsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
isGpsON = true;
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
});
You didn't use any LocationListener but I think you should use that to take the location update on
#Override
public void onProviderEnabled(String provider) {
getLocation(this);
}
I am getting my current location in the form of latitudes and longitudes. My problem is that once I get the coordinates it doesn't get updated when I move to another location.I think onLocationChanged method is not getting called. I read here http://www.lengrand.fr/2013/10/onlocationchanged-is-never-called-on-android/ that it doesn't get called by itself. I have gone through most of the tutorials and can't find a solution.So how can I call onLocationChanged method in my service. Please suggest me step by step.
My codes are as follow:
public class GPSTracker extends Service implements LocationListener {
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
}
#Override
public void onLocationChanged(Location location) {
getLocation();
}
Make sure you requestLocationUpdates(...) from the LocationManager (which in your case it seems you do)
If your inside a building and your device doesn't get GPS fix onLocationChanged(...) is not called, I had the same issue (when debugging in my home) but going outside I saw that the function is called once GPS fix is retrieved.
try
#Override
public void onLocationChanged(Location location)
{
Toast.makeText(getApplicationContext(), "My Position !!!"+ location.getLatitude + location.getLongitude,
Toast.LENGTH_LONG).show();
}
It is weird that you are even getting a single location update. From you code it looks like you call getLocation() when you recieve a location change, but you then only setup your location requests inside of the getLocation() function (i.e. you should never enter the getLocation() function). This is how I implemented a location listener for gps data:
Note: I used this in a service, but I did not have my service implement LocationListener.
private void setupLocationUpdates() {
// Acquire a reference to the system Location Manager
mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
mLocationListener = new LocationListener() {
// Called when the location has changed.
public void onLocationChanged(Location location) {
mLocation = location;
}
}
// Called when the provider is disabled by the user.
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "Status Changed: " + String.valueOf(status) + " Provider:" + provider);
}
// Called when the provider is enabled by the user.
public void onProviderEnabled(String provider) {
if(provider.equalsIgnoreCase("gps")) setNotification(Constants.GPS_ENABLED);
Log.d(TAG, "Provider: " + provider + " ENABLED");
}
// Called when the provider status changes.
public void onProviderDisabled(String provider) {
if(provider.equalsIgnoreCase("gps")) setNotification(Constants.GPS_DISABLED);
Log.d(TAG, "Provider: " + provider + " DISABLED");
}
};
mlocationProvider = LocationManager.GPS_PROVIDER;
// Register for location updates
mLocationManager.requestLocationUpdates(mlocationProvider, 0, 0, mLocationListener);
// Add a GPS Listener to notify when searching for signal and when fix is acquired
mGpsListener = new GpsListener();
mLocationManager.addGpsStatusListener(mGpsListener);
}
in my app I am able to use the GPS but the problem is that it always getting me the same location. Everytime I am retrieving the location from that on, it gives me the same value. First time it was fetched and I was online, wirelessly. Then i went out with only the GPS and even if I was a mile away location was the same. I enabled 3g and still the same.
I send my app to a friend of mine, he got a different first time location and then he sees the same no matter where he goes.
Here is my code:
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled) {
// System.out.println("Network enabled");
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
// System.out.println("GPS enabled");
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
#Override
public void onLocationChanged(Location location) {
// mAct.playToastMessage("Location Changed");
getLocation();
// mAct.setGPSText(location.getLatitude(),location.getLongitude());
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
In this For the parameter of MIN_TIME_BW_UPDATES and MIN_DISTANCE_CHANGE_FOR_UPDATES you have to set the 0 and 0. If it is set to 0,0. It will give you the location update as quick as possible. If you set larger value for the you never get the updated value until your condition satisfied. I hope this could solves your problem.
#Override
public void onLocationChanged(Location loc)
{
loc.getLatitude();
loc.getLongitude();
String Text = “My current location is: “ +
“Latitude = “ + loc.getLatitude() +
“Longitude = “ + loc.getLongitude();
Toast.makeText( getApplicationContext(),Text,Toast.LENGTH_SHORT).show();
}
Source : Tutorial on GPS to get Current Location.