lm.removeUpdate(ll); not releasing updates - android

I have been working for 2 days looking for this bug. I have searched stackoverflow and Android documentation with no luck.
My onLocationChanged code has a counter in it that counts how many times it has been called and if I back arrow out of the activity screen on the phone and return, the counter will go up by 2 for each update. If I back arrowing out and update the GPS, the counter records that onLocationChanged is still getting called even though the screen is in the background and onPause has been called. If I go in and out of the activity with the backarrow, I can get more than two updates per GPS input send depending on how many times the activity screen is entered.
All the GPS code works but these multiple instances can't be good and they mess up other things I am trying to do, like distance traveled between two updates.
Here is what I think is the relevant parts of my code. Obviously I left out the main part but the point is that after returning to this screen after back-arrowing out then a single send of a GPS data point increments the n variable by more than one depending on how many times I have returned to the screen.
I must be doing something obvious but I can't find it.
public class Data extends Activity {
protected LocationListener ll;
protected LocationManager lm;
static int n = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.data);
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener ll = new mylocationlistener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, ll);
}
class mylocationlistener implements LocationListener{
#Override
public void onLocationChanged(Location location) {
if (location != null){
n = n + 1;
textData.setText("\n" + n);
}
}
and
#Override
protected void onPause() {
if(lm != null) {
lm.removeUpdates(ll);
}
ll = null;
lm = null;
super.onPause();
}
The only clue I have is that if I take the lm.removeUpdates(ll) out of the if(lm != null) then the code crashes which makes me think that lm must be null and that lm.removeUpdates(ll) must not be correct but it matches the all the examples I could find as well as the Android documentation as far as I can tell.
Please help.

LocationListener ll = new mylocationlistener();
This LocationListener is local to your method onCreate().So is your LocationManager lm.So when you are removing updates its not working with the manager and listener that you declared as the class variable.
Just write as
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
ll = new mylocationlistener(); in your onCreate().

Related

Making Sure All tasks executes in onLocationChanged Method

I am doing a lot of job in onLocationChanged method, i want to lock the method until all jobs are done even if the location manager achieves it's condition.
for example i have the following code:
private LocationManager _locMgr;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_locMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
_locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 2, this);
}
public void onLocationChanged(Location location) {
//do alot of job
}
The problem i am facing that if the time in locationManager is greater than 2 seconds and greater than 2 meters it'll execute the onLocationChanged() even if there's tasks not finished.
Please somebody help me with this.
If you are sure that onLocationChanged() is called before finished, try this:
Declare an Activity field private bolean isAllDone = true;
Declare a lock object private final Object lock = new Object();
Then at onLocationChange test it:
public void onLocationChanged(Location location) {
if(isAllDone){
synchronized (lock){
if(isAllDone){
isAllDone = false;
//do alot of job
isAllDone = true;
}
}
}
}

Android: measured distance between locations is wrong

...or most probably, I am doing it wrong. What I want is to display a Toast every one meter I walk inside home. The code below gives me wrong results, as the moment I install the app on my phone I get a Toast without even moving!
public class MainActivity extends Activity {
private LocationListener mLocationListener;
private String mLocationProvider;
private LocationManager mLocationManager;
private Location mCurrentLocation;
private int mCounter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mLocationListener = new MyLocationListener();
Criteria criterion = new Criteria();
criterion.setAccuracy(Criteria.ACCURACY_FINE);
criterion.setCostAllowed(true);
criterion.setPowerRequirement(Criteria.POWER_HIGH);
mLocationProvider = mLocationManager.getBestProvider(criterion, true);
}
#Override
protected void onResume() {
super.onResume();
mCurrentLocation = mLocationManager.getLastKnownLocation(mLocationProvider);
mLocationManager.requestLocationUpdates(mLocationProvider, 5000, 1, mLocationListener);
}
#Override
protected void onPause() {
super.onPause();
mLocationManager.removeUpdates(mLocationListener);
}
private class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location newlocation) {
float distance = mCurrentLocation.distanceTo(newlocation);
if (distance >= 1) {
mCounter++;
Toast.makeText(MainActivity.this, String.format("Message #%d: you walked one more meter", mCounter), Toast.LENGTH_SHORT).show();
mCurrentLocation = newlocation;
}
}
}
}
A GPS signal is not precise enough to give exact locations for a 1m radius. There can be deviation peeks up to 50 - 100m in real situations using GPS. This depends much on the environment you are at. GPS will be reflected by buildings, water etc. An average deviation is 10 - 20m. This will get even worse if your inside of a building using a GPS provider instead of a Network provider.
Furthermore you will never get the same coordinates twice in a row, because of this. Even if you don't move! To avoid that you could temporarly save the location and compare it with the new location. If the distance between them hits a defined boarder use the new location.
Change your location provider to GPS. And you have instantiated the LocationListener before you request the new Location(in onResume(); onResume() will be called after onCreate()). This might be the reason for your app showing Toast on start up.. Try to instantiate LocationListener after the requestLocationUpdates()..

Android lastKnownLocation returns null

I've got this problem I don't see anything wrong in the code but getLastKnownLocation returns null every time . any ideas ?
public class LocationDemo2Activity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
EditText et1 = (EditText) findViewById(R.id.editText1);
LocationManager manager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
Location location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null) et1.setText((int)location.getLatitude());
else et1.setText("null");
}
}
thanks
getLastKnownLocation() will frequently return null, particularly if the location provider (e.g., GPS) has not been used recently. You only use getLastKnownLocation() in situations where you either do not really need a location (but would like to have one) or where you will use other techniques if getLastKnownLocation() returns null (e.g., request location updates).

Android - How to get current user coordinates/location on demand?

I have an Activity with a button, I just want the button to get current user location via gps/internet/etc and show a toast with those coordinates. That's all, just check the coords once, and show them. Only and every time I click the button, the coords should be updated and shown.
How can I do this? I'm having some trouble understanding LocationManager (if that's what I should be using)
I have these in manifest
"android.permission.INTERNET"
"android.permission.ACCESS_FINE_LOCATION"
"android.permission.ACCESS_NETWORK_STATE"
"android.permission.ACCESS_COARSE_LOCATION"
The logcat only shows Couldn't get connection factory client on app startup. The app shows a mapview at first, and that is working ok, so I don't know if that error is my problem.
I did:
...
LocationManager mlocManager =
(LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
....
public class MyLocationListener implements LocationListener
{ #Override public void onLocationChanged(Location loc)
{
TextView textView = (TextView) findViewById(R.id.textView2);
textView.setText("Latitud: "+loc.getLatitude()+" , Longitud"+loc.getLongitude());
}
...
}
But it's not changing textview2 value
Use a global variable in onLocationChanged(Location l) and onClick() off the button you se the value. The value will always be actualized.

Turn off GPS icon when LocationListener is sleeping

I am struggling a bit with the LocationListener in Android. I want to make an app that will get the current GPS location, and then afterwards sleep for a long time. A day or more. In this period of time i want the GPS notification icon to not show.
What i have now, is in the onLocationChanged a Thread.sleep(x) but this will keep the icon on in the sleep period. How can i do this, and is there a better approach than to use Thread.sleep?
Thanks in advance
You have to turn off the LocationManager completly for that. I did it in my App, where I only check the Location every 10 seconds, 'cause I found out, that the turning off saves a bit more battery power than a min_distance or min_time of the LocationManager.
Something like:
// Turning off
mLocationManager.removeUpdates(gpsListener);
mLocationManager = null;
// Turning on again
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_MINTIME, GPS_MINDISTANCE, gpsListener);
The icon will disappear till the LocationManager is turned on again.
If you have overlays, think to disable the location on them too :
#Override
protected void onResume()
{
Log.i("ProjetTEA", "onResumeMain");
if (mLocationListener != null)
{
mLocationOverlay.enableMyLocation();
mLocationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(mBestProvider, 10000, 2, mLocationListener);
}
super.onResume();
}
#Override
protected void onPause()
{
Log.i("ProjetTEA", "onPauseMain");
mLocationOverlay.disableMyLocation();
mLocationManager.removeUpdates(mLocationListener);
mLocationManager = null;
super.onPause();
}

Categories

Resources