I'm wondering why my app still finds location although the GPS is disabled. So I asked myselft why this is possible and I have too less knowledge about this. Maybe the NETWORK_PROVIDER needs no GPS?
I promise, GPS is really disabled.
Can anyone tell me how this is possible?
I have this in my App:
in oncreate():
locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
Method:
public void getGpsLocation(){
locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, myLocationListener, this.getMainLooper());
}
Listener:
LocationListener myLocationListener = new LocationListener() {
// When location has changed
public void onLocationChanged(Location location) {
locationManager.removeUpdates(this);
locationAll = location;
// positionOnceFound = true --> location was already found and no further update necessary
//if (location != null && positionOnceFound == false)
if (location != null)
{
// location is found, no more update necessary --> true
positionOnceFound = true;
// get Lat/Lon of my current position
myPosLat = location.getLatitude();
myPosLon = location.getLongitude();
// For calculating the point B(right top corner) and point C(left bottom corner
// Lat/Lon of B and C needed for getting the prices from this area around my position
double dy = 5.0 / 110.54; // 5.0 -> 5km to vertical
double dx = 5.0 / (111.320 * Math.cos(myPosLat / 180 * Math.PI)); // 5km to horizontal
// Get point B
rightTopCornerLon = myPosLon + dx;
rightTopCornerLat = myPosLat + dy;
// Get point C
leftBottomCornerLon = myPosLon - dx;
leftBottomCornerLat = myPosLat - dy;
System.out.println("Alat: " + myPosLat + " Alon: " + myPosLon + " Blat: " + rightTopCornerLat + " Blon: " + rightTopCornerLon +
" Clat: " + leftBottomCornerLat + " Clon: " + leftBottomCornerLon);
getCityName(isItStartOrStop);
}
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
The network provider requires the permission of ACCESS_COARSE_LOCATION, so it will work and provide you location updates using the WIFI networks, or Mobile networks, this may not be so accurate but is faster than getting a location update using the GPS.
Yes, NETWORK_PROVIDER needs no GPS, but NETWORK_PROVIDER fetches location with low precision by wireless network site.
Yes, NETWORK_PROVIDER doesn't requires GPS.
Network provider access you location through Wireless network if GPS is not enabled but it is not accurate location. Enabling GPS will provide you with more accurate location results.
The access coarse location and access fine location permissions in you meanifeast file differentiate it. With access coarse location you will get location without GPS but fine location can access GPS location too
NETWORK_PROVIDER works with both permissions
Related
So I am having this problem - the below code is part of a class in my app.
Now, this class gives me coordinates that are ABOUT right to my location. Always a few 100 meters away from where I really should be. Why is this happening? Is this maybe because I dont ask for a "fine" accuracy?
THANKS :)
public void OnLocationChanged(Location location)
{
_currentLocation = location;
{
// this is needed for my mocked location
GlobalElapsedRealTime = _currentLocation.ElapsedRealtimeNanos;
GlobalLatitude = _currentLocation.Latitude;
GlobalLongitude = _currentLocation.Longitude;
// Log.Debug("2", "Your Real Location is at " + GlobalLongitude + " // " + GlobalLatitude);
}
}
public void InitializeLocationManager()
{
_locationManager = ctxt.GetSystemService(Context.LocationService) as LocationManager;
if (_locationManager.AllProviders.Contains(LocationManager.NetworkProvider)
&& _locationManager.IsProviderEnabled(LocationManager.NetworkProvider))
{
_locationProvider = LocationManager.NetworkProvider;
Log.Debug("1", "Location Manager has been initialized!");
}
else
{
_locationProvider = String.Empty;
}
}
public void StartLocationUpdates()
{
_locationManager.RequestLocationUpdates(_locationProvider, 0, 0, this);
}
It's because you are using the LocationManager.NetworkProvider. This guesses your location based of cell towers and known WiFi hotspots and is not particularly accurate. Being a few hundred meters out sounds about right. Useful for working out which city or suburb you are in maybe but not for more accurate tracking.
Try using LocationManager.GPSProvider and make sure the ACCESS_FINE_LOCATION permission is enabled. It may take a bit longer to get a fix but it'll be much more accurate. How accurate depends on the device it's run on (phone GPS can be pretty good but not totally accurate as the chips are usually chosen based off price), and how much of a fix you can get - tall buildings can interfere with it for example.
More details:
https://developer.android.com/reference/android/location/LocationManager.html#GPS_PROVIDER
I am new to android, can anyone help me for my question.... How to get current Location and getting the registered user's location available within 3km or 5km distance??????
It's like a Find Taxi to show the user location nearby the taxi available.
I can get current location by using this code.
// Getting LocationManager object from System Service LOCATION_SERVICE
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
// Creating a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Getting the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location From GPS
Location location = locationManager.getLastKnownLocation(provider);
if(location!=null){
onLocationChanged(location);
}
locationManager.requestLocationUpdates(provider, 20000, 0, this);
final LatLng latLng = new LatLng(mLatitude, mLongitude);
Toast.makeText(MainActivity.this, " "+latLng, Toast.LENGTH_SHORT).show();
#Override
public void onLocationChanged(Location location) {
mLatitude = location.getLatitude();
mLongitude = location.getLongitude();
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
Use the distanceBetween method as it sounds like you already have the coordinates and that's all you need with this method:
Location.distanceBetween() Javadoc
This link might be helpful to you, as it details the use of the Haversine formula to calculate the distance.
Excerpt:
This script [in Javascript] calculates great-circle distances between the two points – that is, the shortest distance over the earth’s surface – using the ‘Haversine’ formula.
Use geocoder.getFromLocationName, you get back a list of Address objects, in those objects you will find all the information you need about the location.
To test this on the simulator you need an image with the Google APIs included. In a device should be fine if you have the market installed.
There are two steps to this:
Get the current location - latitude & longitude, using the GPS, network, last-known location etc. The Android location documentation includes sample code.
Use the Android Geocoder class to request a lookup to convert the lat/long to an Address (from which you can easily extract city, country, street, etc). Specifically, you need to use the getFromLocation() method
I am trying to get my current coordinates with network provider and not gps provider.
I was able to figure out the solution for that but I am a bit confused with the concept in this scenario.
Working Code
Here's my code for getting my coordinates:
public void getLocation(){
locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
if(appUtils.isOnline()){
try{
Geocoder geocoder = new Geocoder(
MainActivity.this.getApplicationContext(),
Locale.getDefault());
Location locationNetwork = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
List<Address> list;
if(locationNetwork!=null){
Toast.makeText(context,"Network Available!!",Toast.LENGTH_LONG).show();
list = geocoder.getFromLocation(locationNetwork.getLatitude(),locationNetwork.getLongitude(),3);
if(list!=null&&list.size()>0){
latitude = list.get(0).getLatitude();
longitude = list.get(0).getLongitude();
Toast.makeText(context,String.valueOf(latitude) + " (....) " + String.valueOf(longitude),Toast.LENGTH_LONG).show();
int count = 0;
while (latitude==null||longitude==null){
latitude = list.get(count).getLatitude();
longitude = list.get(count).getLongitude();
count++;
Toast.makeText(context,String.valueOf(latitude) + " --- " + String.valueOf(longitude),Toast.LENGTH_LONG).show();
}
}
}else{
Toast.makeText(context,"No response!!",Toast.LENGTH_LONG).show();
}
}catch (IOException e){
e.printStackTrace();
}
}else{
Toast.makeText(context,"Server not responding",Toast.LENGTH_LONG).show();
}
}
This piece of code is working perfectly fine when the gps is enabled. If gps is disabled, it doesn't work.
Now, if we are setting the location to NETWORK_PROVIDER:
Location locationNetwork = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Why do we still require gps ?
Now if I change it to PASSIVE PROVIDER:
Location locationNetwork = locationManager
.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
It works fine with the passive provider. Why is it that ?
Can someone explain what is the major difference here and what would be the right way to get the coordinates with network provider ?
I know this question is been asked several times and I did went through it. I just want to get cleared with this concept.
Thank's in advance.. :)
It doesn't require GPS to use the network provider, I've done it many times. However, getLastKnowLocation may not return a value if either it has never had an app request updates for that provider, or if the last time that happened was too long ago. You cannot count on that function always returning non-NULL. If you want to ensure that you get a location, use requestSingleUpdate instead. This will always get you a location (assuming the provider you use is enabled), but may take some time- a result may not be immediately available.
(There is one other time that function may never return- if you use the GPS provider and it can't get a lock on enough sattelites to find a location. Such as if you're in an underground parking garage).
This is the bit of code that I use to quickly get the current location, by checking all available network options.
private double[] getGPS(){
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
List<String> providers = lm.getProviders(true);
/* Loop over the array backwards, and if you get an accurate location, then break out the loop*/
Location l = null;
for (int i=providers.size()-1; i>=0; i--) {
l = lm.getLastKnownLocation(providers.get(i));
if (l != null) break;
}
double[] gps = new double[2];
if (l != null) {
gps[0] = l.getLatitude();
gps[1] = l.getLongitude();
}
return gps;
}
This is my code to register network provider
netlocationListener = new MynetLocationListener();
locationMangaer.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,interval,mttravel,
netlocationListener);
/*----------Listener class to get coordinates ------------- */
private class MynetLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
Toast.makeText(getBaseContext(), "accuracy & network provider"+loc.getAccuracy(),Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), "location changed", Toast.LENGTH_LONG).show();
CharSequence time1=android.text.format.DateFormat.format("MM-dd-yyyy hh:mm:ss", new java.util.Date());
.LENGTH_LONG).show();
String date =time1.toString();
float tsp= 0;
Toast.makeText(getBaseContext(),"Location changed : Lat: " + loc.getLatitude()
+ " Lng: " + loc.getLongitude(),Toast.LENGTH_SHORT).show();
String longitude = Double.toString(loc.getLongitude());
Log.v(TAG, longitude);
String latitude =Double.toString( loc.getLatitude());
Log.v(TAG, latitude);
/*----------to get City-Name from coordinates ------------- */
String cityName=null;
Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
List<Address> addresses = null;
try {
addresses = gcd.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
if (addresses.size() > 0)
// System.out.println(addresses.get(0).getLocality());
cityName=addresses.get(0).getLocality();
} catch (IOException e) {
e.printStackTrace();
}
String accuracy=Float.toString( loc.getAccuracy());
String s = longitude+"\n"+latitude +"\n\nMy Currrent City is: "+cityName + "accuracy"
+ accuracy + "speed"+loc.getSpeed();
}
It shows true -
Toast.makeText(getBaseContext(), Boolean.toString(locationMangaer.isProviderEnabled(LocationManager.NETWORK_PROVIDER)), Toast.LENGTH_LONG).show();
If I change provider to GPS then it works perfectly but I need to get location from network provider. I checked working with internet, wifi but still no result.
Its not even entering the onlocationchanged().
For network based location, they are a lot less inaccurate than GPS, meaning you need to move the device a much larger distance to allow the signal to hook on to another network tower before
onLocationChanged() is called. Also not all network towers provide location.
I don't see where you're initializing the location manager. I'd guess you're not getting messages using network location because you're not moving enough to trigger an location change. Network position is not very accurate. I've seen network positioning be over 100ft off, and would hazard a guess that your device has a hundred foot "error radius" that you will have to move outside of to get a location update.
I've cut-n-pasted my code below, you're mileage may vary.
// see if this line gives you what you want
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// get location via network
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
// get location via GPS
//locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Following is the code which i am using to find the latitude longitude and location of a place in my app, but it always show no location found
I have added the permissions in manifest file
{
LocationManager locManager;
setContentView(R.layout.main);
locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000L,500.0f, locationListener);
Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null)
{
String param = (String)locManager.getProviders(true).get(0);
Location loc = locManager.getLastKnownLocation(param);
double latitude = location.getLatitude();
double longitude = location.getLongitude();
}
}
private void updateWithNewLocation(Location location)
{
TextView myLocationText = (TextView)findViewById(R.id.widget52);
String latLongString = " ";
if (location != null)
{
double lat = location.getLatitude();
double lng = location.getLongitude();
latLongString = "Lat:" + lat + "\nLong:" + lng;
}
else
{
latLongString = "No location found";
}
myLocationText.setText("Your Current Position is:\n" +
latLongString);
}
private final LocationListener locationListener = new LocationListener()
{
public void onLocationChanged(Location location)
{
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider)
{
updateWithNewLocation(null);
}
public void onProviderEnabled(String provider)
{
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
};
}
pls help me...
I've put your code in an Android project and ran it on the emulator and it seems to be working fine.
I would change the code to first check for a lastknown location, and after that check for location updates.
Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
If that location is null, or too stale (timestamp) for your needs, you can start requesting location updates. (currently, you're first requesting location updates from the GPS, and then decide to retrieve its lastknownlocation). This might cause the location manager to stop querying the GPS.
Also you need to ensure the following is in place :
For GPS Provider, make sure the following permission is put in the manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Ensure the GPS is turned on that you have sufficient GPS coverage.
Do this by checking for the GPS icon in your Notification bar
Test on a real device
Although testing GPS location listeners works partly through the emulator, the behavior of an actual device will always be different.
Debug on the emulator
Basic GPS testing can be done using the emulator. Put a breakpoint in your locationlistener, and use the DDMS perspective to send some GPS coordinates to your AVD image.
#Siva, your problem is with the UI thread, as your updates are from different thread.
To verify if this is the UI problem, put a toast or Log cat the message when you receive an update.
Once you know that UI problem, then try using Handler to postInvalidate() the UI.