putSerializable not working in Android - android

I have been finding ways to resolve on how to pass multiple values from one class to the other.
I recently found a way which is to use putSerializable to do it but has not been successful. I only been able to return the last longitude and latitude to the other class.
This is my array json string:
{"longitude":"101.9366229","latitude":"1.236459"},
{"longitude":"101.930041","latitude":"1.224119"}]
Below are my code to pass the values:
class Findfriends extends AsyncTask<String, String, JSONObject> {
final String TAG = "Findfriends.java";
protected JSONObject doInBackground(String... args) {
// TODO Auto-generated method stub
// here Check for success tag
try {
HashMap<String, String> params = new HashMap<>();
params.put("username", args[0]);
JSONObject json = jsonParser.makeHttpRequest(
GET_FRIENDS, "POST", params);
if (json != null) {
Log.d("JSON result", json.toString());
return json;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(JSONObject json) {
if (json != null) {
Toast.makeText(Borrower_AP.this, json.toString(),
Toast.LENGTH_LONG).show();
try {
dataJsonArr = json.getJSONArray("Posts");
for (int i = 0; i < dataJsonArr.length(); i++) {
JSONObject c = dataJsonArr.getJSONObject(i);
Longitude = c.getDouble("longitude");
Latitude = c.getDouble("latitude");
Log.e(TAG, "Longitude: " + Longitude
+ ", Latitude: " + Latitude);
coordinates.setLongt(Longitude);
coordinates.setLat(Latitude);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
public class Coordinates implements Serializable {
private Double lat;
private Double longt;
public Double getLat () {
return lat;
}
public void setLat(Double lat) {
this.lat = lat;
}
public Double getLongt() {
return longt;
}
public void setLongt(Double longt) {
this.longt = longt;
}
}
Get the values back:
Intent intent=this.getIntent();
Bundle bundle=intent.getExtras();
Coordinates coordinates=(Coordinates)bundle.getSerializable("coordinates");
System.out.println("Lat:" + coordinates.getLat());
System.out.println("Long:" + coordinates.getLongt());

for your requirement you need Arraylist of your class Coordinates just add objects to it in loop where you parsing json and just send it to another activity and in new activity get it by casting it to Coordinates arraylist
here is the sample
if i consider coordinates in onpost method is arraylist
ArrayList<Coordinates> coordinates=new ArrayList<Coordinates>();
in your onpost forloop
use following
for (int i = 0; i < dataJsonArr.length(); i++) {
JSONObject c = dataJsonArr.getJSONObject(i);
Longitude = c.getDouble("longitude");
Latitude = c.getDouble("latitude");
Log.e(TAG, "Longitude: " + Longitude
+ ", Latitude: " + Latitude);
Coordinates coordinatesobj=new Coordinates();
coordinatesobj.setLongt(Longitude);
coordinatesobj.setLat(Latitude);
coordinates.add(coordinatesobj);
}
where you starting new activity there put below
Intent intent = new Intent(SourceActivity.this, TargetActivity.class);
intent.putExtra("key", coordinates);
at receiving side activity
Intent intent=this.getIntent();
Bundle bundle=intent.getExtras();
ArrayList<Coordinates> coordinates=( ArrayList<Coordinates>)bundle.getSerializable("key");
hope it helps

Related

android map marker using json array values in android

I need to plot map marker using the values which I get from the JSONArray. I have used the following code.It is working fine when I pass the latitude and longitude values directly but when I pass the values fetched from JSONArray the map isnt getting plotted.
StringRequest stringRequest = new StringRequest(Request.Method.POST,url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
//converting the string to json array object
JSONObject object = new JSONObject(response);
if (object.getInt("status") == 200) {
JSONArray jsonArray = object.getJSONArray("data");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject pobj = jsonArray.getJSONObject(i);
lat = Double.parseDouble(pobj.getString("latitude"));
lon = Double.parseDouble(pobj.getString("longitude")); pobj.getDouble("latitude")+","+pobj.getDouble("longitude");
Log.i("MAP",""+response);
Log.i("lat-",""+lat);
Log.i("lon-",""+lon);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
private void DisplayTrack() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("geo:" + lat + "," + lon + "?q=" + lat + "," + lon + ")")); //NOT WORKING
intent.setData(Uri.parse("geo:" + 15.824730932928347 + "," + 74.50431285009074 + "?q=" + 15.824730932928347 + "," + 74.50431285009074 + ")")); //WORKING
startActivity(intent);
}
Below is my data:
"data": [
{
"id": "43",
"site_no": "361",
"p_id_no": "68-1-361",
"sas_application_no": "95534",
"latitude": "15.824730932928347",
"longitude": "74.50431285009074",
From the comments: With this logic you're assigning the lat& lon of the last object in your jsonArray. It's most likely that by the time you reach your last object, one of your object has caused some JSONException or your last element has empty or null value. In any case it's being assigned null value. Do check your JSON response fully.
So I created a little demo how you can do it. Read the inline comments to understand:
public class MainActivity extends AppCompatActivity {
//declare the global variable, initially they are null
private Double lat, lon;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// prepare request
StringRequest stringRequest = new StringRequest(Request.Method.POST, "url",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
//converting the string to json array object
JSONObject object = new JSONObject(response);
//check
if (object.getInt("status") == 200) {
JSONArray jsonArray = object.getJSONArray("data");
for (int i = 0; i < jsonArray.length(); i++) {
//keep getting the new objects
JSONObject pobj = jsonArray.getJSONObject(i);
//assign the last object lat/lon
lat = Double.parseDouble(pobj.getString("latitude"));
lon = Double.parseDouble(pobj.getString("longitude"));
}
//if they are not null then call the activity
if (lat != null && lon != null) {
DisplayTrack(lat, lon);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
// call your request like you do
}
//declared the function out of the Network call scope
private void DisplayTrack(Double lat, Double lon) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("geo:" + lat + "," + lon + "?q=" + lat + "," + lon + ")")); //NOT WORKING
startActivity(intent);
}
}

Google Maps crashes when you cannot drive to a location

I have a google maps project where you can type in an address and you will get a marker displaying, the address, the duration (travelling by car), and the distance from the users location to point B. It works great!
My problem though, is that whenever I put a location that is not accessed by a car, the app crashes. I'm not looking for anything major, and I do not need anything else than the driving distance, so for the user to just be told that you can't drive here, is just fine for me.
I'm using JSONParsing to parse the address after an UrlRequest. legs, distance, duration, end_address, end-lat, end-lng, are the values that I'm fetching from this file:
legs: [
{
distance: {
text: "547 km",
value: 547015
},
duration: {
text: "5 h 23 min",
value: 19361
},
end_address: "Montreal, Quebec, Kanada",
end_location: {
lat: 45.5017123,
lng: -73.5672184
},
start_address: "Toronto, Ontario, Kanada",
start_location: {
lat: 43.6533096,
lng: -79.3827656
},
steps: [
{
distance: {
text: "0,3 km",
value: 280
},
duration: {
text: "1 min",
value: 66
},
end_location: {
lat: 43.6557259,
lng: -79.3837337
},
html_instructions: "",
polyline: {
points: "e`miGhmocNs#Rm#N]JmA^KBcAZSFWHe#Nk#Pa#Le#L"
},
start_location: {
lat: 43.6533096,
lng: -79.3827656
},
travel_mode: "DRIVING"
},
So my question is, does anyone have any suggestions as to what kind of conditions I should have for this kind of method to run.
if(!=travel_mode: "DRIVING")
{
Toast.makeText(MapsActivity.this, "You cannot drive there",
Toast.LENGTH:SHORT).show();
}
else
{
execute code;
}
Fetch the travel_mode and have it as a condition somehow? Thank you in advance!
My whole code,
The main class, when you press a button the address will be converted
private void init() {
searchText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
dataTransfer = new Object[2];
url = getDirectionsUrl();
GetDistances getDistances = new GetDistances();
dataTransfer[0] = mMap;
dataTransfer[1] = url;
getDistances.execute(dataTransfer);
return false;
}
});
Building the URL...
private String getDirectionsUrl()
{
//WORKS
//https://maps.googleapis.com/maps/api/directions/json?origin=Toronto&destination=Montreal&key=API_KEY"
StringBuilder googleDirectionsUrl = new StringBuilder("https://maps.googleapis.com/maps/api/directions/json?");
//Possible two textfields with origin being another textfield
googleDirectionsUrl.append("origin="+myLat+","+myLng);
googleDirectionsUrl.append("&destination="+searchText.getText().toString());
googleDirectionsUrl.append("&key="+"API_KEY");
return googleDirectionsUrl.toString();
}
Sending the Url to be parsed...
public class DataParser {
private HashMap<String, String> getDuration(JSONArray googleDirectionsJson) {
HashMap<String, String> googleDirectionsMap = new HashMap<>();
String duration = "";
String distance = "";
String title = "";
Log.d("json response", googleDirectionsJson.toString());
try {
duration = googleDirectionsJson.getJSONObject(0).getJSONObject("duration").getString("text");
distance = googleDirectionsJson.getJSONObject(0).getJSONObject("distance").getString("text");
title = googleDirectionsJson.getJSONObject(0).getString("end_address");
googleDirectionsMap.put("duration", duration);
googleDirectionsMap.put("distance", distance);
googleDirectionsMap.put("end_address", title);
} catch (JSONException e) {
e.printStackTrace();
}
return googleDirectionsMap;
}
public HashMap<String, String> parseDirections(String jsonData) {
JSONArray jsonArray = null;
JSONObject jsonObject;
try {
jsonObject = new JSONObject(jsonData);
jsonArray = jsonObject.getJSONArray("routes").getJSONObject(0).getJSONArray("legs");
} catch (JSONException e) {
e.printStackTrace();
}
return getDuration(jsonArray);
}
private HashMap<String, Double> getLatLng(JSONArray googleLatLngJson) {
HashMap<String, Double> googleLatLngMap = new HashMap<>();
Double latitude = 0.0;
Double longitude = 0.0;
try {
latitude = googleLatLngJson.getJSONObject(0).getJSONObject("end_location").getDouble("lat");
longitude = googleLatLngJson.getJSONObject(0).getJSONObject("end_location").getDouble("lng");
googleLatLngMap.put("lat", latitude);
googleLatLngMap.put("lng", longitude);
Log.d("json response", googleLatLngMap.toString());
} catch (JSONException e) {
e.printStackTrace();
}
return googleLatLngMap;
}
public HashMap<String, Double> parseLatLng(String jsonData) {
JSONArray jsonArray = null;
JSONObject jsonObject;
try {
jsonObject = new JSONObject(jsonData);
jsonArray = jsonObject.getJSONArray("routes").getJSONObject(0).getJSONArray("legs");
} catch (JSONException e) {
e.printStackTrace();
}
return getLatLng(jsonArray);
}
}
Getting the values from the JSONparsed hashmaps and putting them into new hashmaps to add the markers with their values
public class GetDistances extends AsyncTask<Object, String, String>{
GoogleMap mMap;
String url;
String googleDirectionsData;
String duration, distance;
Double latitude, longitude;
LatLng latLng;
String title;
#Override
protected String doInBackground(Object... objects) {
mMap = (GoogleMap)objects[0];
url = (String)objects[1];
HttpHandler httpHandler = new HttpHandler();
try
{
googleDirectionsData = httpHandler.readUrl(url);
}
catch(IOException e)
{
e.printStackTrace();
}
return googleDirectionsData;
}
#Override
protected void onPostExecute(String s)
{
DataParser parser = new DataParser();
HashMap<String, String> directionsList = null;
directionsList = parser.parseDirections(s);
duration = directionsList.get("duration");
distance = directionsList.get("distance");
title = directionsList.get("end_address");
HashMap<String, Double> positionList = null;
positionList = parser.parseLatLng(s);
latitude = positionList.get("lat");
longitude = positionList.get("lng");
latLng = (new LatLng(latitude, longitude));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 13));
MarkerOptions markerOptions = new MarkerOptions()
.position(latLng)
.draggable(true)
.title(title);
markerOptions.snippet("Distance: " + distance + ", " + "Duration: " + duration);
mMap.addMarker(markerOptions);
}
}
"API_KEY" - is my actual key, just trying to keep it private.
SOLVED
I just made a try catch in the onPostExecute method, and it solved the crash.
public class GetDestination extends AsyncTask<Object, String, String>{
GoogleMap mMap;
String url;
String googleDirectionsData;
String duration, distance;
Double latitude, longitude;
LatLng latLng;
String title;
private static Context context;
public GetDestination(Context c){
context = c;
}
public static void showToast(){
Toast.makeText(context, "You can't drive through the oceans!", Toast.LENGTH_LONG).show();
}
#Override
protected String doInBackground(Object... objects) {
mMap = (GoogleMap)objects[0];
url = (String)objects[1];
HttpHandler httpHandler = new HttpHandler();
try
{
googleDirectionsData = httpHandler.readUrl(url);
}
catch(IOException e)
{
e.printStackTrace();
}
return googleDirectionsData;
}
#Override
protected void onPostExecute(String s)
{
try {
DataParser parser = new DataParser();
HashMap<String, String> directionsList = null;
directionsList = parser.parseDirections(s);
duration = directionsList.get("duration");
distance = directionsList.get("distance");
title = directionsList.get("start_address");
HashMap<String, Double> positionList = null;
positionList = parser.parseLatLng(s);
latitude = positionList.get("lat");
longitude = positionList.get("lng");
latLng = (new LatLng(latitude, longitude));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 13));
MarkerOptions markerOptions = new MarkerOptions()
.position(latLng)
.draggable(true)
.title(title);
markerOptions.snippet("Distance: " + distance + ", " + "Duration: " + duration);
mMap.addMarker(markerOptions);
}
catch (Exception e)
{
showToast();
e.printStackTrace();
}
}
}
Be sure to pass in the context in the Mainactivity class,
searchText1.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
dataTransfer = new Object[2];
url = getDirectionsUrl();
GetDestination getDestination = new GetDestination(MapsActivity.this);
dataTransfer[0] = mMap;
dataTransfer[1] = url;
getDestination.execute(dataTransfer);
return false;
}
});
It's great that you have solved the problem yourself. Congrats.
But the better approach will be to put a log in the response and check the difference between the two responses i.e drivable and not drivable.
In this way, you could read the exact response and based on the response you can show different messages to the user.
And of course, a try, catch could be there to handle any kind of exception.
Hope this Helps.

Add marker to map from JSON, Android

I was trying to add markers to a map automatically after getting the data from JSON, with the position that is in the api, this is what I have:
#Override
protected Void doInBackground(Void... params) {
HttpHandler sh2 = new HttpHandler();
final String jsonStrOportunidades = sh2.makeServiceCall(urlOportunidades);
Log.e(TAG, "Response from URL: " + jsonStrOportunidades);
if (jsonStrOportunidades != null) {
try {
JSONArray array = new JSONArray(jsonStrOportunidades);
for (int i = 0; i < array.length(); i++) {
JSONObject jsonObject = array.getJSONObject(i);
String Designacao = jsonObject.getString("Designacao");
String Coord_LAT = jsonObject.getString("Coord_LAT");
String Coord_LONG = jsonObject.getString("Coord_LONG");
HashMap<String, String> oportunidades = new HashMap<>();
oportunidades.put("Designacao", Designacao);
oportunidades.put("Coord_LAT", Coord_LAT);
oportunidades.put("Coord_LONG", Coord_LONG);
double lat1 = Double.parseDouble(Coord_LAT);
double lng1 = Double.parseDouble(Coord_LONG);
mMap.addMarker(new MarkerOptions().position(new LatLng(lat1, lng1)));
listaOportunidades.add(oportunidades);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Json parsin error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
return null;
}
"mMap.addMarker" doesn't work, is it even possible creating markers from there?
Try setting the marker from onPostExecute. doInBackground isn't the place to update UI components.
#Override
protected String doInBackground(Void... params) {
HttpHandler sh2 = new HttpHandler();
final String jsonStrOportunidades = sh2.makeServiceCall(urlOportunidades);
Log.e(TAG, "Response from URL: " + jsonStrOportunidades);
return jsonStrOportunidades;
}
#Override
protected void onPostExecute(String jsonStrOportunidades){
if (jsonStrOportunidades != null) {
try {
JSONArray array = new JSONArray(jsonStrOportunidades);
for (int i = 0; i < array.length(); i++) {
JSONObject jsonObject = array.getJSONObject(i);
String Designacao = jsonObject.getString("Designacao");
String Coord_LAT = jsonObject.getString("Coord_LAT");
String Coord_LONG = jsonObject.getString("Coord_LONG");
HashMap<String, String> oportunidades = new HashMap<>();
oportunidades.put("Designacao", Designacao);
oportunidades.put("Coord_LAT", Coord_LAT);
oportunidades.put("Coord_LONG", Coord_LONG);
double lat1 = Double.parseDouble(Coord_LAT);
double lng1 = Double.parseDouble(Coord_LONG);
mMap.addMarker(new MarkerOptions().position(new LatLng(lat1, lng1)));
listaOportunidades.add(oportunidades);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
Toast.makeText(getApplicationContext(), "Json parsin error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
Also, you need to change the AsyncTask class like this
YourAsyncTaskClass extends AsyncTask<String, Void, String>

How to get Integer Json value in android

In my android i have got a response from Json but i want to get that Json value in Integer variable in android.In Jsonarray a i have got my value.So please help me for this. I have return that integer value in "MenuNameFromAndroid" function.
protected class AsyncMenuname extends
AsyncTask<MenunameSendFrom, JSONObject, JSONObject> {
JSONObject jsonObj = null;
#Override
protected JSONObject doInBackground(MenunameSendFrom... params) {
RestAPI api = new RestAPI();
try {
jsonObj = api.MenuNameFromAndroid(params[0].getMenuname());
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("AsyncCreateUser", e.getMessage());
}
return jsonObj;
}
#Override
protected void onPostExecute(JSONObject objects) {
try {
//JSONArray jsonArray = objects.getJSONArray("Value");
String string = null;
JSONArray a = objects.getJSONArray("Value");
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(TwoList.this, "Successfully inserted...", Toast.LENGTH_LONG).show();
}
}
In this function i have got a response of JSON object
public JSONObject MenuNameFromAndroid(String getMenuname) throws Exception {
JSONObject result = null;
JSONObject o = new JSONObject();
JSONObject p = new JSONObject();
o.put("interface","RestAPI");
o.put("method", "MenuNameFromAndroid");
p.put("getMenuname",mapObject(getMenuname));
o.put("parameters", p);
String s = o.toString();
String r = load(s);
result = new JSONObject(r);
return result;
}
And This is function that I have return float value. That float value i want to get in android
float menuId = 0;
public float MenuNameFromAndroid(string getMenuname)
{
if (dbConnection.State.ToString() == "Closed")
{
dbConnection.Open();
}
menuId = db.getDb_Value("select menu_id From menu where m_name='" + getMenuname + "'");
dbConnection.Close();
return menuId;
}

My UI is blocked using AsyncTask with distancematrix and google Maps

I'm using google maps to show some markers. The markers are download from a database and, at the same time, I get the distancematrix from google api, between the current position of the user and the marker that I get from the database.
My problem is that I was doing this with .get, bloking my ui (I've read that .get blocked the ui:
dataFromAsyncTask = testAsyncTask.get();
Now, I'm trying to do the same without blocking the ui, but I'm not be able to get at the same time, or in a good way, the distance for this markers.
I appreciate some help, please.
This is my code with my old and wrong .get:
for (City city : listCity.getData()) {
geoPoint = city.getLocation();
nameBeach = city.getName();
if (geoPoint == null) {
} else {
latitude = String.valueOf(geoPoint.getLatitude());
longitude = String.valueOf(geoPoint.getLongitude());
startRetrievenDistanceAndDuration();
try {
dataFromAsyncTask = testAsyncTask.get();
} catch (InterruptedException i) {
} catch (ExecutionException e) {
}
mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude()))
.title(nameCity)
.snippet(dataFromAsyncTask)
.icon(BitmapDescriptorFactory.defaultMarker()));
}
}
startRetrievenDistanceAndDuration method:
private void startRetrievenDistanceAndDuration() {
final String url;
testAsyncTask = new DistanceBetweenLocations(new FragmentCallback() {
#Override
public void onTaskDone(String result) {
}
});
url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxx";
testAsyncTask.execute(new String[]{url});
}
public interface FragmentCallback {
public void onTaskDone(String result);
AsyncTask class:
#Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
URL url = null;
StringBuilder result = null;
String duration = "";
String distance = "";
try {
url=new URL(params[0]);
}catch (MalformedURLException m){
}
try {
urlConnection = (HttpURLConnection) url.openConnection();
}catch (IOException e){}
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder();
String line;
while((line = reader.readLine()) != null) {
result.append(line);
}
}catch (IOException e){
} finally {
urlConnection.disconnect();
}
try {
JSONObject jsonObject = new JSONObject(result.toString());
JSONArray jsonArray = jsonObject.getJSONArray("rows");
JSONObject object_rows = jsonArray.getJSONObject(0);
JSONArray jsonArrayElements = object_rows.getJSONArray("elements");
JSONObject object_elements = jsonArrayElements.getJSONObject(0);
JSONObject object_duration = object_elements.getJSONObject("duration");
JSONObject object_distance = object_elements.getJSONObject("distance");
duration = object_duration.getString("text");
distance = object_distance.getString("text");
} catch (JSONException e) {
e.printStackTrace();
}
return distance + ", " + duration;
}
#Override
protected void onPostExecute(String result) {
mFragmentCallback.onTaskDone(result);
}
}
I'm trying to do this, but I only show the last marker of my list:
Call in the loop the method:
startRetrievenDistanceAndDuration();
And in onTaskDone try to put the marker, but only get the last marker of my list
#Override
public void onTaskDone(String result) {
mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude()))
.title(nameBeach)
.snippet(result)
.icon(BitmapDescriptorFactory.defaultMarker()));
}
UPDATED AFTER CHANGES: (still don't work)
I can parse the data in Asynctask and send it in onPostExecute, but I only get one value, and not the 9 values that I have....
MAIN ACTIVITY:
DistanceBetweenLocations task = new DistanceBetweenLocations(mlatituDouble, mlongitudeDouble){
#Override
protected void onPostExecute(HashMap<String, String> result) {
super.onPostExecute(result);
String name = result.get("beachName");
String distance = result.get("distance");
String duration = result.get("duration");
String latitue = result.get("latitude");
String longitude = result.get("longitude");
Double mlatituDouble = Double.parseDouble(latitue);
Double mlongitudeDouble = Double.parseDouble(longitude);
if (mMap == null) {
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapView))
.getMap();
Toast.makeText(getActivity(), "mMap NO null", Toast.LENGTH_SHORT).show();
mMap.addMarker(new MarkerOptions().position(new LatLng(mlatituDouble, mlongitudeDouble))
.title(name)
.snippet(distance + " " + duration)
.icon(BitmapDescriptorFactory.defaultMarker()));
}
}
};
task.execute();
ASYNCTASK CLASS:.
public class DistanceBetweenLocations extends AsyncTask<String, String, HashMap<String, String>> {
Double currentLatitude;
Double currentlongitude;
public BeachMap beachMap;
public BackendlessCollection<Beach> dataBeach;
public GoogleMap mMap;
String latitude;
String longitude;
HashMap<String, String> map;
public DistanceBetweenLocations(Double currentLatitude, Double currentlongitude){
this.currentLatitude = currentLatitude;
this.currentlongitude = currentlongitude;
}
#Override
protected HashMap<String, String> doInBackground(String... params) {
dataBeach = beachMap.listBeach;
for (Beach city : dataBeach.getData()) {
GeoPoint geoPoint = city.getLocation();
String nameBeach = city.getName();
if (geoPoint == null) {
} else {
latitude = String.valueOf(geoPoint.getLatitude());
longitude = String.valueOf(geoPoint.getLongitude());
HttpURLConnection urlConnection = null;
URL url = null;
StringBuilder result = null;
String duration = "";
String distance = "";
try {
url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxxx");
} catch (MalformedURLException m) {
}
try {
urlConnection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
}
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
} catch (IOException e) {
} finally {
urlConnection.disconnect();
}
try {
JSONObject jsonObject = new JSONObject(result.toString());
JSONArray jsonArray = jsonObject.getJSONArray("rows");
JSONObject object_rows = jsonArray.getJSONObject(0);
JSONArray jsonArrayElements = object_rows.getJSONArray("elements");
JSONObject object_elements = jsonArrayElements.getJSONObject(0);
JSONObject object_duration = object_elements.getJSONObject("duration");
JSONObject object_distance = object_elements.getJSONObject("distance");
duration = object_duration.getString("text");
distance = object_distance.getString("text");
map = new HashMap<String, String>();
map.put("beachName", nameBeach);
map.put("distance", distance);
map.put("duration", duration);
map.put("latitude", latitude);
map.put("longitude", longitude);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return map;
}
}
I'll use your last code (the "UPDATED AFTER CHANGES"), ok?
If I get it right, your DistanceBetweenLocations result will be a list of beaches geolocation data. So, on every iteration of the for loop in doInBackground, you are replacing the value of "map" variable, this is your problem.
To solve your problem, you can have a List of HashMap or a List of a Pojo like this:
public class BeachPojo {
private String beachName;
private String distance;
private String duration;
private String latitude;
private String longitude;
public String getBeachName() {
return beachName;
}
public void setBeachName(String beachName) {
this.beachName = beachName;
}
public String getDistance() {
return distance;
}
public void setDistance(String distance) {
this.distance = distance;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
}
Using the Pojo, your AsyncTask will be like this:
public class DistanceBetweenLocations extends AsyncTask<String, String, List<BeachPojo>> {
Double currentLatitude;
Double currentlongitude;
public BeachMap beachMap;
public BackendlessCollection<Beach> dataBeach;
public GoogleMap mMap;
String latitude;
String longitude;
public DistanceBetweenLocations(Double currentLatitude, Double currentlongitude){
this.currentLatitude = currentLatitude;
this.currentlongitude = currentlongitude;
}
#Override
protected List<BeachPojo> doInBackground(String... params) {
List<BeachPojo> list = new ArrayList<BeachPojo>();
BeachPojo pojo;
dataBeach = beachMap.listBeach;
for (Beach city : dataBeach.getData()) {
GeoPoint geoPoint = city.getLocation();
String nameBeach = city.getName();
if (geoPoint == null) {
} else {
latitude = String.valueOf(geoPoint.getLatitude());
longitude = String.valueOf(geoPoint.getLongitude());
HttpURLConnection urlConnection = null;
URL url = null;
StringBuilder result = null;
String duration = "";
String distance = "";
try {
url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxxx");
} catch (MalformedURLException m) {
}
try {
urlConnection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
}
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
} catch (IOException e) {
} finally {
urlConnection.disconnect();
}
try {
JSONObject jsonObject = new JSONObject(result.toString());
JSONArray jsonArray = jsonObject.getJSONArray("rows");
JSONObject object_rows = jsonArray.getJSONObject(0);
JSONArray jsonArrayElements = object_rows.getJSONArray("elements");
JSONObject object_elements = jsonArrayElements.getJSONObject(0);
JSONObject object_duration = object_elements.getJSONObject("duration");
JSONObject object_distance = object_elements.getJSONObject("distance");
duration = object_duration.getString("text");
distance = object_distance.getString("text");
pojo = new BeachPojo();
pojo.setBeachName(nameBeach);
pojo.setDistance(distance);
pojo.setDuration(duration);
pojo.setLatitude(latitude);
pojo.setLongitude(longitude);
list.add(pojo);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return list;
}
}
Now you have a List to iterate. I have adjusted the code a little bit to this goal:
DistanceBetweenLocations task = new DistanceBetweenLocations(mlatituDouble, mlongitudeDouble){
#Override
protected void onPostExecute(List<BeachPojo> result) {
super.onPostExecute(result);
if (mMap == null) {
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapView))
.getMap();
}
Double beachLatitude;
Double beachLongitude;
for (BeachPojo pojo : result) {
beachLatitude = Double.parseDouble(pojo.getLatitude());
beachLongitude = Double.parseDouble(pojo.getLongitude());
mMap.addMarker(new MarkerOptions().position(new LatLng(beachLatitude, beachLongitude))
.title(pojo.getBeachName())
.snippet(pojo.getDistance() + " " + pojo.getDuration())
.icon(BitmapDescriptorFactory.defaultMarker()));
}
}
};
task.execute();
I hope you understand the idea of returning a List from your AsyncTask and loop throught the result on onPostExecute method.
Note: this is an implementation without knowing the real code, then you should adjust to your reality.
I'm not exactly sure what you're trying to do but I think you've made this more complicated then it has to be.
From what I understand you have a list of City objects and you use them to construct some URLs from which you retrieve a JSON object that is use to construct MarkerOptions objects.
You can do that using a AsyncTask like this:
public class Task extends AsyncTask<City, Void, Markers> {
String currentLatitude;
String currentlongitude;
public Task(String currentLatitude, String currentlongitude){
this.currentLatitude = currentLatitude;
this.currentlongitude = currentlongitude;
}
#Override
protected String doInBackground(City... cities) {
final Markers mMap = ...;
for (City city : cities) {
GeoPoint geoPoint = city.getLocation();
String nameBeach = city.getName();
if (geoPoint != null) {
String latitude = String.valueOf(geoPoint.getLatitude());
String longitude = String.valueOf(geoPoint.getLongitude());
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
URL url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxx";);
urlConnection = (HttpURLConnection) url.openConnection();
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
JSONObject jsonObject = new JSONObject(result.toString()).getJSONArray("rows").getJSONObject(0).getJSONArray("elements").getJSONObject(0);
String duration = jsonObject.getJSONObject("duration").getString("text");
String distance = jsonObject.getJSONObject("distance").getString("text");
mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude()))
.title(nameBeach)
.snippet(distance + ", " + duration)
.icon(BitmapDescriptorFactory.defaultMarker()));
} catch (Exception e) {
e.printStackTrace();
} finally {
if(reader!=null){
try {
reader.close();
}catch (Exception e){
e.printStackTrace();
}
}
if (urlConnection != null) {
try {
urlConnection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
return mMap;
}
}
And here is how you can use this task.
public class Login extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
Task task = new Task(currentLatitude, currentlongitude){
#Override
protected void onPostExecute(Markers markers) {
super.onPostExecute(markers);
//This runs on the UI thread and "markers" is the "mMap" object that was create on the background thread.
}
};
List<City> cities = ....
task.execute(cities.toArray(new City[cities.size()]));
}
}
The idea is that you need to execute all the long running operation in the AsyncTask's doInBackground(...) method. Also, you don't need to create other objects to deal with the AsyncTask response, you can override the task's onPostExecute(...) inside the class you've created the task in.

Categories

Resources