Google Places API photo_reference - java

I have been trying to extract the goolge places api photo reference but have not had any success. I was wondering if someone could help me. Below is my code:
// KEY Strings
public static String KEY_REFERENCE = "reference"; // id of the place
public static String KEY_NAME = "name"; // name of the place
public static String KEY_VICINITY = "vicinity"; // Place area name
public static String KEY_PHOTO = "photo_reference";
class LoadPlaces extends AsyncTask<String, String, String> {
/**
* getting google places JSON response
* */
protected String doInBackground(String... args) {
// creating Places class object
googlePlaces = new GooglePlaces();
try {
String types = MenuActivity.type;
String keyword = MenuActivity.keyword;
// get nearest places
nearPlaces = googlePlaces.search(gps.getLatitude(),gps.getLongitude(),
types, keyword);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed Places into LISTVIEW
* */
// Get JSON response status
String status = nearPlaces.status;
// Check for OK status
if (status.equals("OK")) {
// Successfully got places details
if (nearPlaces.results != null) {
// loop through each place
for (Place p : nearPlaces.results) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(KEY_REFERENCE, p.reference);
map.put(KEY_NAME, p.name);
map.put(KEY_PHOTO,p.photo);
map.put(KEY_VICINITY, p.vicinity);
// adding HashMap to ArrayList
placesListItems.add(map);
}
// list adapter - removed rating
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, placesListItems,
R.layout.list_item, new String[] {
KEY_REFERENCE, KEY_NAME, KEY_VICINITY, KEY_PHOTO},
new int[] { R.id.reference, R.id.name, R.id.address, R.id.phptp});
// Adding data into ListView
lv.setAdapter(adapter);
}
}
}
Below is my code that performs the search and parses the data:
public class GooglePlaces {
/** Global instance of the HTTP transport. */
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final String LOG_KEY = "GGPlace";
// Google API Key
private static final String API_KEY = "";
// Google Places serach
private static final String PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?&rankby=distance";
private double _latitude;
private double _longitude;
private double _radius;
private String address;
public PlacesList search(double latitude, double longitude, String types, String keyword)
throws Exception {
this._latitude = latitude;
this._longitude = longitude;
try {
HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
HttpRequest request = httpRequestFactory.buildGetRequest(new GenericUrl(PLACES_SEARCH_URL));
request.getUrl().put("key", API_KEY);
request.getUrl().put("location", _latitude + "," + _longitude);
request.getUrl().put("sensor", "true");
if(types != null)
{
request.getUrl().put("types", types);
request.getUrl().put("keyword", keyword);
}
PlacesList list = request.execute().parseAs(PlacesList.class);
// Check log cat for places response status
Log.d("Places Status", "" + list.status);
return list;
} catch (HttpResponseException e) {
Log.e("Error:", e.getMessage());
return null;
}
}
public static HttpRequestFactory createRequestFactory(
final HttpTransport transport) {
return transport.createRequestFactory(new HttpRequestInitializer() {
public void initialize(HttpRequest request) {
GoogleHeaders headers = new GoogleHeaders();
headers.setApplicationName("APP NAME");
headers.gdataVersion="2";
request.setHeaders(headers);
JsonHttpParser parser = new JsonHttpParser(new JacksonFactory());
request.addParser(parser);
}
});
}
}
This is my PlaceList class:
public class PlacesList implements Serializable {
#Key
public String status;
#Key
public List<Place> results;
}
Here is my Place class:
public class Place implements Serializable {
#Key
public String id;
#Key
public String name;
#Key
public String reference;
#Key
public String vicinity;
#Key
public Geometry geometry;
#Key
public List<Photo> photos;
}
And finally my Photo class:
public class Photo implements Serializable {
#Key
public String photo_reference;
#Key
public int height;
#Key
public int width;
}
I guess I am calling or passing the photo_reference the wrong way. I am hoping there is someone out there that can help me out. I've been working on this for weeks and have almost completely given up.

Hi firstly your search url is wrong.
You have to follow this format:
https://developers.google.com/places/web-service/photos
Please see below for a complete example:
http://wptrafficanalyzer.in/blog/showing-nearby-places-with-photos-at-any-location-in-google-maps-android-api-v2/
If you download the source code, it will help you see how to fetch the json string in an array which is in another array.
The snippet below just answers the part where you have to fetch the image:
package in.wptrafficanalyzer.locationnearbyplacesphotos;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class PlaceJSONParser {
/** Receives a JSONObject and returns a list */
public Place[] parse(JSONObject jObject){
JSONArray jPlaces = null;
try {
/** Retrieves all the elements in the 'places' array */
jPlaces = jObject.getJSONArray("results");
} catch (JSONException e) {
e.printStackTrace();
}
/** Invoking getPlaces with the array of json object
* where each json object represent a place
*/
return getPlaces(jPlaces);
}
private Place[] getPlaces(JSONArray jPlaces){
int placesCount = jPlaces.length();
Place[] places = new Place[placesCount];
/** Taking each place, parses and adds to list object */
for(int i=0; i<placesCount;i++){
try {
/** Call getPlace with place JSON object to parse the place */
places[i] = getPlace((JSONObject)jPlaces.get(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
return places;
}
/** Parsing the Place JSON object */
private Place getPlace(JSONObject jPlace){
Place place = new Place();
try {
// Extracting Place name, if available
if(!jPlace.isNull("name")){
place.mPlaceName = jPlace.getString("name");
}
// Extracting Place Vicinity, if available
if(!jPlace.isNull("vicinity")){
place.mVicinity = jPlace.getString("vicinity");
}
if(!jPlace.isNull("photos")){
JSONArray photos = jPlace.getJSONArray("photos");
place.mPhotos = new Photo[photos.length()];
for(int i=0;i<photos.length();i++){
place.mPhotos[i] = new Photo();
place.mPhotos[i].mWidth = ((JSONObject)photos.get(i)).getInt("width");
place.mPhotos[i].mHeight = ((JSONObject)photos.get(i)).getInt("height");
place.mPhotos[i].mPhotoReference = ((JSONObject)photos.get(i)).getString("photo_reference");
JSONArray attributions = ((JSONObject)photos.get(i)).getJSONArray("html_attributions");
place.mPhotos[i].mAttributions = new Attribution[attributions.length()];
for(int j=0;j<attributions.length();j++){
place.mPhotos[i].mAttributions[j] = new Attribution();
place.mPhotos[i].mAttributions[j].mHtmlAttribution = attributions.getString(j);
}
}
}
place.mLat = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lat");
place.mLng = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lng");
} catch (JSONException e) {
e.printStackTrace();
Log.d("EXCEPTION", e.toString());
}
return place;
}
}

I first misunderstood photo_reference as Base64 Encoded String. But it is not indeed it is a reference parameter to identify and fetch a photo from google maps API. Imagine this as a token parameter. So to fetch a photo with max-width 400 you can use below URL.
https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CnRtAAAATLZNl354RwP_9UKbQ_5Psy40texXePv4oAlgP4qNEkdIrkyse7rPXYGd9D_Uj1rVsQdWT4oRz4QrYAJNpFX7rzqqMlZw2h2E2y5IKMUZ7ouD_SlcHxYq1yL4KbKUv3qtWgTK0A6QbGh87GB3sscrHRIQiG2RrmU_jF4tENr9wGS_YxoUSSDrYjWmrNfeEHSGSc3FyhNLlBU&key=YOUR_API_KEY
For more details visit Google Places documentation
https://developers.google.com/places/web-service/photos

Related

problem recived the earthquake JSON result

This Is the Error:-
E/QueryUtils: problem recived the earthquake JSON result
java.net.ProtocolException: Expected one of [OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, PATCH] but was Get
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.setRequestMethod(HttpURLConnectionImpl.java:606)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.setRequestMethod(DelegatingHttpsURLConnection.java:113)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.setRequestMethod(HttpsURLConnectionImpl.java)
at com.example.quakereport.QueryUtils.makeHttpRequest(QueryUtils.java:92)
at com.example.quakereport.QueryUtils.featchEarthquakeDate(QueryUtils.java:52)
at com.example.quakereport.MainActivity$EarthquakeAsyncTask.doInBackground(MainActivity.java:64)
at com.example.quakereport.MainActivity$EarthquakeAsyncTask.doInBackground(MainActivity.java:56)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:760)
MainActivity.java
public class MainActivity extends AppCompatActivity {
private EarthquakeAdapter mAdapter;
//URL for earthquake data from the USGS dataset
private static final String USGS_REQUEST_URL ="https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&eventtype=earthquake&orderby=time&minmag=6&limit=10";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/** Find a refrence to the {#link ListView} in the layout*/
ListView eathquakeListView = (ListView) findViewById(R.id.list);
/** Create a new {#link ArrayAdapter} of earthquakes*/
mAdapter = new EarthquakeAdapter(this,new ArrayList<Earthquake>());
eathquakeListView.setAdapter(mAdapter);
/** Start the AsyncTask to fetch the earthquake data*/
EarthquakeAsyncTask task = new EarthquakeAsyncTask();
task.execute(USGS_REQUEST_URL);
eathquakeListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
// Find the current earthquake that was clicked on
Earthquake currentEarthquake = mAdapter.getItem(position);
//convert the String URL int a URI object(to pass into the intent constructor)
Uri eathquakeuri = Uri.parse(currentEarthquake.getmUrl());
//Create a new intent to view the earthquake URI
Intent websiteIntent = new Intent(Intent.ACTION_SEND, eathquakeuri);
// Send the intent to launch a new activity
startActivity(websiteIntent);
}
});
}
private class EarthquakeAsyncTask extends AsyncTask<String, Void, List<Earthquake>>{
protected List<Earthquake> doInBackground(String... urls) {
/** If there is a valid list of {#link Earthquake}, then add them to the adapter's data set. This will trigger the
* Listview to update*/
if(urls.length<1 || urls[0] == null){
return null;
}
List<Earthquake> result = QueryUtils.featchEarthquakeDate(urls[0]);
return result;
}
#Override
protected void onPostExecute(List<Earthquake> data) {
/** Clear the adapter of previous earthquake data*/
mAdapter.clear();
/** If there is a valid list of {#link Earthquake}s, then add them to the adapter's dataset. THis will trigger
* the ListVIew to update*/
if (data != null && !data.isEmpty()){
mAdapter.addAll(data);
}
}
}
}
QueryUtils.java
public final class QueryUtils {
/**
* Sample JSON response for a USGS query
*/
/**
* Create a private constructor because no one should ever create a {#link QueryUtils} object.
* This class is only meant to hold static variables and methods, which can be accessed
* directly from the class name QueryUtils (and an object instance of QueryUtils is not needed).
*/
private static final String LOG_TAG = QueryUtils.class.getSimpleName();
private QueryUtils() {
}
/**
* Query the USGS dataset and return a list of{#link Earthquake} objects.
*/
public static List<Earthquake> featchEarthquakeDate(String requestUrl)
{
// Create URL Object
URL url = createurl(requestUrl);
// Perform HTTP request to the URL and recive a JSON response back
String JSONResponse = null;
try{
JSONResponse = makeHttpRequest(url);
}catch (IOException e)
{
Log.e(LOG_TAG,"Problem Making http equest", e);
}
// Extract relevent fields fom the JSON response and create a list of {#link Earthquake}s
List<Earthquake> earthquakes = extractFeatureFromJson(JSONResponse);
//Return the list of {#link Earthquake}s
return earthquakes;
}
/**
* Return new URL from object from the given string URL
*/
private static URL createurl(String stringURL){
URL url = null;
try {
url = new URL(stringURL);
}catch (MalformedURLException e){
Log.e(LOG_TAG,"problem building the url", e);
}
return url;
}
/**
* Make an HTTP request to the given URL and return a string as the response.
* */
private static String makeHttpRequest(URL url)throws IOException{
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null){
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try{
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000/* millisecond*/);
urlConnection.setConnectTimeout(15000 /*milisecond*/);
urlConnection.setRequestMethod("Get");
urlConnection.connect();
//If the request was successful (response code 200), then read the Input Stream and parse the Response.
if (urlConnection.getResponseCode() == 200){
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
}else {
Log.e(LOG_TAG,"Error Response code" + urlConnection.getResponseCode());
}
}catch (IOException e){
Log.e(LOG_TAG,"problem recived the earthquake JSON result",e);
}finally {
if (urlConnection!=null)
{
urlConnection.disconnect();
}
if (inputStream!=null){
/*
Closing the input Stream could throw an IOException, which is why the makeHttpRequest(URL url) method
signature specific than an IOException could be thrown.
*/
inputStream.close();
}
}
return jsonResponse;
}
private static String readFromStream(InputStream inputStream) throws IOException{
StringBuilder output = new StringBuilder();
if (inputStream != null){
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null){
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return a list of {#link Earthquake} objects that has been built up from
* parsing a JSON response.
*/
private static List<Earthquake> extractFeatureFromJson(String eartheuakeJSON) {
// If the JSON string is empity or null, then return early.
if (TextUtils.isEmpty(eartheuakeJSON))
{
return null;
}
// Create an empty ArrayList that we can start adding earthquakes to
List<Earthquake> earthquakes = new ArrayList<Earthquake>();
// Try to parse the JSON response string. If there's a problem with the way the JSON
// is formatted, a JSONException exception object will be thrown.
// Catch the exception so the app doesn't crash, and print the error message to the logs.
try {
// create a JSONObject from the JSON response string
JSONObject baseJsonResponse = new JSONObject(eartheuakeJSON);
// Extract the JSONArray associated with the key called "features", which represent a list of features(or earthquakes).
JSONArray earthquakeArray = baseJsonResponse.getJSONArray("features");
// For each earthquake in the earthquakeArray, create an {#link Earthquake} object
for (int i = 0; i < earthquakeArray.length(); i++) {
JSONObject currentEarthquake = earthquakeArray.getJSONObject(i);
// For a given earthquake, extract the JSONObject associated with the key called "properties", which represent a
// list of all properties for the earthquake.
JSONObject properties = currentEarthquake.getJSONObject("properties");
// Extract the value for the key called "mag"
Double magnitude = properties.getDouble("mag");
// Extract the value for the key called "place"
String location = properties.getString("place");
// Extract the value for the key called "time"
long time = properties.getLong("time");
// Extract the value for the key called "url"
String url = properties.getString("url");
// Create a new {#link Earthquake} object with the magnitude,locaton,time, and url
// from the JSON response
Earthquake earthquake = new Earthquake(magnitude, location, time,url);
// Add the new {#link Earthquake} to the list of earthquakes.
earthquakes.add(earthquake);
}
} catch (JSONException e) {
// If an error is thrown when executing any of the above statements in the "try" block,
// catch the exception here, so the app doesn't crash. Print a log message
// with the message from the exception.
Log.e("QueryUtils", "Problem parsing the earthquake JSON results", e);
}
// Return the list of earthquakes
return earthquakes;
}
}
Earthquake.java
package com.example.quakereport;
import android.content.Context;
public class Earthquake {
private Double mMagnitude;
private String mLocation;
private String mDate;
private long mTimeInMillisecond;
private String mUrl;
public Earthquake(Double Magnitude, String Location, long TimeInMIllisecond, String Url) {
mMagnitude = Magnitude;
mLocation = Location;
mTimeInMillisecond = TimeInMIllisecond;
mUrl = Url;
}
public Double getmMagnitude() {
return mMagnitude;
}
public String getmLocation() {
return mLocation;
}
public String getmUrl() {
return mUrl;
}
public long getmTimeInMillisecond() {
return mTimeInMillisecond;
}
}
EartquakeAdapter.java
public class EarthquakeAdapter extends ArrayAdapter<Earthquake> {
private static final String LOCATION_SEPARATOR = "of";
public EarthquakeAdapter (Context context, List<Earthquake> place)
{
super(context,0,place);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null)
{
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.earthquake_list_item,parent,false);
}
Earthquake currentEarthQuake = getItem(position);
TextView magnitude = (TextView) listItemView.findViewById(R.id.magnitude);
// Formate The Magnitude to show 1 decimal place
String formattedMaginitude = formatedMagnitude(currentEarthQuake.getmMagnitude());
magnitude.setText(formattedMaginitude);
//Set the prope background color on the magnitude circle.
// Fetch the background fom the Textview, which is a GadientDrawable.
GradientDrawable maginitudeCircle = (GradientDrawable) magnitude.getBackground();
// Get the appropriate background color based on the current earthquake magnitude
int magnitudeColor = getMagnitudeColor(currentEarthQuake.getmMagnitude());
// Set the color on the magnitude cicle
maginitudeCircle.setColor(magnitudeColor);
String originallocation = currentEarthQuake.getmLocation();
String primaryLocation;
String locationOffset;
if(originallocation.contains(LOCATION_SEPARATOR))
{
String[] parts = originallocation.split(LOCATION_SEPARATOR);
locationOffset = parts[0] + LOCATION_SEPARATOR;
primaryLocation = parts[1];
}else {
locationOffset= getContext().getString(R.string.near_the);
primaryLocation = originallocation;
}
TextView primarrylocation = (TextView) listItemView.findViewById(R.id.location_primarry);
primarrylocation.setText(primaryLocation);
TextView locationOffsetView = (TextView) listItemView.findViewById(R.id.location_offset);
locationOffsetView .setText(locationOffset);
// TextView locationView = (TextView) listItemView.findViewById(R.id.location_primarry);
// locationView.setText(currentEarthQuake.getmLocation());
Date dateObject = new Date(currentEarthQuake.getmTimeInMillisecond());
TextView dateView = (TextView) listItemView.findViewById(R.id.date);
// Fomate the date string (ex "Mar 3, 1995")
String formattedDate = formatDate(dateObject);
dateView.setText(formattedDate);
TextView timeView = (TextView) listItemView.findViewById(R.id.time);
String formattedtime = formatTime(dateObject);
timeView.setText(formattedtime);
return listItemView;
}
private int getMagnitudeColor(double magnitude)
{
int mgnitudeColorResourceId;
int magnitudeFloor = (int) Math.floor(magnitude);
switch (magnitudeFloor)
{
case 0:
case 1:
mgnitudeColorResourceId = R.color.magnitude1;
break;
case 2:
mgnitudeColorResourceId = R.color.magnitude2;
break;
case 3:
mgnitudeColorResourceId = R.color.magnitude3;
break;
case 4:
mgnitudeColorResourceId = R.color.magnitude4;
break;
case 5:
mgnitudeColorResourceId = R.color.magnitude5;
break;
case 6:
mgnitudeColorResourceId = R.color.magnitude6;
break;
case 7:
mgnitudeColorResourceId = R.color.magnitude7;
break;
case 8:
mgnitudeColorResourceId = R.color.magnitude8;
break;
case 9:
mgnitudeColorResourceId = R.color.magnitude9;
break;
default:
mgnitudeColorResourceId = R.color.magnitude10plus;
break;
}
return ContextCompat.getColor(getContext(),mgnitudeColorResourceId);
}
private String formatDate(Date dateObject){
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy");
return dateFormat.format(dateObject);
}
private String formatTime (Date dateObject){
SimpleDateFormat timeFormate = new SimpleDateFormat("h:mm a");
return timeFormate.format(dateObject);
}
private String formatedMagnitude(double magnitude){
DecimalFormat magnitudeFormate = new DecimalFormat("0.0");
return magnitudeFormate.format(magnitude);
}
}
In File: QueryUtils.java
You need to change this line of code
urlConnection.setRequestMethod("Get");
To this one
urlConnection.setRequestMethod("GET");
The error message explains it:
This Is the Error:- E/QueryUtils: problem recived the earthquake JSON result java.net.ProtocolException: Expected one of [OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, PATCH] but was Get at
It expected GET but it was Get

How to show coordinates-markers on Android App with Google Maps from XML file

I have an xml file with some places in it and their coordinates. I want to show those places on my android app on Google Maps as markers. I have already load the maps.
How could I do this? Any help would be so much appreciated, even if someone could explain it theoritically, as it seems I cant grasp its concept. Can someone help?
example of xml file(placesp.xml):
<placesp>
<placep>
<place_id>1</place_id>
<name>Place1</name>
<description>Place description 1</description>
<coordinates>;40.430224;21.559570</coordinates>
</placep>
<placep>
<place_id>2</place_id>
<name>Place2</name>
<description>Place description 2</description>
<coordinates>;40.423324;21.062439</coordinates>
</placep>
<placep>
<place_id>3</place_id>
<name>Place3</name>
<description>Place description 3</description>
<coordinates>;40.266952;21.238220</coordinates>
</placep>
</placesp>
Maybe you could use a HashMap to save the data.
You just create a new class like this:
public class Coordinates {
public static final HashMap<String, LatLng> COORDINATES = new HashMap<String, LatLng>();
static {
// Place1
COORDINATES.put("Place1", new LatLng(40.430224;21.559570));
}
}
You can access the data stored by the hashmap like this:
locationLatLng = new LatLng(Coordinates.COORDINATES.get("Place1").latitude,Coordinates.COORDINATES.get("Place1").longitude);
And then using this line in the class where you loaded the map to add the markers:
map.addMarker(new MarkerOptions().position(locationLatLng));
I am not really sure how to access data from the xml file, but in theory the logic is the same. You have to get a LatLng coordinate to tell the addMarker method where to put the marker, and thats actually it. I hope I could help you with this.
First you need to create a model class to hold the information for each place. I provide you a sample bellow: Place.class
public class Place {
private int placeId;
private String placeName;
private String placeDescription;
private double placeLongitude;
private double placeLatitude;
public Place() {
super();
}
public int getPlaceId() {
return placeId;
}
public void setPlaceId(final int placeId) {
this.placeId = placeId;
}
public String getPlaceName() {
return placeName;
}
public void setPlaceName(final String placeName) {
this.placeName = placeName;
}
public String getPlaceDescription() {
return placeDescription;
}
public void setPlaceDescription(final String placeDescription) {
this.placeDescription = placeDescription;
}
public double getPlaceLongitude() {
return placeLongitude;
}
public void setPlaceLongitude(final double placeLongitude) {
this.placeLongitude = placeLongitude;
}
public double getPlaceLatitude() {
return placeLatitude;
}
public void setPlaceLatitude(final double placeLatitude) {
this.placeLatitude = placeLatitude;
}
}
Next you will need a XML parser class to retrieve XML data to Place type list. You can use the following sample: PlaceXmlParser.class
public class PlaceXmlParser {
private static final String TAG = PlaceXmlParser.class.getSimpleName();
private static final String PLACE_ID = "place_id";
private static final String PLACE_NAME = "name";
private static final String PLACE_DESCRIPTION = "description";
private static final String PLACE_COORDINATES = "coordinates";
public PlaceXmlParser() {
super();
}
public List<Place> parsePlacesXml(final InputStream xmlStream) {
Place place = null;
final List<Place> placeList = new ArrayList<>();
try {
final XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
final XmlPullParser parser = xmlFactoryObject.newPullParser();
parser.setInput(xmlStream, null);
int event = parser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
if (event == XmlPullParser.START_TAG) {
final String name = parser.getName();
switch (name) {
case PLACE_ID:
place = new Place();
setPlaceId(parser, place);
break;
case PLACE_NAME:
setPlaceName(parser, place);
break;
case PLACE_DESCRIPTION:
setPlaceDescription(parser, place);
break;
case PLACE_COORDINATES:
setPlaceLatLong(parser, place);
placeList.add(place);
break;
}
}
event = parser.next();
}
} catch (final XmlPullParserException e) {
Log.e(TAG, e.toString());
} catch (final IOException e) {
Log.e(TAG, e.toString());
}
return placeList;
}
private boolean areValidArgs(final XmlPullParser parser, final Place place) {
return null != parser && null != place;
}
private void setPlaceId(final XmlPullParser parser, final Place place) {
if (areValidArgs(parser, place)) {
final String placeId = getTagValue(parser);
place.setPlaceId(Integer.parseInt(placeId));
}
}
private void setPlaceName(final XmlPullParser parser, final Place place) {
if (areValidArgs(parser, place)) {
final String placeName = getTagValue(parser);
place.setPlaceName(placeName);
}
}
private void setPlaceDescription(final XmlPullParser parser, final Place place) {
if (areValidArgs(parser, place)) {
final String placeDescription = getTagValue(parser);
place.setPlaceDescription(placeDescription);
}
}
private void setPlaceLatLong(final XmlPullParser parser, final Place place) {
if (areValidArgs(parser, place)) {
final String[] latLong = getTagValue(parser).split(";");
if (3 == latLong.length) {
place.setPlaceLatitude(Double.parseDouble(latLong[1]));
place.setPlaceLongitude(Double.parseDouble(latLong[2]));
}
}
}
private String getTagValue(final XmlPullParser parser) {
String result = "";
try {
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
} catch (final XmlPullParserException e) {
Log.e(TAG, e.toString());
} catch (final IOException e) {
Log.e(TAG, e.toString());
}
return result;
}
}
Finally, in you Google Map's activity, implement OnMapReadyCallback interface, override onMapReady method and add place markers to Google Map: MapActivity.class
public class MapActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private List<Place> placeList;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
this.placeList = getPlaceList();
}
#Override
public void onMapReady(final GoogleMap googleMap) {
this.mMap = googleMap;
addPlaceListMarkersToGoogleMap();
}
private void addPlaceListMarkersToGoogleMap() {
for (final Place place : this.placeList) {
final LatLong latLong = new LatLong(place.getPlaceLatitude(), place.getPlaceLongitude());
this.mMap.addMarker(new MarkerOptions().position(latLong).title(place.getPlaceName()));
}
}
private List<Place> getPlaceList() {
final String xmlString = "<placesp>" +
"<placep>" +
" <place_id>1</place_id>" +
" <name>Place1</name>" +
" <description>Place description 1</description>" +
" <coordinates>;40.430224;21.559570</coordinates>" +
"</placep>" +
"<placep>" +
" <place_id>2</place_id>" +
" <name>Place2</name>" +
" <description>Place description 2</description>" +
" <coordinates>;40.423324;21.062439</coordinates>" +
"</placep>" +
"<placep>" +
" <place_id>3</place_id>" +
" <name>Place3</name>" +
" <description>Place description 3</description>" +
" <coordinates>;40.266952;21.238220</coordinates>" +
"</placep>" +
"</placesp>";
final InputStream xmlStream = getXmlStream(xmlString);
final PlaceXmlParser parser = new PlaceXmlParser();
return parser.parsePlacesXml(xmlStream);
}
private InputStream getXmlStream(final String xmlString) {
InputStream xmlStream = null;
try {
xmlStream = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
}
return xmlStream;
}
}
Provided code works well for given XML sample, be aware of possible exceptions and handle it. Hope this help!

Fetching multiple rows from webservice and display it in android listview

i have this webservice:
[WebMethod]
public string findUserNameById(int Id)
{
return getStudent(Id);
}
public String getStudent(int id)
{
SqlConnection conn;
conn = Class1.ConnectionManager.GetConnection();
conn.Open();
SqlCommand newCmd = conn.CreateCommand();
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "select * from dbo.tblUser where Id=" + id + "";
SqlDataReader sdr = newCmd.ExecuteReader();
String address = null;
if (sdr.Read())
{
address = sdr.GetValue(0).ToString();
address += "," + sdr.GetValue(1).ToString();
address += "," + sdr.GetValue(2).ToString();
}
conn.Close();
return address;
}
which retrieve row values like this: Id, name, grade. and im calling this webservice from android application:
public class MainActivity extends AppCompatActivity {
private EditText editText;
private TextView textView;
private Handler mHandler= new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText)findViewById(R.id.editText);
textView = (TextView)findViewById(R.id.textView);
}
public void getName(View v){
String inputId =editText.getText().toString();
//String[] params= new String[]{"10.0.2.2",inputId};
String[] params= new String[]{"192.168.1.17:90",inputId};
new MyAsyncTask().execute(params);
}
class MyAsyncTask extends AsyncTask<String, Void, String>
{
public String SOAP_ACTION="http://tempuri.org/findUserNameById";
public String OPERATION_NAME ="findUserNameById";
public String WSDL_TARGET_NAMESPACE ="http://tempuri.org/";
public String SOAP_ADDRESS;
private SoapObject request;
private HttpTransportSE httpTransport;
private SoapSerializationEnvelope envelop;
Object response= null;
#Override
protected String doInBackground(String... params) {
SOAP_ADDRESS="http://"+params[0]+"/myWebService.asmx";
request= new SoapObject(WSDL_TARGET_NAMESPACE,OPERATION_NAME);
PropertyInfo pi=new PropertyInfo();
pi.setName("Id");
pi.setValue(Integer.parseInt(params[1]));
pi.setType(Integer.class);
request.addProperty(pi);
pi= new PropertyInfo();
envelop= new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelop.dotNet=true;
envelop.setOutputSoapObject(request);
httpTransport=new HttpTransportSE(SOAP_ADDRESS);
try{
httpTransport.call(SOAP_ACTION,envelop);
response=envelop.getResponse();
}
catch (Exception e){
response=e.getMessage();
}
return response.toString();
}
#Override
protected void onPostExecute(final String result){
super.onPostExecute(result);
mHandler.post(new Runnable() {
#Override
public void run() {
textView.setText(result);
}
});
}
}
I want to fetch all of the rows and display it in a list view in the android, how to do it?
the query will be like : select * from dbo.tblUser
what should i change in the webservice? also what should i do in java for android?
try this code-
SoapObject response = (SoapObject) envelope.getResponse();
yourArray=new String[response.getPropertyCount()];
for(int i=0;i<response.getPropertyCount();i++){
Object property = response.getProperty(i);
if(property instanceof SoapObject){
SoapObject final_object = (SoapObject) property;
yourArray[i] = final_object.getProperty("YOUR_PROPERTY_NAME");
}
}
I would recommend that you declare your MainAsyncTask like this:
public class MainAsyncTask extends AsyncTask<String, Void, String[]> {
Then modify doInBackground to do all the processing that you are now doing in onPostExecute (except for the Toast part if any) and have it return the String[] (or null if there's an error). You can store the result code in an instance variable of MainAsyncTask and return null on error. Then onPostExecute has access to the same info that it does with your current code. Finally, if there is no error, just call a method in your main activity from onPostExecute to do the UI updates, passing it the String[] result.
Declare one POJO -
class AllocatedData{
String Id, name, grade;
getters and constructor
}
Code -
List<AllocatedData> list = new ArrayList<AllocatedData>();
if (responseLevel4 != null) {
for(int i = 0; i < responseLevel4.getPropertyCount(); i++){
responseLevel5 = (SoapObject) responseLevel4.getProperty(i);
Data allocated = new AllocatedData(checkStringProperty("Id"),checkStringProperty("name"),
checkStringProperty("grade"));
list.add(allocated);
}
}
}
Which function handles if property is Null
public String checkStringProperty(String propertyName){
if(responseLevel5.hasProperty(propertyName)){
return responseLevel5.getProperty(propertyName).toString();
} else {
return null;
}
}
But my Suggestion is use JSON reponse Or generate response in JSON.
I tried it before in Asp.net web services in which difficult to generated JSON. try WCF services
Link :- http://www.codeproject.com/Articles/167159/How-to-create-a-JSON-WCF-RESTful-Service-in-sec
By Using json you can parse directly by GSON liabrary this is very fast as compate to SOAP.
Gson gson = new Gson();
for (int i = 0; i < array.length(); i++) {
AllocatedData app = gson.fromJson(array.getJSONObject(i).toString(), AllocatedData .class);
list.add(app);
}
I would suggest you to create a Model Class which holds all the Property you need to send back
Public class Address{
public int grade;
public String name;
public String grade;
}
Create List<Address> addressList;
Iterate through the result set you get from database and in each iteration create a address object and put it in List and return List as response
Edit
Android Side reading from list you can refer this link
http://seesharpgears.blogspot.in/2010/10/web-service-that-returns-array-of.html
SERVICE SIDE
Instead of this Line
if (sdr.Read())
{
address = sdr.GetValue(0).ToString();
address += "," + sdr.GetValue(1).ToString();
address += "," + sdr.GetValue(2).ToString();
}
change it to
List<Address> addressList=new ArrayList<Address>();
while (sdr.Read())
{
Address address=new Address();
address.id = sdr.GetValue(0);
address.name= sdr.GetValue(1).ToString();
address.grade=sdr.GetValue(2).ToString();
addressList.add(address);
}
return addressList;

android: 3 different markers have same data onclick, inner class

I have 3 markers in a map. I get marker data through a server and associate it through each marker. Due to data amount, I only get a subset of data for each marker (for development I have 3 markers, but there may be many more). So I associate an ID to each marker, and for the next activity, I get that ID and retrieve the complete data set for the next activity to be displayed.
Unfortunately all markers end up being associated with the same ID. What am I missing here?
Initially I was passing a final variable to the inner class in order to assign the ID. Finding this question: How to pass parameters to anonymous class? (kudos!) I introduced an initializer to the inner class, thinking the final attribute might have been the problem. But nope. Still getting the same ID on all markers.
private class Getter extends AsyncTask<String, Void, JSONArray> {
private Exception exception;
protected static final String TAG = "Getter";
protected JSONArray doInBackground(String... urls) {
try {
try {
//get JSON data from server
return json_objects.getJSONArray("objects");
} catch (JSONException jse) {
//more error handling
}
}catch(Exception e) {
this.exception = e;
return null;
}
}
protected void onPostExecute(JSONArray obj_arr) {
try {
if (this.exception != null) {
//some error handling
} else if (obj_arr != null) {
for (int i = 0; i < obj_arr.length(); i++) {
JSONObject obj = obj_arr.getJSONObject(i);
create_marker(obj);
}
}
} catch(JSONException jse) {
//error handling
}
}
private void create_marker(JSONObject obj) {
try {
JSONObject location = obj.getJSONObject("location");
double lat = location.getDouble("lat");
double lng = location.getDouble("lng");
String id = obj.getString("id");
LatLng pos = new LatLng(lat, lng);
mMap.addMarker(new MarkerOptions().position(
pos).title(obj.getString("name")).
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
String local_id;
public GoogleMap.OnMarkerClickListener init(String id) {
local_id = id;
return this;
}
#Override
public boolean onMarkerClick(Marker marker) {
Intent i = new Intent(MapActivity.this, NextActivity.class);
i.putExtra("obj_id", local_id);
startActivity(i);
return false;
};
}.init(id));
} catch (JSONException e) {
//error handling
}
}
}

How to get hashmap key and value in java from another function

I have a json parse like this
public class SecondFragment extends Fragment implements OnClickListener {
// URL to get contacts JSON
private static String contestUrl = "http://api.apps.com/contest";
// JSON Node names
private static final String TAG_ITEM_ID = "id";
private static final String TAG_URL = "url";
private static final String TAG_START_DATE = "start_date";
private static final String TAG_END_DATE = "end_date";
// contacts JSONArray
JSONArray foods = null;
// Hashmap for ListView
ArrayList<HashMap<String, String>> foodslist;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
foodslist = new ArrayList<HashMap<String, String>>();
// Calling async task to get json
new GetContacts().execute();
}
/**
* Async task class to get json by making HTTP call
* */
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(contestUrl, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
foods = new JSONArray(jsonStr);
// looping through All Contacts
for (int i = 0; i < foods.length(); i++) {
JSONObject c = foods.getJSONObject(i);
String id = c.getString(TAG_ITEM_ID);
String name = c.getString(TAG_URL);
String email = c.getString(TAG_START_DATE);
String address = c.getString(TAG_END_DATE);
// tmp hashmap for single contact
HashMap<String, String> contact = new HashMap<String, String>();
// adding each child node to HashMap key => value
contact.put(TAG_ITEM_ID, id);
contact.put(TAG_URL, name);
contact.put(TAG_START_DATE, email);
contact.put(TAG_END_DATE, address);
String start_date = (String)contact.get(TAG_ITEM_ID);
// adding contact to contact list
foodslist.add(contact);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
}
}
I have two function, onCreate and GetContacts. In the end of onCreate it call GetContacts and call this json.
My question is, how can I got the Hashmap value on GetContacts so I can use it on onCreate
So far, I got this to get the value of Hashmap
String start_date = (String)contact.get(TAG_ITEM_ID);
But, its only works on GetContacts.
Anyone can help me?
Thanks Before
There are couple of ways:
Way-1:
Create instance variable (class-level) of HashMap contact and then you can use it anywhere within class inclusing onCreate and getContacts method.
package stackoverflow.q_25034927;
import java.util.HashMap;
import java.util.Map;
public class PassVariable {
private static Map<String, String> contact = new HashMap<String, String>();
public void onCreate() {
//populate contact object as per your logic
getContacts();
}
private void getContacts() {
//Use contact object directly which was pre-populby onCreate method.
}
}
Way-2:
Pass map to the getContacts() method:
package stackoverflow.q_25034927;
import java.util.HashMap;
import java.util.Map;
public class PassVariable {
public void onCreate() {
final Map<String, String> contact = new HashMap<String, String>();
//populate contact object as per your logic.
getContacts(contact);
}
private void getContacts(Map<String, String> contact) {
//Use contact object which is passed as argument.
}
}
On other side, please use cameCasing while naming Java methods or variables. GetContacts is not right, make it getContacts.
For email and address fields, using TAG_START_DATE and TAG_END_DATE is no fun. :-)
String email = c.getString(TAG_START_DATE);
String address = c.getString(TAG_END_DATE);
To answer about #3 below, variable s is not accessible in NotInner class:
package com.test;
public class Test {
static String s = "";
}
class NotInner {
public static void main(String[] args) {
System.out.println(s); //Compilation error: s cannot be resolved to a variable
}
}
You have
List<Map<String,String>> foodslist = ...;
which is filled in the loop.
To get at individual values, iterate:
for( Map<String,String> item: foodslist ){
String id = item.get(TAG_ITEM_ID);
String name = item.get(TAG_URL);
String email = item.get(TAG_START_DATE);
String address = item.get(TAG_END_DATE);
}
Or you write a method for the class where you keep foodslist:
String getAttr( int i, String tag ){
return foodslist.get(i).get(tag);
}
and you can call
String id = xxx.getAttr( i, TAG_ITEM_ID );
So return the data ...
public List<Map<String, String>> getContacts() {
if (foodslist != null && foodslist.isEmpty()) {
return foodslist;
}
foodslist = new ArrayList<Map<String, String>>();
try {
foods = new JSONArray(jsonStr);
// looping through All Contacts
for (int i = 0; i < foods.length(); i++) {
JSONObject c = foods.getJSONObject(i);
String id = c.getString(TAG_ITEM_ID);
String name = c.getString(TAG_URL);
String email = c.getString(TAG_START_DATE);
String address = c.getString(TAG_END_DATE);
// tmp hashmap for single contact
HashMap<String, String> contact = new HashMap<String, String>();
// adding each child node to HashMap key => value
contact.put(TAG_ITEM_ID, id);
contact.put(TAG_URL, name);
contact.put(TAG_START_DATE, email);
contact.put(TAG_END_DATE, address);
// adding contact to contact list
foodslist.add(contact);
}
return foodslist;
}
Though I'm not sure why that variable is called foodslist if it's supposed to contain contacts.

Categories