JSON and Google Local Search

来源:互联网 发布:淘宝客佣金是怎么扣的 编辑:程序博客网 时间:2024/06/05 14:45

原帖地址。。。。http://randamblings.wordpress.com/2010/04/08/day-4-json-and-google-local-search/

I posted yesterday that it looked like getting location information from Google would be pretty complicated. It took a while to work out what I needed to do, but in the end it wasn’t too bad.

Today’s Results

I met my goal again for today – I can search for specific locations, and they’re labelled on the map.

The items on the far left and right are indeed the nearest train stations. The one in the middle is actually a local pub – I’m not really sure why this result came up. For the most part this works really well though. It’s a bit laggy on loading the results, I need to come up with some sort of “Please wait, loading” popup, because currently it just hangs for a few seconds. In some cases it freezes when I search, and I’m not sure why, it seems fairly random. But generally, it works. If you tap one of the markers, currently it gives you a popup with information about the location

Compared again to Google maps to show accuracy -

Obviously I could do with making my markers smaller, and ideally tapping on a location would bring up another overlay, or take you to another screen. It’s just for testing purposes right now though.

The Code

Strangely, Google saw fit to not include any Google search functionality in their API. Presumably this is so people can’t steal their results and use them without branding, or something to that effect. I don’t really see how this is any different to being able to access it through your own web site though. But, there’s still a way to do it. I thought this would involve coding my own search script in javascript or some such, but it turns out they’ve done that much for us.

If you take this link – http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=banana – it does a google search for ‘banana’ and outputs the results in a format known as JSON. Somewhat similar in principle to XML, it’s basically a standard way of outputting sets of data, each of which has a type and a value. Normally if you want to take data from a text file and turn it into something you can manipulate in a program, you need to go through the long and boring task of writing methods to read a file, split it up, and work out what each section means.

Enter Jackson. Jackson is a fantastic library which does all the hard work for you. All you have to do is give it the JSON text, set up some classes which match the the data that’s included in it, and set it to work. Android does actually have it’s own JSON parser built in, but it’s not as simple to use, and apparently not as efficient. Jackson works just fine with Android though, so it’s easy to implement in your apps. There’s a basic tutorial over at the Jackson website (I’ll post it at the end of the post) which covers the basics, and it’s pretty simple. Firstly, you need to set up a class that will hold all the data from the JSON output. For example, if you had an output that had a list of people’s details, you’d want a Person class. In this class you just need to have parameter declarations which match the names of each item in the list, and getters and setters for each parameter. Google’s one outputs a bunch of stuff that you don’t really need, but you can just tell it to ignore anything you don’t define.

private double lat;

public double getLat() {
return lat;}
public void setLat(double lat) {
this.lat = lat;}

To get the results from the internet you need to set up an InputStream  with a HttpClient

public InputStream getJSONData(String url){

DefaultHttpClient httpClient = new DefaultHttpClient();
URI uri;
InputStream data = null;
try{
uri = new URI(url);
HttpGet method = new HttpGet(uri);
HttpResponse response = httpClient.execute(method);
data = response.getEntity().getContent();
}
catch(Exception e)
{
e.printStackTrace();
}

return data;

}

The code to turn the data into Java objects is so simple it hurts, assuming you have your classes set up correctly.

Reader r = new InputStreamReader(getJSONData(“http://ajax.googleapis.com/ajax/services/search/local?v=1.0&q=”+request+”&sll=”+lat+”,”+lng));
ObjectMapper mapper = new ObjectMapper();

mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
ResponseData responseData = mapper.readValue(r, ResponseData.class);

Results result = responseData.getResponseData();
results = result.getResults();

Thanks to the long result strings Google gives, it took 3 classes for me to get it to read it correctly. The ResponseData class just has a single Results item in it, and this then contains a list of Result items. There might be a simpler way to do it, but I was getting all sorts of errors any other way I did it. I set it to ignore ‘unknown properties’ (that is, anything that I haven’t defined in my classes) for 2 reasons – one, I don’t need all the data it gives you, two, it just failed to read one of the parameters (GsearchResultClass) no matter what I did. I’m not sure why, possibly to do with the capitalisation, but either way, I decided to just skip it.

If it all goes correctly. it should give you a list of result objects, which you can then use the getters you defined to get all your data out of it. Simple. The search URL for the Local search is a bit different -

http://ajax.googleapis.com/ajax/services/search/local?v=1.0&q=PLACE TO SEARCH FOR&sll=CO-ORDINATES TO SEARCH NEAR

for example

http://ajax.googleapis.com/ajax/services/search/local?v=1.0&q=train&sll=50.00001,-5.00001

Next I added a search box to my map screen, and set it to search when you hit the OK button

button.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {
double lat = p.getLatitudeE6()/1E6;
double lng = p.getLongitudeE6()/1E6;
results = gs.runJSONParser(URLEncoder.encode(edit.getText().toString()),lat,lng);
OverlayItem oi;
GeoPoint gp;
int lati;
int lngi;
itemizedoverlay.clearOverlays();
for(Result rs : results)
{
lati = (int)(rs.getLat()*1E6);
lngi = (int)(rs.getLng()*1E6);

gp = new GeoPoint(lati,lngi);
oi = new OverlayItem(gp,rs.getTitleNoFormatting(),rs.getStreetAddress());
itemizedoverlay.addOverlay(oi);
}
}

Here, we’re getting our current location, and the string in the search box, and passing it to our search function. Note that you need to convert the search string to a URI. This is the format of a web address, but essentially what this does here is convert any characters that a HTTP query can’t handle and convert them into something it can – for example converting a space into %20.

The Next Step:

I’m pretty much done with the back end stuff now, and I’ve got all the data I need. There are two other parts to the project -

  • Create a custom database so I can add my own locations to it
  • Turn it all into an augmented reality application

For those unfamiliar with the term augmented reality – it’s all the rage these days, applications that take your camera view, and overlay things on top of that. The idea of this app is that I’ll take this location information from Google, and overlay that on the camera, roughly at the location of the buildings.

I’m not really sure where to start with this, so it’ll be interesting. Over the last few days, I’ve been able to read up on the basics on various tutorials. Today I was getting to the point where there just wasn’t any information out there. There are obviously applications out there that do use Google search functionality, but most aren’t willing to share their experience. Along with that, Google doesn’t like people accessing search results directly via Android, so there’s no documentation for it.

Tomorrow’s Goal

Hard to say anything specific. I’ll have a look at setting up a Camera view and see what I can do with it.

Links of the Day

http://www.softwarepassion.com/android-series-parsing-json-data-with-gson/

This refers to using the GSON library for JSON parsing, which works similarly to Jackson, but is apparently slower.

http://wiki.fasterxml.com/JacksonInFiveMinutes

Jackson’s basic tutorial. Explains the basics very well.

http://code.google.com/apis/ajaxsearch/documentation/#fonje

Explains how to use Google’s search API and some basics of how to call it in Java.

As usual, feel free to leave a comment or email android@lc8n.co.uk if you need any further information. Interestingly this blog has had 40 hits today, and I’m not sure where from. I’ve been tagging it here and on twitter, but I have all of 5 followers on Twitter (ProbablyJoe if you feel so inclined) and I’ve given this link to about 5 people. Interesting.

原创粉丝点击