I tried to use reverse geocoding with AsyncTask but but the parameters of latitude and longitude that passes through the method doInBackground() are not happening correctly. any idea?
public class SitesAdapter extends ArrayAdapter<StackSite> {
public static Double lat;
public static Double lng;
#Override
public View getView(int pos, View convertView, ViewGroup parent){
...
lat = -1.80;
lng = -80.20;
...
}
public void start(){
new GetAddressTask(mContext).execute(lat, lng);
}
public static class GetAddressTask extends AsyncTask<Double, Void, String> {
//mContext
#Override
protected String doInBackground(Double... params) {
Geocoder gc = new Geocoder(mContext, Locale.getDefault());
List<Address> list = null;
String city = "";
double latitude = params[0];
double longitude = params[1];
try {
list = gc.getFromLocation(lat, lng, 1);
} catch (IOException e) {
e.printStackTrace();
}
if (list != null && list.size() > 0) {
Address address = list.get(0);
city = String.format("%s, %s", address.getAdminArea(), address.getCountryName());
}
return city;
}
#Override
protected void onPostExecute(String city) {
tituloTxt.setText(city);
}
}
}
error:
11-21 15:10:24.409: E/Trace(24502): error opening trace file: No such file or directory (2)
Well after so only had to do this to pass the coordinates. First add coordinate to constructor LatLng(double latitude, double longitude) and pass the parameters.
lat = -1.80;
lng = -80.20;
LatLng latlng = new LatLng(lat, lng);
new GetAddressTask(mContext).execute(lat, lng);
Then inside the doInbackground method get parameters.
public static class GetAddressTask extends AsyncTask<LatLng, Void, String> {
//mContext
#Override
protected String doInBackground(LatLng... params) {
Geocoder gc = new Geocoder(mContext, Locale.getDefault());
List<Address> list = null;
String city = "";
LatLng loc = params[0]; //Get all parameters: latitude and longitude
try {
list = gc.getFromLocation(loc.latitude, loc.longitude, 1); //get specific parameters
} catch (IOException e) {
e.printStackTrace();
}
if (list != null && list.size() > 0) {
Address address = list.get(0);
city = String.format("%s, %s", address.getAdminArea(), address.getCountryName());
return city;
}else{
return "City no found";
}
}
#Override
protected void onPostExecute(String city) {
tituloTxt.setText(city);
}
}
before calling execute method, u can just create a constructor ,in which you can initialize your class data members which can be further used in doInBackground(..).
Add two variables to your class and set them when you create async task, then use them in method. Simple.
public class GetAddressTask extends AsyncTask<String, Void, String> {
Context mContext;
float lat,lin;
public void setLat(int lat){...}
//rest of class
of course you can make everything static (fields and setters).
Edit.
If you are calling execute with some parameters, remember that your values have to be set before calling execute.
Related
I created a new file for my AsyncTask, so I can break up my code into MVP.
File: TranslateAddress.java
public class TranslateAddress extends AsyncTask<String, Void, String> {
final Dialog customDialog = new Dialog(MainActivity.this);
protected void onPreExecute() {
super.onPreExecute();
customDialog.setContentView(R.layout.custom_location_dialog);
customDialog.setTitle("Looking for address");
TextView text = (TextView) customDialog.findViewById(R.id.textView);
text.setText("Looking for address");
customDialog.show();
}
protected String doInBackground(String... params) {
Geocoder geocoder;
List<Address> addresses = null;
geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
if (geocoder != null) {
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
} catch (IOException e) {
e.printStackTrace();
}
address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
city = addresses.get(0).getLocality();
state = addresses.get(0).getAdminArea();
country = addresses.get(0).getCountryName();
postalCode = addresses.get(0).getPostalCode();
knownName = addresses.get(0).getFeatureName(); // Only if available else return NULL
// do download here
} else {
Log.e("Error", "Geocoder returned Null");
MainActivity.OpenFragment("SolicitationFramgnet");
}
return null;
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
//dialog.dismiss();
customDialog.dismiss();
EditText localText = (EditText) findViewById(R.id.localText);
if (localText != null) {
localText.setText(address);
}
}
}
These are the lines that have errors:
final Dialog customDialog = new Dialog(MainActivity.this);
Error: MainActivity is not an enclosing class
geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
Error: Same as above, MainActivity is not an enclosing class
MainActivity.OpenFragment("SolicitationFramgnet");
Error: Non static method OpenFragment cannot be referenced from a static context. This error I can fix by making OpenFragment static, however, it breaks half of the code inside it.
EditText localText = (EditText) findViewById(R.id.localText);
Error: Cannot resolve method "findViewById(int)"
Moving your AsyncTask to another .java file you lose the reference of your MainActivity because before it functioned as an InnerClass and now it is just a Java Class, so you cannot use MainActivity methods or static context in this situation. Is the same thing for findViewById method because it belongs to your Activity and not to your AsyncTask. To fix it you have to pass the context in your Constructor and the main layout so you can use FindViewById method inside your TranslateAddress file using this View (as a parameter of your constructor).
Something like this:
public class TranslateAddress extends AsyncTask<String, Void, String> {
final Dialog customDialog;
private MainActivity mainActivity;
private View view;
public TranslateAddress(View view, MainActivity mainActivity){
this.view = view;
this.mainActivity = mainActivity;
}
protected void onPreExecute() {
super.onPreExecute();
customDialog = new Dialog(mainActivity);
customDialog.setContentView(R.layout.custom_location_dialog);
customDialog.setTitle("Looking for address");
TextView text = (TextView) customDialog.findViewById(R.id.textView);
text.setText("Looking for address");
customDialog.show();
}
protected String doInBackground(String... params) {
Geocoder geocoder;
List<Address> addresses = null;
geocoder = new Geocoder(mainActivity, Locale.getDefault());
if (geocoder != null) {
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
} catch (IOException e) {
e.printStackTrace();
}
address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
city = addresses.get(0).getLocality();
state = addresses.get(0).getAdminArea();
country = addresses.get(0).getCountryName();
postalCode = addresses.get(0).getPostalCode();
knownName = addresses.get(0).getFeatureName(); // Only if available else return NULL
// do download here
} else {
Log.e("Error", "Geocoder returned Null");
mainActivity.OpenFragment("SolicitationFramgnet");
}
return null;
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
//dialog.dismiss();
customDialog.dismiss();
EditText localText = (EditText) view.findViewById(R.id.localText);
if (localText != null) {
localText.setText(address);
}
}
}
For context, pass it from your MainActivity like this:
In AsyncTask, Create a constructor
Context context;
TranslateAddress(Context c){
context = c;
}
Now use context instead of MainActivity.this. And execute AsyncTask from MainActivity as following:
new TranslateAddress(this).execute();
and for findViewById(), use following code:
context.findViewById("YOUR_ID");
I'm working on a small app and have implemented Google Maps and Places api. Currently i'm able to see all my markers on the map and clustering working fine. I'm able to zoom in the clusters open up and able to see the markers. I have a spinner that has different types and once selected that type is passed to the places search string.
This is my maps code that includes the clustering:
public class MapsActivity extends FragmentActivity implements LocationListener,ClusterManager.OnClusterItemInfoWindowClickListener<MyItem> {
GoogleMap mMap;
double myLatitude = 0;
double myLongitude = 0;
HashMap<String, String> mMarker = new HashMap<String, String>();
PlaceJSONParser placeJsonParser = new PlaceJSONParser();
private ClusterManager<MyItem> mClusterManager;
protected MyItem clickedClusterItem;
String[] placeType;
String[] placeTypeName;
Spinner spinPlaceType;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mMap = mapFragment.getMap();
onMapReady();
// Array of place types
placeType = getResources().getStringArray(R.array.placeType);
// Array of place type names
placeTypeName = getResources().getStringArray(R.array.placeTypeName);
// Creating an array adapter with an array of Place types
// to populate the spinner
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.spinner_item, R.id.textview, placeTypeName);
// Getting reference to the Spinner
spinPlaceType = (Spinner) findViewById(R.id.spinPlaceType);
// Setting adapter on Spinner to set place types
spinPlaceType.setAdapter(adapter);
spinPlaceType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
int selectedPosition = spinPlaceType.getSelectedItemPosition();
final String type = placeType[selectedPosition];
StringBuilder sb = new StringBuilder(
"https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
sb.append("location=" + myLatitude + "," + myLongitude);
sb.append("&type=" + type);
sb.append("&radius=4000");
sb.append("&key=PLACES_KEY");
// Creating a new non-ui thread task to download Google place json
// data
PlacesTask placesTask = new PlacesTask();
// Invokes the "doInBackground()" method of the class PlaceTask
placesTask.execute(sb.toString());
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
StringBuilder sb = new StringBuilder(
"https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
sb.append("location=" + myLatitude + "," + myLongitude);
sb.append("&type=restaurant");
sb.append("&radius=4000");
sb.append("&key=PLACES_KEY");
// Creating a new non-ui thread task to download Google place json
// data
PlacesTask placesTask = new PlacesTask();
// Invokes the "doInBackground()" method of the class PlaceTask
placesTask.execute(sb.toString());
}
});
// Will display next 20 places returned form the next_page_token
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab_more);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Finding you some more places.", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
StringBuilder sb = new StringBuilder(
"https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
sb.append("pagetoken=" + placeJsonParser.getNext_Page_token());
sb.append("&key=PLACES_KEY");
// Creating a new non-ui thread task to download Google place json
// data
if (placeJsonParser.getNext_Page_token() == null || placeJsonParser.getNext_Page_token() == ""){
Snackbar.make(view, "No more places left to find.", Snackbar.LENGTH_SHORT)
.setAction("Action", null).show();
}
PlacesTask placesTask = new PlacesTask();
// Invokes the "doInBackground()" method of the class PlaceTask
placesTask.execute(sb.toString());
}
});
mMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker marker) {
Intent detailsIntent = new Intent(getBaseContext(), PlaceDetailsActivity.class);
String reference = mMarker.get(marker.getId());
marker.getPosition();
detailsIntent.putExtra("reference", reference);
detailsIntent.putExtra("markerLat", myLatitude);
detailsIntent.putExtra("markerLong", myLongitude);
startActivity(detailsIntent);
}
});
}
public void onMapReady(){
// Enabling MyLocation in Google Map
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setCompassEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
// Getting LocationManager object from System Service
// LOCATION_SERVICE
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
// Creating a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Getting the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location From GPS
Location location = locationManager.getLastKnownLocation(provider);
// onLocationChanged(location);
if (location != null) {
onLocationChanged(location);
}
}
/**
* A method to download json data from url
*/
private String downloadUrl(String strUrl) throws IOException {
String referer ="";
StringBuilder jsonResults = new StringBuilder();
HttpURLConnection conn = null;
try {
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
conn = (HttpURLConnection) url.openConnection();
if (referer != null) {
conn.setRequestProperty("Referer", referer);
}
InputStreamReader in = new InputStreamReader(conn.getInputStream());
// Load the results into a StringBuilder
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
// Displays the list of places found in the terminal.
Log.i("Data", "Places Found: " + jsonResults);
} catch (MalformedURLException e) {
Log.i("Google Places Utility", "Error processing Places API URL");
return null;
} catch (IOException e) {
Log.i("Google Places Utility", "Error connecting to Places API");
return null;
} finally {
if (conn != null) {
conn.disconnect();
}
}
return jsonResults.toString();
}
/**
* A class, to download Google Places
*/
private class PlacesTask extends AsyncTask<String, Integer, String> {
String data = null;
// Invoked by execute() method of this object
#Override
protected String doInBackground(String... url) {
try {
data = downloadUrl(url[0]);
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
// Executed after the complete execution of doInBackground() method
#Override
protected void onPostExecute(String result) {
ParserTask parserTask = new ParserTask();
// Start parsing the Google places in JSON format
// Invokes the "doInBackground()" method of the class ParseTask
parserTask.execute(result);
}
}
/**
* A class to parse the Google Places in JSON format
*/
private class ParserTask extends
AsyncTask<String, Integer, List<HashMap<String, String>>> {
JSONObject jObject;
// Invoked by execute() method of this object
#Override
protected List<HashMap<String, String>> doInBackground(
String... jsonData) {
List<HashMap<String, String>> places = null;
try {
jObject = new JSONObject(jsonData[0]);
/** Getting the parsed data as a List construct */
places = placeJsonParser.parse(jObject);
} catch (Exception e) {
Log.d("Exception", e.toString());
}
return places;
}
// Executed after the complete execution of doInBackground() method
#Override
protected void onPostExecute(List<HashMap<String, String>> list) {
// Clears all the existing markers
mMap.clear();
setUpClusterer(list);
}
}
private void setUpClusterer(List<HashMap<String, String>> list) {
// Position the map.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(myLatitude,myLongitude), 13));
// Initialize the manager with the context and the map.
// (Activity extends context, so we can pass 'this' in the constructor.)
mClusterManager = new ClusterManager<MyItem>(this, mMap);
// Point the map's listeners at the listeners implemented by the cluster
// manager.
mMap.setOnCameraChangeListener(mClusterManager);
mMap.setOnMarkerClickListener(mClusterManager);
mMap.setInfoWindowAdapter(mClusterManager.getMarkerManager());
mMap.setOnInfoWindowClickListener(mClusterManager);
mClusterManager.setOnClusterItemInfoWindowClickListener(this);
mClusterManager
.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() {
#Override
public boolean onClusterItemClick(MyItem item) {
clickedClusterItem = item;
return false;
}
});
// Add cluster items (markers) to the cluster manager.
addItems(list);
mClusterManager.getMarkerCollection().setOnInfoWindowAdapter(
new MyCustomAdapterForItems());
}
public class MyCustomAdapterForItems implements GoogleMap.InfoWindowAdapter {
private final View myContentsView;
MyCustomAdapterForItems() {
myContentsView = getLayoutInflater().inflate(
R.layout.info_window, null);
}
#Override
public View getInfoWindow(Marker marker) {
TextView tvTitle = ((TextView) myContentsView
.findViewById(R.id.txtTitle));
TextView tvSnippet = ((TextView) myContentsView
.findViewById(R.id.txtSnippet));
tvTitle.setText(clickedClusterItem.getTitle());
tvSnippet.setText(clickedClusterItem.getSnippet());
return myContentsView;
}
#Override
public View getInfoContents(Marker marker) {
return null;
}
}
private void addItems(List<HashMap<String, String>> list) {
double latitude;
double longitude;
for (int i = 0; i < list.size(); i++) {
HashMap<String, String> hmPlace = list.get(i);
// Getting latitude of the place
latitude = Double.parseDouble(hmPlace.get("lat"));
// Getting longitude of the place
longitude = Double.parseDouble(hmPlace.get("lng"));
String name = hmPlace.get("place_name");
// Getting vicinity
String vicinity = hmPlace.get("vicinity");
MyItem offsetItem = new MyItem(latitude, longitude, hmPlace.get("reference"), name, vicinity);
mClusterManager.addItem(offsetItem);
}
}
public void onClusterItemInfoWindowClick(MyItem item) {
Intent placesIntent = new Intent(getBaseContext(), PlaceDetailsActivity.class);
String reference = item.getReference();
placesIntent.putExtra("name", item.getTitle());
placesIntent.putExtra("reference", reference);
placesIntent.putExtra("sourcelat", myLatitude);
placesIntent.putExtra("sourcelng", myLongitude);
startActivity(placesIntent);
}
#Override
public void onLocationChanged(Location location) {
myLatitude = location.getLatitude();
myLongitude = location.getLongitude();
LatLng myLocation = new LatLng(myLatitude, myLongitude);
mMap.moveCamera(CameraUpdateFactory.newLatLng(myLocation));
mMap.animateCamera(CameraUpdateFactory.zoomTo(13));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
my myItem class to get info for the markers:
package com.example.tariq.outandabout;
import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.clustering.ClusterItem;
public class MyItem implements ClusterItem {
LatLng mPosition;
private String reference,placeTitle,snippet;
public MyItem(double lat, double lng,String val,String title, String snip) {
mPosition = new LatLng(lat, lng);
reference=val;
placeTitle=title;
snippet = snip;
}
#Override
public LatLng getPosition() {
// TODO Auto-generated method stub
return mPosition;
}
public String getReference() {
// TODO Auto-generated method stub
return reference;
}
public String getTitle() {
// TODO Auto-generated method stub
return placeTitle;
}
public String getSnippet() {
// TODO Auto-generated method stub
return snippet;
}
}
Currently only red markers are getting displayed but I was wondering if there is a way to have a different markers depending on the type selected from the spinner, For example if I select Hospital then the markers are shown as little hospital icons, if I select ATM, then a little ATM icon appears.
Any help will be appreciated.
Firstly you have to store all the info you need (at this situation just LatLng and marker icon) insite ClusterItem object.
public class MarkerItem implements ClusterItem {
private String title;
private String snippet;
private LatLng latLng;
private BitmapDescriptor icon;
public MarkerItem(MarkerOptions markerOptions) {
this.latLng = markerOptions.getPosition();
this.title = markerOptions.getTitle();
this.snippet = markerOptions.getSnippet();
this.icon = markerOptions.getIcon();
}
#Override
public LatLng getPosition() {
return latLng;
}
public String getTitle() {
return title;
}
public String getSnippet() {
return snippet;
}
public void setLatLng(LatLng latLng) {
this.latLng = latLng;
}
public BitmapDescriptor getIcon() {
return icon;
}
public void setIcon(BitmapDescriptor icon) {
this.icon = icon;
}
}
The next step would be to make cluster renderer show your icon instead of default maker icon. To achieve that, you need to extend DefaultClusterRenderer object:
public class ClusterRenderer extends DefaultClusterRenderer<MarkerItem> {
public ClusterRenderer(Context context, GoogleMap map, ClusterManager<MarkerItem> clusterManager) {
super(context, map, clusterManager);
clusterManager.setRenderer(this);
}
#Override
protected void onBeforeClusterItemRendered(MarkerItem markerItem, MarkerOptions markerOptions) {
if (markerItem.getIcon() != null) {
markerOptions.icon(markerItem.getIcon()); //Here you retrieve BitmapDescriptor from ClusterItem and set it as marker icon
}
markerOptions.visible(true);
}
}
Finally, you have to initialize the clusterRenderer and markerItems
ClusterManager clusterManager = new ClusterManager<>(context, googleMap);
ClusterRenderer clusterRenderer = new ClusterRenderer<>(activity, googleMap, clusterManager); // not needed to use clusterManager.setRenderer method since i made it in constructor
MarkerOptions markerOptions = new MarkerOptions()
.position(new LatLng(latitude, longitude))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.your_resource_icon));
MarkerItem markerItem = new MarkerItem(markerOptions);
clusterManager.addItem(markerItem);
You can implement your own logic, which icon you want to pass to markerItem here.
EDIT
To pass different icons, you could create a separate method for that
Example:
public MarkerOptions getMarkerOptions(LatLng latLng, String title, String snippet, int iconRes) {
return new MarkerOptions()
.title(title)
.snippet(snippet)
.position(latLng)
.icon(BitmapDescriptorFactory.fromResource(iconRes));
}
EDIT 2
I updated MarkerItem class to suit your needs, replace your MyItem class with MarkerItem class. Add your items using this class and update it to suit your needs
I have created a infowindow for a marker and trying to set the address of a particular location by tapping on it but its not doing anything. Where am I making mistake?
map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
LayoutInflater layoutInflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.info_window, null, false);
anchor_name = (TextView) view.findViewById(R.id.ancor_name);
anchor_address = (TextView) view.findViewById(R.id.address_a);
LatLng latlng = marker.getPosition();
AsyncTask<LatLng, Void, String> mytask = new AsyncTask<LatLng, Void, String>() {
#Override
protected String doInBackground(LatLng... params) {
return getParticularLocationAddress(params[0]);
}
#Override
protected void onPostExecute(String result) {
anchor_address.setText(result);
anchor_name.setText("Ravi");
}
};
mytask.execute(latlng);
//anchor_address.setText(getParticularLocationAddress(latlng));
return view;
}
});
getParticularLocationAddress method is given as
public String getParticularLocationAddress(LatLng latlng) {
double longitude = latlng.longitude;
double latitude = latlng.latitude;
String marker_address = null;
try {
if (longitude != 0) {
Geocoder geo = new Geocoder(this.getApplicationContext(), Locale.getDefault());
addresses = geo.getFromLocation(latitude, longitude, 1);
marker_address = addresses.get(0).getAddressLine(0) + ", "
+ addresses.get(0).getAddressLine(1);
} else {
marker_address = "Can't resolve";
}
} catch (Exception e) {
e.printStackTrace();
}
return marker_address;
}
I am developing an android application which displays a map. When it loads, it displays some addresses and sets markers for them.
When I click on any marker it should display a value in a custom view. But the custom text which is received from a json parser, gets a null value. When I click on the marker again, it sets correct value.
When I click on second marker it display 1st marker value. When I click on 2nd marker again it displays correct value. This process continues
Here's my code:
private class GeocoderTask extends AsyncTask<String, Void, List<Address>>{
private Context mainContxt;
Geocoder geocoder;
public GeocoderTask(Context con){
mainContxt=con;
}
#Override
protected List<Address> doInBackground(String... locationName) {
Geocoder geocoder = new Geocoder(mainContxt);
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocationName(locationName[0],1);
} catch (IOException e) {
e.printStackTrace();
}
return addresses;
}
#Override
protected void onPostExecute(List<Address> addresses) {
for(int i=0;i<addresses.size();i++){
Address address = (Address) addresses.get(i);
latLng = new LatLng(address.getLatitude(), address.getLongitude());
String addressText = String.format("%s, %s",
address.getMaxAddressLineIndex() > 0 ? address.getAddressLine(0) : "",
address.getCountryName());
markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title(addressText);
if(i==0) {
googleMap.animateCamera(CameraUpdateFactory.zoomBy(14),2000,null);
googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
}
googleMap.addMarker(markerOptions);
}
googleMap.setOnMarkerClickListener(new OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker_address) {
location=marker_address.getTitle();
Toast.makeText(getApplicationContext(),location, Toast.LENGTH_LONG).show();
new LoadSingleProperty().execute();
//new LoadImage().execute();
return false;
}
});
googleMap.setInfoWindowAdapter(new InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker arg0) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
View myContentView = getLayoutInflater().inflate(
R.layout.custom_marker, null);
tempnew_price=getPrice(temptotal_price+"" +email);
TextView tvTitle = ((TextView) myContentView
.findViewById(R.id.title));
// tvTitle.setText(location);
tvSnippet = ((TextView) myContentView
.findViewById(R.id.snippet));
ivProperty = ((ImageView) myContentView
.findViewById(R.id.image_property));
tvTitle.setText(tempcovered_area+ " "+tempnew_price+System.getProperty("line.separator")+templocation);
tvSnippet.setText("A "+ tempbedroom + " "+tempproperty_type);
// new LoadImage().execute();
ivProperty.setImageBitmap(bmp);
return myContentView;
}
});
googleMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker arg0) {
Intent intent = new Intent(getBaseContext(),
search_property_activity.class);
intent.putExtra("Email", email);
startActivity(intent);
}
});
}
}
this is my loadsingle class coding.....
class LoadSingleProperty extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivityMap.this);
pDialog.setMessage("Loading Location. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
if(location!=null && !location.equals("")){
params.add(new BasicNameValuePair("Location", location));
json= jsonParser.makeHttpRequest(url_loc_address, "GET", params);
}
Log.d("MyLocation: ", json.toString());
try {
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
address = json.getJSONArray(TAG_ALL_ADDRESS);
//for (int i = 0; i < address.length(); i++) {
JSONObject c = address.getJSONObject(0);
templocation = c.getString(TAG_LOCATION);
tempcovered_area=c.getString(TAG_COVERED_AREA);
temptotal_price=c.getString(TAG_Total_Price);
tempbedroom=c.getString(TAG_BEDROOM);
tempproperty_type=c.getString(TAG_PROPERTY_TYPE);
tempemail=c.getString(TAG_EMAIL);
//}
} else {
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
new GeocoderTask(MainActivityMap.this).execute(location);
}
}
Help me friends ...thx in advance
Create a constructor for LoadSingleProperty
class LoadSingleProperty extends AsyncTask<String, String, String> {
Marker mMarker;
public LoadSingleProperty(Marker marker){
mMarker = marker;
}
.
.
.
}
and pass your marker object to it.
new LoadSingleProperty(marker_address).execute();
Once parsing is done set your marker's title using setTitle() method for the marker
mMarker.setTitle(c.getString(TAG_PROPERTY_TYPE));
where you currently do this
tempproperty_type=c.getString(TAG_PROPERTY_TYPE);
Don't forget to refresh your info window once title is reset
How to force refresh contents of the markerInfoWindow
You may also want to show some sort of a loading icon till this time since you're performing a network request.
EDIT:
In case you're using a custom titleview, get a reference to InfoWindowAdapter object before setting as a adapter to googleMap
InfoWindowAdapter infoWindowAdapter = new InfoWindowAdapter() {...
Once parsing is complete, get info window view for mMarker object by calling
infoWindowAdapter.getInfoWindow(mMarker);
Find your textView from the view obtained above and set its text. Then refresh your info window by calling showInfoWindow() to update the info window.
Also please refer this link.
The info window that is drawn is not a live view. The view is rendered
as an image (using View.draw(Canvas)) at the time it is returned. This
means that any subsequent changes to the view will not be reflected by
the info window on the map. To update the info window later (for
example, after an image has loaded), call showInfoWindow()
private class GeocoderTask extends AsyncTask<String, Void, List<Address>> {
private Context mainContxt;
Geocoder geocoder;
public GeocoderTask(Context con) {
mainContxt = con;
}
#Override
protected List<Address> doInBackground(String... locationName) {
Geocoder geocoder = new Geocoder(mainContxt);
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocationName(locationName[0], 1);
} catch (IOException e) {
e.printStackTrace();
}
return addresses;
}
#Override
protected void onPostExecute(List<Address> addresses) {
for (int i = 0; i < addresses.size(); i++) {
Address address = (Address) addresses.get(i);
latLng = new LatLng(address.getLatitude(),
address.getLongitude());
String addressText = String.format(
"%s, %s",
address.getMaxAddressLineIndex() > 0 ? address
.getAddressLine(0) : "", address
.getCountryName());
markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title(addressText);
if (i == 0) {
googleMap.animateCamera(CameraUpdateFactory.zoomBy(14),
2000, null);
googleMap.animateCamera(CameraUpdateFactory
.newLatLng(latLng));
}
googleMap.addMarker(markerOptions);
}
}
}
Then you write below code
googleMap.setOnMarkerClickListener(new OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker_address) {
location = marker_address.getTitle();
new LoadSingleProperty().execute();
return false;
}
});
Take another customeWindowAdapter or else use the present one only and set that in onPostExecute() method of 'LoadSingleProperty' AsyncTask..
This will solve that.
ping here you have any queries
I want to obtain the users current location within a DialogFragment and pass all data to a SQLite databse. In my DoInBackground I get the current location which is working perfectly
I want to set a TextView of long and lat, how can I pass the value out my AysncTask and back to my dialog
protected getLocation doInBackground(String... params) {
}
protected void onPostExecute(getLocation result) {
}
}
I want to pass the value in the outer class so I can put the data in sql
public Dialog onCreateDialog(Bundle savedInstanceState){
final AlertDialog.Builder build = new AlertDialog.Builder(getActivity());
text = (TextView) view.findViewById(R.id.insert_long);
text2 = (TextView) view.findViewById(R.id.insert_lat);
build.setView(view);
db = new DBHelper(getActivity());
db.open();
build.setPositiveButton(R.string.add, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
}
});
The three types used by an asynchronous task are the following:
Params, the type of the parameters sent to the task upon execution.
Progress, the type of the progress units published during the
background computation.
Result, the type of the result of the background computation.
So you need pass Double[] or your custom structure wraping lat,lon as result.
private class MyTask extends AsyncTask<Void, Void, Double[]>
And implement onPostExecute(Double[] result) method.
You can specify the return type of the method doInBackground(...) when declaring the class.
Like this:
private class LocationReceiver extends AsyncTask<String, Void, double[]> {
protected String doInBackground(String... params) {
try {
LocationManager loca = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
double longitude = location.getLongitude();
double latitude = location.getLatitude();
return new double[] {longitude, latitude};
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void onPostExecute(double[] resultArray) {
// Do something with the returned location
double lon = resultArray[0];
double lat = resultArray[1];
}
}
Create a custom class with latitude and longitude variables :
class LatLng {
public final double latitude;
public final double longitude;
LatLng(double latitude, double longitude) {
this.latitude = latitude;
this.longitude = longitude;
}
}
Now return LatLng object from doInBackground method for getting both values in onPostExecute method:
protected LatLng doInBackground(String... params) {
...
double longitude = location.getLongitude();
double latitude = location.getLatitude();
return new LatLng(location.getLatitude(),location.getLongitude());
}
And change LocationTask class as:
private static class LocationTask extends AsyncTask<Location,
Void, getLocation> {
....
#Override
protected getLocation doInBackground(String... params) {
// your code here
}
#Override
protected void onPostExecute(getLocation result) {
text = (TextView) context.findViewById(R.id.textName);
text.setText(result.latitude +"--"+result.longitude);
}
}