I am using the android emulator ddms to simulate movement using a gpx file. There are about 1000 entries in the gpx file. However, I'm finding that my onLocationChanged method is only being triggered a few times during the course of the entire file. My code is as follows...
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, myListener);
myListener = new LocationListener(){
public void onLocationChanged(Location location){
double mylat = location.getLatitude();
double mylon = location.getLongitude();
...
}
...
}
My understanding of the requestLocationUpdates being set to 1000 is that it should request a location update every 1 second provided the location is more than 1m away from the previous. Is this correct? If so, why would I only be retrieving a few of the lat/lon pairs from the gpx file? Wouldn't I be retrieving nearly a thousand? (The GPS data is from someone running so there is constant motion.)
I haven't had very good luck with using the emulator locations using gpx, kml, or manually entering lat/long coordinates . In my experience, setting the location and distance minimums in requestLocationUpdates does work well on real hardware but not in the emulator.
If using the gpx file is just for testing purposes, try setting the time and location constraints to 0 and 0 just to see if it now registers all 1000 of your points within the emulator.
Related
I have an app that pinpoints the users location on a map. This runs successfully on both my Nexus 4 & 5, but will no longer work on my Nexus 7.
It did run on the 7, but then the device powered off during execution, and now the app will no longer work.
I have reset the device back to factory and have run all updates on it.
Here is the code from my onCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
map.setMyLocationEnabled(true);
Criteria criteria = new Criteria();
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
double lat = location.getLatitude();
double lng = location.getLongitude();
LatLng coordinate = new LatLng(lat, lng);
CameraUpdate center = CameraUpdateFactory.newLatLng(coordinate);
CameraUpdate zoom=CameraUpdateFactory.zoomTo(16);
map.moveCamera(center);
map.animateCamera(zoom);
}
It says that I am getting a NullPointerException at ** ** double lat = location.getLatitude();
I could understand an issue if it would happen on all my devices, but I can't wrap my head around why just this one device (and especially after it worked earlier)?
Per the getLastKnownLocation documentation:
If the provider is currently disabled, null is returned.
as you are using getBestProvider(criteria, false) you are saying you allow providers that are not enabled (that's what false means) - switch it to true if you only want to look at enabled providers (which will assure that getLastKnownLocation does not return null).
Note that the getLastKnownLocation could be very out of date and you may still want to look for location updates if you need to get a recent location.
There are a couple things to keep in mind when deling with gsp or network location.
*- The data takes time to arrive to your device: yes , it may take even 1 minute to recive the device 's current location. Thats why you should use a LocationListener
*-May sounds crazy but verify your smartphone is connectecd to the internet
I have a timer that runs every second. Every second I get the GPS location and do other stuffs.
I am wondering which way is better:
1- Request a single location update and then get the last known location
private void timeout(){
String data[] =new String[DATA_LENGTH];
locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, this, null);
Location loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
.
.
.
}
2- Start Location listener and then just get the last known location whenever my timer expire
OnCreate(){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
private void timeout(){
String data[] =new String[DATA_LENGTH];
Location loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
.
.
.
}
Thank you
PS: Note that battery is not a concern to me as per the requirement of the product
requestSingleUpdate is meant to be single, if you need to query the GPS frequently you should definitely go with option 2.
Keep a global Location object in memory, use it in you other stuff and update it whenever your listener gets an update from the LocationManager.
You can listen for changes via requestLocationUpdates - the code below is a quick-n-dirty example (untested). Remember, you have to have location services turned on to use this.
LocationListener locGPSListener= new LocationListener() {...}
LocationListener locNetworkListener= new LocationListener() {...}
mgr = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// listens using GPS for location
mgr .requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locGPSListener);
// uses towers for location
mgr .requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locNetworkListener);
...
What approach is better, depends on
Androids GPS behaviour and
your Application.
ad 1. if explicitly getting a location delivers a more recent fix, than this is an advantage, because:
ad 2. if your application don't want the android filtering behaviour, and you can filter it yourself better, then this would be better for your app.
Example: (is for ios, but may apply here too:) if I drive with my car to a traffic signal, and do a harsh breaking, then ios still shows 5 km/h speed, although I am standing still. This I call unwanted filtering.
This has all nothing to do with battery: if you get the location via message or if you query it is the same from battery point of view. It smore a software design issue: (events vs. polling)
A difference would only be if GPS is disabled, but disabling GPS makes only sense if it can be disabled for long time.
I have used the code below and everything is working fine except that onLocationChanged is called even if I am sitting at the same location .
I thought it should be called only when I am moving right ?
I only want to get the location after I have moved a certain distance.
Please help me out.
Thanks in advance.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
locationMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationMgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
this);
}
#Override
public void onLocationChanged(Location location) {
Toast.makeText(this, "Working!", Toast.LENGTH_SHORT).show();
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
String Text = "Latitud = " + lat + "\nLongitud = " +
lng;
Toast.makeText(getBaseContext(),Text,Toast.LENGTH_SHORT).show();
}
}
You're requesting location updates at the shortest possible intervals/distances
locationMgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
this);
This is what the documentation says about those parameters
" The location update interval can be controlled using the minTime parameter. The elapsed time between location updates will never be less than minTime, although it can be more depending on the Location Provider implementation and the update interval requested by other applications. "
The minDistance parameter can also be used to control the frequency of location updates. If it is greater than 0 then the location provider will only send your application an update when the location has changed by at least minDistance meters, AND at least minTime milliseconds have passed. However it is more difficult for location providers to save power using the minDistance parameter, so minTime should be the primary tool to conserving battery life.
I personally use a minTime of 10 seconds and 10 meters for my app
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000,
10, locationListener);
Network location is not as precise as you would think it is. Therefore the result returned by the sensors can fluctuate. This is even more true when you consider that GPS signal weakens if you don't have direct line of sight with the satellites, and the number of visible satellites also has effect on the precision. This gets even worse when you start using the network provider, where the position is calculated by triangulation of the signal strength of cell towers, and the number and SSIDs of visible wireless network. Since these can fluctuate quite a lot, the precision suffers greatly. There are bunch of averaging algorithms, and heuristics employed to minimize such fluctuations, but ultimately nothing can stabilize it to be as good as you expect it to be.
A simple averaging and variation filtering can help you. Adding a correction based on the device accelerometer can also help a lot, but it will make your code more complex.
I am developing an application in android and I want to get the latitude and longitude of the android mobile. My code for getting latitude and longitude is giving values after some time. And sometimes, it doesn't give values at all. Can anyone help me what can be done!
You need to add this code for getting te current location. make sure you give all the permissions
Location Manager location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location!=null)
{
latitude = location.getLatitude();
longitude = location.getLongitude();
}
Please used last know location from your location service provider if you not get latest because
When your application is not running at that time some other application used location manager to get current location.
then once you start your application with location manager,what happen location manager basically take some time to prepare to send current location so at that time you have to get last know location from location provider,for that you have to design service in such way.
once the location manager is stable then used those location.
this is best way.
Thank you
Bhavdip
One quicker way would be to get the last known location getLastKnownLocation()
and check if the time of this location is not far location.getTime(). Or use it until you get the real location.
Another tip is to use both GPS_PROVIDER and NETWORK_PROVIDER so your code will be like this :
LocationManager locManager;
locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
/*call both providers , the quickest one will call the listener and in the listener you remove the locationUpdates*/
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0 ,0 , locationListener);
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0 ,0 , locationListener);
Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
/*check both providers even for lastKnownLocation*/
if (location == null)
{
location = locManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
if(location != null) {
String lat = String.valueOf(location.getLatitude());
v1.setText(lat);
String longi = String.valueOf(location.getLatitude());
v2.setText(longi);
}
this is a simple example, a more elaborate solution would compare the newest lastKnownLocation between providers.
I created a program that displays a mapView, with the location of the phone, and the ability to send this location (latitude, longitude) through email. (to add some places to a database).
I'm using the LocationManager class and getLatitude / getLongitude methods to get the phone's location. My code looks like this:
double MyLongitude = 0;
double MyLatitude = 0;
Location location = null;
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 35000, 10, new ShowLocation());
location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
MyLatitude = location.getLatitude();
MyLongitude = location.getLongitude();
When test my application on the emulator, everything is OK: mapView displays the location I fixed (using telnet and geo fix command), and I can send the location through email. I get the same result on the phone of a friend; everything seems to work OK.
The problem is on my phone. I can display my location on the mapView (the little blue circle), but when I try to send my location through email, the Latitude and Longitude were both set to 0.
Here is the code to display my location on the mapView:
MyLocationOverlay myLocation = new MyLocationOverlay(this, mapView);
myLocation.enableMyLocation();
I don't understand why my location appears to work when displayed, but I can't get the correct latitude and longitude, while it seems to work on emulator and my friend's phone.
Is this due to missing code or something like that? Is this a problem with my phone? I checked the permissions, and I already have the needed ones:
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_MOCK_LOCATION
I also tried to test with LocationManager.NETWORK_PROVIDER instead of LocationManager.GPS_PROVIDER, but got the same result.
You can override onLoationChanged(Location l) on your MyLocationOverlay, which will get called whenever the overlay gets a new location to draw your position, instead of requesting location updates and getLastKnownLocation.
I am guessing that getLastKnownLocation is returning 0, 0 because there hasn't been a location fix yet.