I need to perform some tasks with google map,
1. first I need the user to be able to place only one marker
2. Then retrieve the city and other details such as street address
Does anyone know about this?
I wrote a minimal example to show how you could achieve what you're looking for:
public void onModuleLoad() {
RootPanel.get().add(new GoogleMaps());
}
private class GoogleMaps extends Composite {
private MapWidget fMap;
private Geocoder fCoder;
private Marker fMarker;
public GoogleMaps() {
fMap = new MapWidget(LatLng.newInstance(47.0559084, 8.3114878), 6);
fMap.setSize("300px", "300px");
fCoder = new Geocoder();
MarkerOptions options = MarkerOptions.newInstance();
options.setDraggable(true);
fMarker = new Marker(LatLng.newInstance(47.0559084, 8.3114878), options);
fMap.addOverlay(fMarker);
fMarker.setVisible(false);
addHandlers();
initWidget(fMap);
}
private void addHandlers() {
fMap.addMapDoubleClickHandler(new MapDoubleClickHandler() {
#Override
public void onDoubleClick(MapDoubleClickEvent event) {
if (event.getLatLng() != null) {
performReverseLookup(event.getLatLng());
}
}
});
fMarker.addMarkerDragEndHandler(new MarkerDragEndHandler() {
#Override
public void onDragEnd(MarkerDragEndEvent event) {
LatLng point = event.getSender().getLatLng();
if (point != null) {
performReverseLookup(point);
}
}
});
}
private void performReverseLookup(final LatLng point) {
fCoder.getLocations(point, new LocationCallback() {
#Override
public void onSuccess(JsArray<Placemark> locations) {
if (locations.length() > 0) {
LatLng point = locations.get(0).getPoint();
fMarker.setLatLng(point);
fMarker.setVisible(true);
fMap.getInfoWindow().open(point, new InfoWindowContent(locations.get(0).getAddress()));
}
}
#Override
public void onFailure(int statusCode) {}
});
}
}
To your first point: Create only one instance of Marker and update its LatLng upon user interaction (done in performReverseLookup()).
Your second question: After performing the reverse lookup you can get the Placemark object out of the locations array and retrieve details like the address.
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
I get user current location by using override method
public void onSuccess(LocationEngineResult result) {
location = Point.fromLngLat(result.getLastLocation().getLongitude(),result.getLastLocation().getLatitude());
}
but I don't know how to replace the latitude and longitude on variable
private final Point ROUTE_ORIGIN=Point.fromLngLat(location.longitude(),location.latitude());
with the location i get from public void onSuccess(LocationEngineResult result) is there any solution for this?
The app crashed with error
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'double com.mapbox.geojson.Point.longitude()' on a null object reference
Can anyone give me some idea or solution? I tried to find sources but still can't solve it.
public class ArActivity extends BaseActivity implements RouteListener, ProgressChangeListener, OffRouteListener {
private static final String TAG = ArActivity.class.getSimpleName();
// Handles navigation.
private MapboxNavigation mapboxNavigation;
// Fetches route from points.
private RouteFetcher routeFetcher;
private RouteProgress lastRouteProgress;
private PermissionsManager permissionsManager;
private LocationEngine locationEngine;
private LocationEngineCallback<LocationEngineResult> locationCallback;
public Point location;
private boolean visionManagerWasInit = false;
private boolean navigationWasStarted = false;
TextView tvlocation;
// This dummy points will be used to build route. For real world test this needs to be changed to real values for
// source and target location
private final Point ROUTE_ORIGIN=Point.fromLngLat(location.longitude(),location.latitude());
private final Point ROUTE_DESTINATION = Point.fromLngLat(101.769116, 2.923220);
#Override
protected void initViews() {
setContentView(R.layout.activity_ar_navigation);
tvlocation = findViewById(R.id.location);
}
#Override
protected void onPermissionsGranted() {
startVisionManager();
startNavigation();
}
#Override
protected void onStart() {
super.onStart();
startVisionManager();
startNavigation();
}
#Override
protected void onStop() {
super.onStop();
stopVisionManager();
stopNavigation();
}
private void startVisionManager() {
if (allPermissionsGranted() && !visionManagerWasInit) {
// Create and start VisionManager.
VisionManager.create();
VisionManager.setModelPerformanceConfig(new Merged(new On(ModelPerformanceMode.DYNAMIC, ModelPerformanceRate.LOW)));
VisionManager.start();
VisionManager.setVisionEventsListener(new VisionEventsListener() {
#Override
public void onAuthorizationStatusUpdated(#NotNull AuthorizationStatus authorizationStatus) {
}
#Override
public void onFrameSegmentationUpdated(#NotNull FrameSegmentation frameSegmentation) {
}
#Override
public void onFrameDetectionsUpdated(#NotNull FrameDetections frameDetections) {
}
#Override
public void onFrameSignClassificationsUpdated(#NotNull FrameSignClassifications frameSignClassifications) {
}
#Override
public void onRoadDescriptionUpdated(#NotNull RoadDescription roadDescription) {
}
#Override
public void onWorldDescriptionUpdated(#NotNull WorldDescription worldDescription) {
}
#Override
public void onVehicleStateUpdated(#NotNull VehicleState vehicleState) {
}
#Override
public void onCameraUpdated(#NotNull Camera camera) {
}
#Override
public void onCountryUpdated(#NotNull Country country) {
}
#Override
public void onUpdateCompleted() {
}
});
VisionArView visionArView = findViewById(R.id.mapbox_ar_view);
// Create VisionArManager.
VisionArManager.create(VisionManager.INSTANCE);
visionArView.setArManager(VisionArManager.INSTANCE);
visionArView.setFenceVisible(true);
visionManagerWasInit = true;
}
}
private void stopVisionManager() {
if (visionManagerWasInit) {
VisionArManager.destroy();
VisionManager.stop();
VisionManager.destroy();
visionManagerWasInit = false;
}
}
private void startNavigation() {
if (allPermissionsGranted() && !navigationWasStarted) {
// Initialize navigation with your Mapbox access token.
mapboxNavigation = new MapboxNavigation(
this,
getString(R.string.mapbox_access_token),
MapboxNavigationOptions.builder().build()
);
// Initialize route fetcher with your Mapbox access token.
routeFetcher = new RouteFetcher(this, getString(R.string.mapbox_access_token));
routeFetcher.addRouteListener(this);
locationEngine = LocationEngineProvider.getBestLocationEngine(this);
LocationEngineRequest arLocationEngineRequest = new LocationEngineRequest.Builder(0)
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
.setFastestInterval(1000)
.build();
locationCallback = new LocationEngineCallback<LocationEngineResult> () {
#Override
public void onSuccess(LocationEngineResult result) {
location = Point.fromLngLat(result.getLastLocation().getLongitude(),result.getLastLocation().getLatitude());
}
#Override
public void onFailure(#NonNull Exception exception) {
}
};
try {
locationEngine.requestLocationUpdates(arLocationEngineRequest, locationCallback, Looper.getMainLooper());
} catch (SecurityException se) {
VisionLogger.Companion.e(TAG, se.toString());
}
initDirectionsRoute();
// Route need to be reestablished if off route happens.
mapboxNavigation.addOffRouteListener(this);
mapboxNavigation.addProgressChangeListener(this);
navigationWasStarted = true;
}
}
private void stopNavigation() {
if (navigationWasStarted) {
locationEngine.removeLocationUpdates(locationCallback);
mapboxNavigation.removeProgressChangeListener(this);
mapboxNavigation.removeOffRouteListener(this);
mapboxNavigation.stopNavigation();
navigationWasStarted = false;
}
}
private void initDirectionsRoute() {
// Get route from predefined points.
NavigationRoute.builder(this)
.accessToken(getString(R.string.mapbox_access_token))
.origin(ROUTE_ORIGIN)
.destination(ROUTE_DESTINATION)
.build()
.getRoute(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
if (response.body() == null || response.body().routes().isEmpty()) {
return;
}
// Start navigation session with retrieved route.
DirectionsRoute route = response.body().routes().get(0);
mapboxNavigation.startNavigation(route);
// Set route progress.
VisionArManager.setRoute(new Route(
getRoutePoints(route),
route.duration().floatValue(),
"",
""
));
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
}
});
}
#Override
public void onErrorReceived(Throwable throwable) {
if (throwable != null) {
throwable.printStackTrace();
}
mapboxNavigation.stopNavigation();
Toast.makeText(this, "Can not calculate the route requested", Toast.LENGTH_SHORT).show();
}
#Override
public void onResponseReceived(#NotNull DirectionsResponse response, RouteProgress routeProgress) {
mapboxNavigation.stopNavigation();
if (response.routes().isEmpty()) {
Toast.makeText(this, "Can not calculate the route requested", Toast.LENGTH_SHORT).show();
} else {
DirectionsRoute route = response.routes().get(0);
mapboxNavigation.startNavigation(route);
// Set route progress.
VisionArManager.setRoute(new Route(
getRoutePoints(route),
(float) routeProgress.durationRemaining(),
"",
""
));
}
}
#Override
public void onProgressChange(Location location, RouteProgress routeProgress) {
lastRouteProgress = routeProgress;
}
#Override
public void userOffRoute(Location location) {
routeFetcher.findRouteFromRouteProgress(location, lastRouteProgress);
}
private RoutePoint[] getRoutePoints(#NotNull DirectionsRoute route) {
ArrayList<RoutePoint> routePoints = new ArrayList<>();
List<RouteLeg> legs = route.legs();
if (legs != null) {
for (RouteLeg leg : legs) {
List<LegStep> steps = leg.steps();
if (steps != null) {
for (LegStep step : steps) {
RoutePoint point = new RoutePoint((new GeoCoordinate(
step.maneuver().location().latitude(),
step.maneuver().location().longitude()
)), mapToManeuverType(step.maneuver().type()));
routePoints.add(point);
List<Point> geometryPoints = buildStepPointsFromGeometry(step.geometry());
for (Point geometryPoint : geometryPoints) {
point = new RoutePoint((new GeoCoordinate(
geometryPoint.latitude(),
geometryPoint.longitude()
)), ManeuverType.None);
routePoints.add(point);
}
}
}
}
}
return routePoints.toArray(new RoutePoint[0]);
}
private List<Point> buildStepPointsFromGeometry(String geometry) {
return PolylineUtils.decode(geometry, Constants.PRECISION_6);
}
private ManeuverType mapToManeuverType(#Nullable String maneuver) {
if (maneuver == null) {
return ManeuverType.None;
}
switch (maneuver) {
case "turn":
return ManeuverType.Turn;
case "depart":
return ManeuverType.Depart;
case "arrive":
return ManeuverType.Arrive;
case "merge":
return ManeuverType.Merge;
case "on ramp":
return ManeuverType.OnRamp;
case "off ramp":
return ManeuverType.OffRamp;
case "fork":
return ManeuverType.Fork;
case "roundabout":
return ManeuverType.Roundabout;
case "exit roundabout":
return ManeuverType.RoundaboutExit;
case "end of road":
return ManeuverType.EndOfRoad;
case "new name":
return ManeuverType.NewName;
case "continue":
return ManeuverType.Continue;
case "rotary":
return ManeuverType.Rotary;
case "roundabout turn":
return ManeuverType.RoundaboutTurn;
case "notification":
return ManeuverType.Notification;
case "exit rotary":
return ManeuverType.RotaryExit;
default:
return ManeuverType.None;
}
}
At the point of instantiating this line (i.e. when the class loads):
private final Point ROUTE_ORIGIN=Point.fromLngLat(location.longitude(),location.latitude());
The location variable you are using is set to nothing:
public Point location;
Aka, it is null and you are getting a NullPointerException.
You should either not try to use the location object until it is instantiated, setting your routeOrigin later on. Or change the ROUTE_ORIGIN to use a static location, the same way you have for ROUTE_DESTINATION.
So I'm making an app and I need continuous location updates to move my custom location marker. I wanted to have a smooth marker movement like Uber has. I implemented SmartLocation library using FusedLocationProvider, location accuracy is set to HIGH, and location is updated every second, yet for some reason I'm getting slow updates that are not accurate. Can someone tell me what I'm doing wrong?
public void onLocationUpdatedListenerInit(){
onLocationUpdatedListener=new OnLocationUpdatedListener() {
#Override
public void onLocationUpdated(Location location) {
animateMarker(location, myLocation);
}
};
}
public void startingLocationTracking(){
LocationParams.Builder builder = new LocationParams.Builder().setAccuracy(LocationAccuracy.HIGH)
.setDistance(0)
.setInterval(1000);
SmartLocation.with(this).location(new LocationGooglePlayServicesProvider()).continuous().config(builder.build()).start(onLocationUpdatedListener);
}
AnimateMarker method:
public static void animateMarker(final Location destination, final Marker marker) {
if (marker != null) {
final LatLng startPosition = marker.getPosition();
final LatLng endPosition = new LatLng(destination.getLatitude(), destination.getLongitude());
final float startRotation = marker.getRotation();
final LatLngInterpolator latLngInterpolator = new LatLngInterpolator.LinearFixed();
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(1000); // duration 1 second
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override public void onAnimationUpdate(ValueAnimator animation) {
try {
float v = animation.getAnimatedFraction();
LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, endPosition);
marker.setPosition(newPosition);
marker.setRotation(computeRotation(v, startRotation, destination.getBearing()));
} catch (Exception ex) {
// I don't care atm..
}
}
});
valueAnimator.start();
}
}
I have implemented MVP pattern in my app. And I'm using WeakReferences to store View's reference in my Presenter. But still my fragments are not being claimed by GC upon destroying. Below is the screenshot of problem. Any idea what is causing this and how to remove this issue?
Below is the code for my Presenter:
public class ProductDetailPresenter implements ProductDetailContract.Presenter {
private final WeakReference<ProductDetailContract.View> view;
private CategoriesDataSource repo;
public ProductDetailPresenter(ProductDetailContract.View view, CategoriesDataSource repo) {
this.view = new WeakReference<>(view);
this.repo = repo;
view.setPresenter(this);
}
#Override
public void start() {
}
#Override
public void submitRating(final Product product, final float mRating) {
final ProductDetailContract.View view =ProductDetailPresenter.this.view.get();
if (view != null) {
repo.submitRating(product.getId(), mRating, true, new CategoriesDataSource.SubmitRatingCallback() {
#Override
public void onRatingSubmitted() {
product.setRating(mRating);
product.setRated(true);
product.setUpdatedAt(new Date(System.currentTimeMillis()));
repo.updateProductInDB(product);
if (!view.isActive()) return;
view.onRatingSubmitted(true, mRating);
}
#Override
public void onError(Throwable throwable) {
if (!view.isActive()) return;
view.onRatingSubmitted(false, 0);
}
});
}
}
#Override
public void onRateKarenClicked() {
ProductDetailContract.View view = this.view.get();
if (view != null) {
view.openDialog();
}
}
#Override
public void onAbhiKhareediyeClicked(Product product) {
EventBus.getDefault().post(
new ProductDetailContract.ContractEventMessages(
ProductDetailContract.ContractEventMessages.EVENT_START_QUANTITY_SCREEN, product));
}
}
This is the problem:
#Override
public void submitRating(final Product product, final float mRating) {
final ProductDetailContract.View view =ProductDetailPresenter.this.view.get(); <-- this is bad
you have a final object that is being passed to the repo. Delete the whole line. You don't need it. Use in the view.get() inside the onRatingSubmitted and onError
I am new to Java and since this question belongs to a very time sensitive project for my work, I dont have the time to learn everything about AsyncTasks.
So my question is:
How do I construct an AsyncTaskout of the following code?
The goal is to draw a route on a map. I fill the ArrayListwith two Geopoints (start-location and the destination of the route). The roadManager is supposed to send those waypoints to a server that sends me back the route.
buildRoadOverlay is the method that finally draws the route on the map.
RoadManager roadManager = new OSRMRoadManager(this);
ArrayList<GeoPoint> waypoints = new ArrayList<GeoPoint>();
GeoPoint myLocation = new GeoPoint(51.488978, 6.746994);
waypoints.add(Location);
waypoints.add(myLocation);
Road road = roadManager.getRoad(waypoints);
I guess this has to go in the onPostExecute -method, right?:
Polyline roadOverlay = RoadManager.buildRoadOverlay(road);
map.getOverlays().add(roadOverlay);
The variable location from the upper code originates from a different method, from which I intend to start the Async task. Meaning, I need to transmit the variable to the AsyncTask when calling it, which I am also not sure how to do exactly.
This is the initialization of the variable location:
GeoPoint Location = new GeoPoint(Double.parseDouble(place.getLongitude()),
Double.parseDouble(place.getLatitude()));
Put the time consuming task in doInBackground(), udpate view in onPostExecute().
public void drawRouteAsync() {
GeoPoint location = new GeoPoint(Double.parseDouble(place.getLongitude()),
Double.parseDouble(place.getLatitude()));
GeoPoint myLocation = new GeoPoint(51.488978, 6.746994);
new RouteAsyncTask().execute(location, myLocation);
}
private class RouteAsyncTask extends AsyncTask<GeoPoint, Void, Road> {
#Override
protected Road doInBackground(GeoPoint... params) {
ArrayList<GeoPoint> waypoints = new ArrayList<GeoPoint>();
waypoints.add(params[0]); // location
waypoints.add(params[1]); // myLocation
RoadManager roadManager = new OSRMRoadManager(mContext); // your context
Road road = roadManager.getRoad(waypoints); // time consuming
return road;
}
#Override
protected void onPostExecute(Road road) {
Polyline roadOverlay = RoadManager.buildRoadOverlay(road);
map.getOverlays().add(roadOverlay); // update view
}
}
AsyncTask have 3 important methods:
protected void onPreExecute() //main thread
protected E doInBackground(T... params) //async thread
protected void onPostExecute(E result) //main thread
E and T will be definded in implementation.
So knowing this, your AsincTask should look somthing like this:
public class GetRouteTask extends AsyncTask<GeoPoint, Void, Integer> {
private Context mContext;
private OnGetRouteCompleted delegate;
private Road route;
public GetRouteTask (Context context, OnGetRouteCompleted delegate) {
this.delegate = delegate;
this.mContext = context;
}
#Override
protected Integer doInBackground(GeoPoint... params) {
ArrayList<GeoPoint> wayPoints = new ArrayList<GeoPoint>();
wayPoints.add(params[0]); // pointFrom
wayPoints.add(params[1]); // pointTo
try {
RoadManager roadManager = new OSRMRoadManager(mContext);
route = roadManager.getRoad(waypoints);
return 1;
} catch (JSONException e) {
return -1;
}
}
#Override
protected void onPostExecute(Integer success) {
if (success == 1) {
delegate.onGetRouteCompleted(true, route);
} else {
delegate.onGetRouteCompleted(false, null);
}
Polyline roadOverlay = RoadManager.buildRoadOverlay(road);
map.getOverlays().add(roadOverlay); // update view
}
public interface OnGetRouteCompleted {
public void onGetRouteCompleted(boolean success, Route route);
}
}
And this how you use it:
public class SomeActivity extend Activity implements OnGetRouteCompleted {
// Methods and properties...
public void drawRouteAsync() {
GeoPoint pointFrom = new GeoPoint(51.489878, 6.143294);
GeoPoint pointTo = new GeoPoint(51.488978, 6.746994);
new GetRouteTask(getApplicationContext(), this).execute(new GeoPoint(){pointFrom , pointTo});
}
#Override
public void onGetRouteCompleted(boolean success, Route route) {
if (success) {
Polyline roadOverlay = RoadManager.buildRoadOverlay(route);
map.getOverlays().add(roadOverlay); // update view
}
}
}
I have literally been searching for this for weeks. I am a novice java programmer but I have been able to piece together an app that can use a double latitude and longitude hard coded in the same class. It will show a list of current places surrounding those points. I have another separate class with a method that is able to get the current location based on the gps/network but I can't pass the variables created from this second class to the PlaceRequest class. I have looked through all of the tutorials on the above subjects but there isn't anything combining current location and place search results. I have two getters declared but can't call the variables in these. Again sort of a rookie so may be an easy fix. Any ideas?
Update - Here is my code so far:
GooglePlaceActivity.java
public class GooglePlaceActivity extends Activity {
/** Called when the activity is first created. */
Button btn1;
TextView txt1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.main);
btn1 = (Button)findViewById(R.id.button1);
txt1 = (TextView)findViewById(R.id.textView1);
btn1.setOnClickListener(l);
}
private class SearchSrv extends AsyncTask<Void, Void, PlacesList>{
#Override
protected PlacesList doInBackground(Void... params) {
PlacesList pl = null;
try {
pl = new PlaceRequest().performSearch();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return pl;
}
#Override
protected void onPostExecute(PlacesList result) {
String text = "Result \n";
if (result!=null){
for(Place place: result.results){
text = text + place.name +"\n";
}
txt1.setText(text);
}
setProgressBarIndeterminateVisibility(false);
}
}
View.OnClickListener l = new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
SearchSrv srv = new SearchSrv();
setProgressBarIndeterminateVisibility(true);
srv.execute();
}
};
}
//////////////////////
PlaceRequest.java
public class PlaceRequest {
private static final HttpTransport transport = new ApacheHttpTransport();
private static final String API_KEY = "keyhere";
private static final String LOG_KEY = "GGPlace";
// The different Places API endpoints.
private static final String PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/search/json?";
private static final String PLACES_AUTOCOMPLETE_URL = "https://maps.googleapis.com/maps/api/place/autocomplete/json?";
private static final String PLACES_DETAILS_URL = "https://maps.googleapis.com/maps/api/place/details/json?";
private static final boolean PRINT_AS_STRING = true;
//double latitude;
//double longitude;
CurrentLocation clo = new CurrentLocation(null);
//clo.onLocationChanged(latitude);
//double longitude = CurrentLocation.getLongitude();
//double latitude = CurrentLocation.getLatitude();
double longi = clo.getLongitude();
double lat = clo.getLatitude();
public PlacesList performSearch() throws Exception {
try {
//CurrentLocation currlo = new CurrentLocation();
//double lat = currlo.getLatitude();
//double longi = currlo.getLongitude();
Log.v(LOG_KEY, "Start Search");
GenericUrl reqUrl = new GenericUrl(PLACES_SEARCH_URL);
reqUrl.put("key", API_KEY);
//reqUrl.put("location", latitude + "," + longitude);
//reqUrl.put("location", getLatitude(latitude) + "," + getLongitude());
reqUrl.put("location", lat + "," + longi);
reqUrl.put("radius", 1600);
reqUrl.put("types", "food");
reqUrl.put("sensor", "false");
Log.v(LOG_KEY, "url= " + reqUrl);
HttpRequestFactory httpRequestFactory = createRequestFactory(transport);
HttpRequest request = httpRequestFactory.buildGetRequest(reqUrl);
Log.v(LOG_KEY, request.execute().parseAsString());
PlacesList places = request.execute().parseAs(PlacesList.class);
Log.v(LOG_KEY, "STATUS = " + places.status);
for (Place place : places.results) {
Log.v(LOG_KEY, place.name);
}
return places;
} catch (HttpResponseException e) {
Log.v(LOG_KEY, e.getResponse().parseAsString());
throw e;
}
catch (IOException e) {
// TODO: handle exception
throw e;
}
}
public static HttpRequestFactory createRequestFactory(final HttpTransport transport) {
return transport.createRequestFactory(new HttpRequestInitializer() {
public void initialize(HttpRequest request) {
GoogleHeaders headers = new GoogleHeaders();
headers.setApplicationName("Google-Places-DemoApp");
request.setHeaders(headers);
JsonHttpParser parser = new JsonHttpParser(new JacksonFactory()) ;
//JsonHttpParser.builder(new JacksonFactory());
//parser.jsonFactory = new JacksonFactory();
request.addParser(parser);
}
});
}
}
/////////////
CurrentLocation.java
public class CurrentLocation {
private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1; // in Meters
private static final long MINIMUM_TIME_BETWEEN_UPDATES = 1000; // in Milliseconds
LocationManager locationManager ;
double latitude=0;
double longitude=0;
public CurrentLocation(Context ctxt) {
super();
locationManager = (LocationManager) ctxt.getSystemService(Context.LOCATION_SERVICE);
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
#Override
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
}
});
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
}
Edit: After looking your complete code, I see a few fundamental design flaws so I'm going to show you how I did it and you can adapt it to your program flow. Please keep in mind that this example is vastly simplified from my original, but it should be enough to get you going.
First, the CurrentLocation.java file. My design decision for wrapping this in a Future was so that I can re-use it in multiple activities with the added bonus of killing it when necessary.
public class CurrentLocation implements Callable<Location> {
private static final String TAG = "CurrentLocation";
private Context context;
private LocationManager lm;
private Criteria criteria;
private Location bestResult;
private boolean locationListenerWorking;
public CurrentLocation(Context context) {
lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
this.context = context;
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
bestResult = null;
locationListenerWorking = false;
}
public Location call() {
return getLoc();
}
private Location getLoc() {
String provider = lm.getBestProvider(criteria, true);
if (provider != null) {
Log.d(TAG, "Using provider: " +provider);
locationListenerWorking = true;
lm.requestLocationUpdates(provider,
0,
0,
singeUpdateListener,
context.getMainLooper());
} else {
Log.w(TAG, "Couldn't find a location provider");
return null;
}
while (locationListenerWorking) {
// Check for the interrupt signal - terminate if necessary
if (Thread.currentThread().isInterrupted()) {
Log.i(TAG, "User initiated interrupt (cancel signal)");
cleanup();
break;
}
try {
// ghetto implementation of a busy wait...
Thread.sleep(500); // Sleep for half a second
} catch (Exception e) {
Log.d(TAG, "Thread interrupted..");
cleanup();
break;
}
}
return bestResult;
}
private void cleanup() {
if (lm != null) {
Log.d(TAG, "Location manager not null - cleaning up");
lm.removeUpdates(singeUpdateListener);
} else {
Log.d(TAG, "Location manager was NULL - no cleanup necessary");
}
}
/**
* This one-off {#link LocationListener} simply listens for a single location
* update before unregistering itself. The one-off location update is
* returned via the {#link LocationListener} specified in {#link
* setChangedLocationListener}.
*/
private LocationListener singeUpdateListener = new LocationListener() {
public void onLocationChanged(Location location) {
Log.d(TAG, "Got a location update");
if (location == null) {
Log.d(TAG, "Seems as if we got a null location");
} else {
bestResult = location;
}
cleanup();
locationListenerWorking = false;
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
}
Then in your calling class (i.e. where you need the lat/lon coordinates - you want to do this from an Activity):
private class GetLocationTask extends AsyncTask <Void, Void, Location> {
private Future<Location> future;
private ExecutorService executor = new ScheduledThreadPoolExecutor(5);
private boolean cancelTriggered = false;
protected void onPreExecute() {
Log.d(TAG, "Starting location get...");
}
public Location doInBackground(Void... arg) {
CurrentLocation currLoc = new CurrentLocation(getApplicationContext());
future = executor.submit(currLoc);
long LOCATION_TIMEOUT = 20000; // ms = 20 sec
try {
// return future.get(Constants.LOCATION_TIMEOUT, TimeUnit.MILLISECONDS);
return future.get(LOCATION_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (Exception e) {
Log.w(TAG, "Location get timed out");
future.cancel(true);
return null;
}
}
public boolean killTask() {
cancelTriggered = true;
boolean futureCancelRes = future.cancel(true);
this.cancel(true);
Log.d(TAG, "Result of cancelling task: " +futureCancelRes);
return futureCancelRes;
}
protected void onPostExecute(Location res) {
if (cancelTriggered) {
Log.d(TAG, "User initiated cancel - this is okay");
cancelTriggered = false;
} else if (res == null) {
Log.d(TAG, "Could not get a location result");
} else {
double lat = res.getLatitude();
double lon = res.getLongitude();
Log.d(TAG, "Latitude: " +lat);
Log.d(TAG, "Longitude: " +lon);
}
}
}
Finally to wrap things up, here's how you call it:
GetLocationTask t = new GetLocationTask();
t.execute();
And if you need to kill the location update for whatever reason (if your user switches out of your activity, etc), this will kill the AsyncTask as well as the associated Future task.
t.killTask();
P.S. You may want to get your API keys changed and edit it out of your post.