Android : onlocationchanged called too late and not according to my requirement

on Monday, October 13, 2014


I am trying to get the current latitude and longitude using an example i found on the following link: http://gabesechansoftware.com/location-tracking/


There are two classes :The first class:



package com.example.marinamapseg;

import android.content.Context;
import android.location.Location;
import android.location.LocationManager;

public class FallbackLocationTracker implements LocationTracker, LocationTracker.LocationUpdateListener {


private boolean isRunning;

private ProviderLocationTracker gps;
private ProviderLocationTracker net;

private LocationUpdateListener listener;

Location lastLoc;
long lastTime;

public FallbackLocationTracker(Context context) {
gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS);
net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK);
}

public void start(){
if(isRunning){
//Already running, do nothing
return;
}

//Start both
gps.start(this);
net.start(this);
isRunning = true;
}

public void start(LocationUpdateListener update) {
start();
listener = update;
}


public void stop(){
if(isRunning){
gps.stop();
net.stop();
isRunning = false;
listener = null;
}
}

public boolean hasLocation(){
//If either has a location, use it
return gps.hasLocation() || net.hasLocation();
}

public boolean hasPossiblyStaleLocation(){
//If either has a location, use it
return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation();
}

public Location getLocation(){
Location ret = gps.getLocation();
if(ret == null){
ret = net.getLocation();
}
return ret;
}

public Location getPossiblyStaleLocation(){
Location ret = gps.getPossiblyStaleLocation();
if(ret == null){
ret = net.getPossiblyStaleLocation();
}
return ret;
}

public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) {
boolean update = false;

//We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale
if(lastLoc == null){
update = true;
}
else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){
update = true;
}
else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){
update = true;
}
else if (newTime - lastTime > 5 * 60 * 1000){
update = true;
}

if(update){
lastLoc = newLoc;
lastTime = newTime;
if(listener != null){
listener.onUpdate(lastLoc, lastTime, newLoc, newTime);
}
}
}
}


The second class:



package com.example.marinamapseg;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class ProviderLocationTracker implements LocationListener, LocationTracker {

// The minimum distance to change Updates in meters
private static final long MIN_UPDATE_DISTANCE = 0;

// The minimum time between updates in milliseconds
private static final long MIN_UPDATE_TIME = 0;

private LocationManager lm;

public enum ProviderType{
NETWORK,
GPS
};
private String provider;

private Location lastLocation;
private long lastTime;

private boolean isRunning;

private LocationUpdateListener listener;

public ProviderLocationTracker(Context context, ProviderType type) {
lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
if(type == ProviderType.NETWORK){
provider = LocationManager.NETWORK_PROVIDER;
}
else{
provider = LocationManager.GPS_PROVIDER;
}
}

public void start(){
if(isRunning){
//Already running, do nothing
return;
}

//The provider is on, so start getting updates. Update current location
isRunning = true;
lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE,this);
lastLocation = null;
lastTime = 0;
//lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE,this);
//return;
}

public void start(LocationUpdateListener update) {
start();
listener = update;

}


public void stop(){
if(isRunning){
lm.removeUpdates(this);
isRunning = false;
listener = null;
}
}

public boolean hasLocation(){
if(lastLocation == null){
return false;
}
if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
return false; //stale
}
return true;
}

public boolean hasPossiblyStaleLocation(){
if(lastLocation != null){
return true;
}
return lm.getLastKnownLocation(provider)!= null;
}

public Location getLocation(){
if(lastLocation == null){
return null;
}
if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
return null; //stale
}
return lastLocation;
}

public Location getPossiblyStaleLocation(){
if(lastLocation != null){
return lastLocation;
}
return lm.getLastKnownLocation(provider);
}

public void onLocationChanged(Location newLoc) {
long now = System.currentTimeMillis();
if(listener != null){
listener.onUpdate(lastLocation, lastTime, newLoc, now);
}
lastLocation = newLoc;
lastTime = now;
}

public void onProviderDisabled(String arg0) {

}

public void onProviderEnabled(String arg0) {

}

public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
}


What i tried doing was to create an object of the first class and check whether the location can be found as follows:



fobj=new FallbackLocationTracker(MainActivity.this);
fobj.start();
if(fobj.hasLocation())
{
Location locobj=fobj.getLocation();
current_latitude=locobj.getLatitude();
current_longitude=locobj.getLongitude();
Toast.makeText(getApplicationContext(),current_latitude+" "+current_longitude,Toast.LENGTH_LONG).show();
placemarkersonmap();
}


The issue is as follows:


The haslocation() method will return false as the lastlocation object is null.But the lastlocation object gets a value only in the onlocationchanged method.So how do i ensure that the onlocationchanged method runs before i call my haslocation method?


0 comments:

Post a Comment