When my map activity is called I make a call in the onCreate to addUserMapPoint. This function contains two instances where I try to get the location information using myOverlay.getMyLocation. On the initial load of this activity the result of the first attempt returns a null GeoPoint and after the main UI thread completes the second attempt located in the listener thread of myOverlay.runOnFirstFix(new Runnable()… is call after a second and does contain a GeoPoint that does contain a lat and lon. The call inside this listener function does appear to put the dot on the map and the line mapController.animateTo(gp) does move the map to my location. My app has a refresh button that when clicked fires off this activity again. I need the lat and lon in order to fetch location data from another service. After the refresh, the second time through the map activity code I was expecting the first call to myOverlay.getMyLocation() would now be able to get the GeoPoint, but it is still null.
If I’m not able to get the GeoPoint by this first call to myOverlay.getMyLocation then how can I pass the lat and lon value from the second call found in the myOverlay.runOnFirstFix(new Runnable()… thread. You will notice that I have been trying to add the lat and lon to MyApp which is helper bean class but the lat and lon in this class is null even after the refresh. If I manually set a lat and lon manually in the addUserMapPoint function the first time the activity is accessed these values are retained. I’m guessing that this is because it is being set on the main UI thread.
public class MapActivity extends com.google.android.maps.MapActivity {
private MapView mapView = null;
private MapController mapController = null;
private MyLocationOverlay myOverlay = null;
public static MyApp app;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
app = (MyApp) getApplicationContext();
mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
mapController = mapView.getController();
List<Overlay> mapOverlays = mapView.getOverlays();
mapOverlays.clear();
addUserMapPoint(mapView);
if (!app.isLocServOff()) {
//map other points – service call to get items from our service near lat and lon
addOtherMapPoints(mapOverlays);
} else {
Toast.makeText(app.getApplicationContext(),"Current location could not be found.",Toast.LENGTH_LONG).show();
}
}
private void addUserMapPoint(MapView mapView){
myOverlay = new MyLocationOverlay(app.getApplicationContext(), mapView);
myOverlay.disableCompass();
myOverlay.enableMyLocation();
if(app.getMyLat()==null||app.getMyLon()==null){
GeoPoint gp = myOverlay.getMyLocation();
if(gp!=null){
app.setMyLat(Helper.latLon1E6Calc(gp.getLatitudeE6()));
app.setMyLon(Helper.latLon1E6Calc(gp.getLongitudeE6()));
app.setLocServOff(false);
}else{
app.setLocServOff(true);
}
}
myOverlay.runOnFirstFix(new Runnable() {
public void run() {
GeoPoint gp = myOverlay.getMyLocation();
if(gp!=null){
app.setMyLat(Helper.latLon1E6Calc(gp.getLatitudeE6()));
app.setMyLon(Helper.latLon1E6Calc(gp.getLongitudeE6()));
app.setLocServOff(false);
mapController.animateTo(gp);
}else{
app.setLocServOff(true);
}
}
});
mapView.getOverlays().add(myOverlay);
}
}
Your help is being requested for the following question. How can I get a GeoPoint that contains a lat and lon in the main UI thread or how can I pass these values from GeoPoint I am able to get from the myOverlay.runOnFirstFix(new Runnable()… thread?
If you are going to suggest that I use Handler or runOnUiThread please provide code example that passes the lat and lon back to something that can be used by the main UI thread/map view. I have tried things like the following code that did not produce the desired outcome. I was able to get the toast message to show up, but was not able to get the lat and lon passed in a way I could use.
final Handler handler = new Handler();
myOverlay.runOnFirstFix(new Runnable() {
@Override public void run() {
handler.post(new Runnable() {
@Override public void run() {
GeoPoint gp = myOverlay.getMyLocation();
if(gp!=null){
app.setMyLat(Helper.latLon1E6Calc(gp.getLatitudeE6()));
app.setMyLon(Helper.latLon1E6Calc(gp.getLongitudeE6()));
app.setLocServOff(false);
mapController.animateTo(gp);
}else{
app.setLocServOff(true);
}
//Toast.makeText(getApplicationContext(),"wowoowowowoowoowowow",Toast.LENGTH_LONG).show();
}
});
}
});
I've also used code like the following to get the lat and lon and it works, but because the current location would sometimes be a different lat and lon than whas was being returned becuase for example I could not get a gps signal but yet an old value was returned. I added checks to see if the lat/lon data was older than 2 minutes, but I still could not match up the most recent lat and lon with that that is returned by myOverlay.getMyLocation.
LocationManager locMgr = (LocationManager)appcontext.getSystemService(Context.LOCATION_SERVICE);
MyLocationListener locLstnr = new MyLocationListener();
//fetch current location for current location
locMgr.requestSingleUpdate(LocationManager.GPS_PROVIDER, locLstnr, appcontext.getMainLooper());