First of all I am new to android and JAVA and as registered user of stackoverflow, but it helped me many times to find a good answer so, thank you for this community, got me many times out of mud with my school projects
I am here because I'm stuck in this small project, is an university one so no money involved.
I am trying to get a route displayed and update it as I move through the city using android google maps api. Until now I managed to get my location, and I can display a route between two points, but the problem is when I want to have the starting point from my current location, it seems I can't save it to a variable (or I don't know how) I used google example for map display as base.
I will post the entire code, maybe someone can also find it useful. Since is an university small project I don't have secrets to hide and I am here to learn so is nice to post the full code.
If someone has a hint for my problem I would appreciate. Thank you!
NOTE: the problem is getting this baby displaying the route from my current location to the second location that is a fixed one.
The main code is the following:
public class mapDisplay extends ActionBarMapActivity {
private LocationManager myLocationManager;
private LocationListener myLocationListener;
private MapController myMapController;
private MapView myMapView;
private MyLocationOverlay myLocation;
private void CenterLocatio(GeoPoint centerGeoPoint)
{
myMapController.animateTo(centerGeoPoint);
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_screen);
myMapView = (MapView) findViewById(R.id.mapview);
//mapView.setBuiltInZoomControls(true);
myMapView.setSatellite(false); //Set satellite view
myMapController = myMapView.getController();
myMapController.setZoom(15); //Fixed Zoom Level
myLocationManager = (LocationManager)getSystemService(
Context.LOCATION_SERVICE);
//For enable location services dialogue
if (!myLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
createGpsDisabledAlert();
}
// see createGpsDisabledAlert function below
myLocationListener = new MyLocationListener();
myLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0,
myLocationListener);
//Get the current location in start-up
GeoPoint initGeoPoint = new GeoPoint(
(int)(myLocationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER)
.getLatitude()*1000000),
(int)(myLocationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER)
.getLongitude()*1000000));
CenterLocatio(initGeoPoint);
//draw the sample route
MapView mv = (MapView) findViewById(R.id.mapview);
mv.setBuiltInZoomControls(true);
MapController mc = mv.getController();
ArrayList all_geo_points = getDirections(50.0536, 8.69339, 50.021973, 8.69584);
GeoPoint moveTo = (GeoPoint) all_geo_points.get(0);
mc.animateTo(moveTo);
mc.setZoom(12);
mv.getOverlays().add(new MyOverlay(all_geo_points));
//Adding position icon for current location
// Add the MyLocationOverlay
myLocation = new MyLocationOverlay(this, myMapView);
myMapView.getOverlays().add(myLocation);
myLocation.enableMyLocation();
myLocation.runOnFirstFix(new Runnable() {
public void run() {
myMapController.animateTo(myLocation.getMyLocation());
}
});
}
private class MyLocationListener implements LocationListener{
public void onLocationChanged(Location argLocation) {
// TODO Auto-generated method stub
GeoPoint myGeoPoint = new GeoPoint(
(int)(argLocation.getLatitude()*1000000),
(int)(argLocation.getLongitude()*1000000));
CenterLocatio(myGeoPoint);
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
//toast shown if GPS is disabled
Context context = getApplicationContext();
CharSequence text = "GPS is disabled! If you want to take full advantage of map please enable the GPS!";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider,
int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
#Override
protected void onResume() {
super.onResume();
myLocation.enableMyLocation();
}
#Override
protected void onPause() {
super.onPause();
myLocation.disableMyLocation();
}
//Back button press returns to first activity (selection screen)
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
//super.onBackPressed();
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
//rest of functions for GPS alert
private void createGpsDisabledAlert(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Your GPS is disabled! Would you like to enable it?")
.setCancelable(false)
.setPositiveButton("Enable GPS",
new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){
showGpsOptions();
}
});
builder.setNegativeButton("Do nothing",
new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private void showGpsOptions(){
Intent gpsOptionsIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(gpsOptionsIntent);
}
//Testing - directions
public static ArrayList getDirections(double lat1, double lon1, double lat2, double lon2) {
String url = "http://maps.googleapis.com/maps/api/directions/xml?origin=" +lat1 + "," + lon1 + "&destination=" + lat2 + "," + lon2 + "&sensor=false&units=metric";
String tag[] = { "lat", "lng" };
ArrayList list_of_geopoints = new ArrayList();
HttpResponse response = null;
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);
response = httpClient.execute(httpPost, localContext);
InputStream in = response.getEntity().getContent();
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(in);
if (doc != null) {
NodeList nl1, nl2;
nl1 = doc.getElementsByTagName(tag[0]);
nl2 = doc.getElementsByTagName(tag[1]);
if (nl1.getLength() > 0) {
list_of_geopoints = new ArrayList();
for (int i = 0; i < nl1.getLength(); i++) {
Node node1 = nl1.item(i);
Node node2 = nl2.item(i);
double lat = Double.parseDouble(node1.getTextContent());
double lng = Double.parseDouble(node2.getTextContent());
list_of_geopoints.add(new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6)));
}
} else {
// No points found
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list_of_geopoints;
}}
EDIT 10.07.2012: I start to wonder if is a stupid question, no one knows the answer or no one wants to answer.
I have tried to save into local variables and use them in get Directions() function but for some reason is crashing my app. Or better, I am invited to fix the error before compiling.
Related
I am new in Android developing, and took a hard one for first project. :D
So the back story :
I have MapActivity what gets MapMarkers from MySql DB (php -> Json)
Now I have a map where are some Marks and user location is known.
And what I want to do?
Simple.. when user gets near to marker (lets say 20m) then he will get
popup where he can submit that he is there..
Problem is that I have no idea how to do it..
My Code is bad, but it works :D.
For rights I have fast workaround (Lenovo tab is with bit old Android, but other way works on Android 7.1.. I hope someone can help me out here. :).
public class kaart extends FragmentActivity implements OnMapReadyCallback {
MapFragment mapFragment;
GoogleMap gMap;
MarkerOptions markerOptions = new MarkerOptions();
CameraPosition cameraPosition;
LatLng center, latLng;
String title;
String kirjeldus;
String vahend;
public static final String ID = "id"; //god to use for marker detection
public static final String TITLE = "nimi";
public static final String KIRJELDUS = "kirjeldus";
public static final String LAT = "lat";
public static final String LNG = "lng";
public static final String VAHEND = "vahend";
private String url = "https://lammerdis.ee/orient/";
String tag_json_obj = "json_obj_req";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.kaart);
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.kaart);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
gMap = googleMap;
gMap.getUiSettings().setMapToolbarEnabled(false);
gMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); //Võimalikud valikud MAP_TYPE_SATELLITE, MAP_TYPE_TERRAIN, MAP_TYPE_HYBRID, MAP_TYPE_NORMAL
gMap.getUiSettings().setZoomControlsEnabled(true);
gMap.getUiSettings().setCompassEnabled(true);
gMap.getUiSettings().setMyLocationButtonEnabled(true);
gMap.getUiSettings().setZoomGesturesEnabled(true);
// Kaardi alguse asukoha Zoomime Aida juurde
center = new LatLng(59.175597, 25.022103);
cameraPosition = new CameraPosition.Builder().target(center).zoom(10).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
getMarkers();
}
private void addMarker(LatLng latlng, final String title, final String kirjeldus, final String vahend) {
markerOptions.position(latlng);
markerOptions.title(title);
markerOptions.snippet(kirjeldus);
if (vahend.equalsIgnoreCase("auto")) {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.auto));
} else {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.jala)); }
gMap.addMarker(markerOptions);
}
// Korjame JSON-ist punktid kokku
private void getMarkers() {
StringRequest strReq = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("Response: ", response.toString());
try {
JSONObject jObj = new JSONObject(response);
String getObject = jObj.getString("punktid");
JSONArray jsonArray = new JSONArray(getObject);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
title = jsonObject.getString(TITLE);
kirjeldus = jsonObject.getString(KIRJELDUS);
vahend = jsonObject.getString(VAHEND);
latLng = new LatLng(Double.parseDouble(jsonObject.getString(LAT)), Double.parseDouble(jsonObject.getString(LNG)));
// Kuvame andmed kaardile
addMarker(latLng, title, kirjeldus, vahend);
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error: ", error.getMessage());
Toast.makeText(kaart.this, error.getMessage(), Toast.LENGTH_LONG).show();
}
});
AppController.getInstance().addToRequestQueue(strReq, tag_json_obj);
//kui punktid kaardil ja seadmes on lubatud asukohta otsida, siis kuvame kasutaja asukoha ka
//Kui on vanem android siis saame Manifestis kirjeldatud õigustega hakkama ja saaba sukoha kuvatud
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
gMap.setMyLocationEnabled(true); //Kuvab asukoha punktina kaardil
gMap.getUiSettings().setMyLocationButtonEnabled(true); // Kuvab asukoha nupu (viskab ilusti oma asukohale)
} else {
//Kui on android 6.0 või uuem siis tuleb õiguseid küsida rakenduse käivitamisel
ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION },
PackageManager.PERMISSION_GRANTED);
//Kui õigused on lubatud siis tuleb neid rakendada, kõige lihtsam on kasutajale pasundada, et rakenduse restardiks
final Toast tag = Toast.makeText(this, R.string.OIGUSE_INFO, Toast.LENGTH_LONG);
tag.show();
new CountDownTimer(50000, 1000)
{
public void onTick(long millisUntilFinished) {tag.show();}
public void onFinish() {tag.show();}
}.start();
}
}
}
You can set up GeoFences ( https://developer.android.com/training/location/geofencing.html ) with these you can create an area where when the user enters it or it you will get an intent in your intent service then it's just a matter of use that info wherever you like.
This is my first time working with Google Maps so sorry if this is a beginner problem. I am working on an app that connects to a portable sensor. The sensor sends pollution data every 2 minutes. Every time I get new data, a marker is placed on google maps and I want to show the data in the info window of the markers so that you can see how the pollution differs depending on where you are.
My problem is that as of now, all my markers info windows are updated with the newest data. I need to make it so that every marker has their own separate info window with unique data.
I think that I need to implement OnInfoWindowClickListener somehow and also that I need the ID of every marker. I have tried to look at answers in other threads and so far I have not understood how I should solve this problem.
Appreciate any help I can get
This is my code right now.
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
....
/* Here we create the infoWindow **/
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
public View getInfoWindow(Marker arg0) {
View v = getLayoutInflater().inflate(R.layout.custom_infowindow, null);
TextView tv = (TextView) v.findViewById(R.id.infoText);
tv.setText("CO2 data: "+String.valueOf(co_mV) + "mV" +"\n" + "N2 data: "+String.valueOf(no2_mV) +" mV");
return v;
}
public View getInfoContents(Marker arg0) {
return null;
}
});
}
....
#Override
public void onLocationChanged(Location location) {
if (!initiateApp) {
if(location.distanceTo(mLastLocation) < 20) {
markerArrayList.get(markerArrayList.size()-1).remove();
markerArrayList.remove(markerArrayList.size()-1);
Toast.makeText(
getApplicationContext(),
"Reading to close to last reading, replace last reading", Toast.LENGTH_SHORT).show();
}
}
if (markerArrayList.size() == 3) {
markerArrayList.get(0).remove();
markerArrayList.remove(0);
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
markerArrayList.add(mCurrLocationMarker);
mLastLocation = location;
Log.d("ADebugTag", "Value: " + Double.toString(location.getLatitude()));
Log.d("ADebugTag", "Value: " + Double.toString(location.getLongitude()));
//move map camera
if(initiateApp){
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
}
initiateApp = false;
boolean contains = mMap.getProjection()
.getVisibleRegion()
.latLngBounds
.contains(latLng);
if(!contains){
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
}
EDIT The data I want to show is "co_mV" and "no2_mV".
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
try {
JSONObject parser = new JSONObject(values[0]);
JSONObject d = parser.getJSONObject("d");
co_mV = d.getInt("co_mV");
no2_mV = d.getInt("no2_mV");
} catch (JSONException e) {
e.printStackTrace();
}
newData();
//response received from server
Log.d("CO2", values[0]);
long timeStamp = System.currentTimeMillis() / 1000L;
time=new java.util.Date((long)timeStamp*1000);
//process server response here....
}
}
create a infowWindowAdapter like this
public class YourCustomInfoWindowAdpater implements GoogleMap.InfoWindowAdapter {
private final View mymarkerview;
private Context context;
private List<YourModelClass> nearByModel;
private Location currentMarker;
public YourCustomInfoWindowAdpater(Context context) {
this.context = context;
currentMarker = new Location();
mymarkerview = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.custominfowindow, null);
}
public View getInfoWindow(Marker marker) {
render(marker, mymarkerview);
return mymarkerview;
}
public View getInfoContents(Marker marker) {
View v = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.custominfowindow, null);
// Getting the position from the marker
LatLng latLng = marker.getPosition();
// Getting reference to the TextView to set latitude
/* TextView tvLat = (TextView) v.findViewById(R.id.tv_lat);
// Getting reference to the TextView to set longitude
TextView tvLng = (TextView) v.findViewById(R.id.tv_lng);
// Setting the latitude
tvLat.setText("Latitude:" + latLng.latitude);
// Setting the longitude
tvLng.setText("Longitude:"+ latLng.longitude);*/
// Returning the view containing InfoWindow contents
return v;
}
private void render(Marker marker, View view) {
TextView place_distance = (TextView) view.findViewById(R.id.place_distance);
// Add the code to set the required values
// for each element in your custominfowindow layout file
}
public void setModels(List<YourModelclass> nearByModel) {
this.nearByModel = nearByModel;
}
}
first of all call YourCustomInfoWindowAdpater yourInfo=new YourCustomInfoWindowAdpater(this);
then set googleMap.setInfoWindowAdapter(yourInfo);
and as soon as you get data call setModels method of yourcustominfowindowadpater in which pass your data model
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 a Google maps app that grabs the users lat and long values, and through the use of a Google JSON response stores a range of supermarket objects with their relative lat and long values. I use an overlay class to the place a marker onto the map dependent on the selected supermarket from the listview that shows the available supermarkets.
This all works fine, where I seem to be having a slight issue is with the accuracy of my overlay class. The map marker doesn't seem to be very accurate, in that the marker is pointing at the wrong place of the specified lat and long points passed to it from my geopoint object. (sometimes up to 11 miles away from where it should be).
I have tried declaring the LOCATION_FINE in my manifest on the uses permissions but this doesn't seem to make any difference. Do I need this as I'm using a JSON response rather than GPS?
How accurate is the map on the emulator? I may-be clutching at straws here but I have heard multiple people saying that when using the Google API's on the emulator it isn't that accurate.
No GPS is being used.
EDIT
To add to this question. I have another question that goes into more depth. I believe the issue is within my update() method as the issue is the incorrect object lat and long values are being sent to the marker.
I will post my code, just to see if anyone can find any issues.
GeoName class:
public class GeoName {
private String id;
private Geometry geometry;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Geometry getGeometry() {
return geometry;
}
public void setGeometry(Geometry geometry) {
this.geometry = geometry;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
PostalCodeAdapter class:
package com.example.restfulweb;
public class PostalCodeAdapter extends BaseAdapter {
private Context ctx = null;
Location l;
Dialog d;
Double Latt;
Double Longg;
private List<GeoName> names = new ArrayList<GeoName>();
public PostalCodeAdapter(Context ctx, List<GeoName> locations) {
this.ctx = ctx;
this.names = locations;
}
#Override
public int getCount() {
return names.size();
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
LinearLayout layout = new LinearLayout(ctx);
AbsListView.LayoutParams params = new AbsListView.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
layout.setLayoutParams(params);
layout.setOrientation(LinearLayout.HORIZONTAL);
GeoName location = this.names.get(arg0);
Location l = location.getGeometry().getLocation();
Latt = l.getLat();
Longg = l.getLng();
TextView value = new TextView(this.ctx);
value.setText(location.getName());
value.setMaxHeight(100);
value.setTypeface(Typeface.DEFAULT, Typeface.NORMAL);
value.setGravity(Gravity.CENTER);
value.setOnClickListener(new CityClickListener(location));
layout.addView(value);
return layout;
}
class CityClickListener implements OnClickListener {
private GeoName geoName = null;
CityClickListener(GeoName name) {
this.geoName = name;
}
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setView(createView());
builder.setTitle("Details of " + geoName.getName());
builder.setCancelable(true);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
updateMap();
}
private void updateMap() {
MapActivity mapAct = (MapActivity)ctx;
MapView map = (MapView)mapAct.findViewById(R.id.map);
map.setScrollBarStyle(MapView.SCROLLBARS_INSIDE_INSET);
map.setBuiltInZoomControls(Boolean.TRUE);
map.displayZoomControls(Boolean.TRUE);
********** ISSUE: THE PASSED LAT AND LONG VALUES ARE NOT BEING PASSED TO THE OVERLAY **********
GeoPoint point = new GeoPoint((int)(Latt* 1E6), (int)(Longg * 1E6));
MapController mc = map.getController();
mc.setZoom(17);
mc.setCenter(point);
mc.animateTo(point);
List<Overlay> overlay = map.getOverlays();
overlay.clear();
Drawable marker = ctx.getResources().getDrawable(R.drawable.marker);
MyItemizedOverlay overlays = new MyItemizedOverlay(marker, map, ctx);
OverlayItem pointerConverted = new OverlayItem(point, geoName.getName(), null);
overlay.add(overlays);
overlays.addOverlay(pointerConverted);
}
private View createView() {
LinearLayout l = new LinearLayout(ctx);
l.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams params = new LayoutParams(100, 300);
l.setLayoutParams(params);
TextView city = new TextView(ctx);
city.setText("Supermarket: " + geoName.getName() + "");
city.setMaxHeight(100);
city.setTypeface(Typeface.DEFAULT, Typeface.NORMAL);
city.setGravity(Gravity.CENTER);
//city.setTextColor(ctx.getResources().getColor(R.color.white));
TextView orientation = new TextView(ctx);
//orientation.setText("Orientation : " + geoName.lat + " || " + geoName.lng);
orientation.setMaxHeight(100);
orientation.setTypeface(Typeface.DEFAULT, Typeface.NORMAL);
orientation.setGravity(Gravity.CENTER);
l.addView(city);
l.addView(orientation);
return l;
}
}
}
Managed to sort this.
For anyone else who is using a JSON layered response. Make sure you access you lat and long values from the correct GeoPoint object classes.
for simplicity you can use Google Maps Android API v2 with recent updates your task becomes simpler.
https://developers.google.com/maps/documentation/android/start
You just need to create GoogleMap object and add appropriate listeners.
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.