Tải bản đầy đủ (.pdf) (6 trang)

Lập trình Androi part 38 potx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (216.53 KB, 6 trang )



253
253
Chapter
Communicating via the
Internet
The expectation is that most, if not all, Android devices will have built-in Internet access.
That could be Wi-Fi, cellular data services (EDGE, 3G, etc.), or possibly something else
entirely. Regardless, most people—or at least those with a data plan or Wi-Fi access—
will be able to get to the Internet from their Android phone.
Not surprisingly, the Android platform gives developers a wide range of ways to make
use of this Internet access. Some offer high-level access, such as the integrated WebKit
browser component. If you want, you can drop all the way down to using raw sockets. In
between, you can leverage APIs—both on-device and from third-party JARs—that give
you access to specific protocols: HTTP, XMPP, SMTP, and so on.
The emphasis of this book is on the higher-level forms of access: the WebKit
component (discussed in Chapter 13) and Internet-access APIs (discussed in this
chapter). As busy coders, we should be trying to reuse existing components versus
rolling our own on-the-wire protocol wherever possible.
REST and Relaxation
Android does not have built-in SOAP or XML-RPC client APIs. However, it does have the
Apache HttpComponents library baked in. You can either layer a SOAP/XML-RPC layer
atop this library or use it “straight” for accessing REST-style web services. For the
purposes of this book, REST-style web services are considered simple HTTP requests
for ordinary URLs over the full range of HTTP verbs, with formatted payloads (XML,
JSON, etc.) as responses.
More expansive tutorials, FAQs, and HOWTOs can be found at the HttpClient web site
( Here, we’ll cover the basics, while checking the weather.
25


CHAPTER 25: Communicating via the Internet
254
HTTP Operations via Apache HttpClient
The HttpClient component of HttpComponents handles all HTTP requests on your
behalf. The first step to using HttpClient is, not surprisingly, to create an HttpClient
object. Since HttpClient is an interface, you will need to actually instantiate some
implementation of that interface, such as DefaultHttpClient.
Those requests are bundled up into HttpRequest instances, with different HttpRequest
implementations for each different HTTP verb (e.g., HttpGet for HTTP GET requests). You
create an HttpRequest implementation instance, fill in the URL to retrieve and other
configuration data (e.g., form values if you are doing an HTTP POST via HttpPost), and
then pass the method to the client to actually make the HTTP request via execute().
What happens at this point can be as simple or as complicated as you want. You can
get an HttpResponse object back, with a response code (e.g., 200 for OK), HTTP
headers, and the like. Or, you can use a flavor of execute() that takes a
ResponseHandler<String> as a parameter, with the net result being that execute()
returns just the String representation of the response body. In practice, this is not a
recommended approach, because you really should be checking your HTTP response
codes for errors. However, for trivial applications, like book examples, the
ResponseHandler<String> approach works just fine.
For example, let’s take a look at the Internet/Weather sample project. This implements
an activity that retrieves weather data for your current location from the National
Weather Service. (Note that this probably only works only for geographic locations in the
United States.) That data is converted into an HTML page, which is poured into a
WebKit widget for display. Rebuilding this demo using a ListView is left as an exercise
for the reader. Also, since this sample is relatively long, we will only show relevant
pieces of the Java code here in this chapter, though you can always download the full
source code from the Apress web site.
To make this a bit more interesting, we use the Android location services to figure out
where we are—well, sort of. The full details of how that works are left until Chapter 32.

In the onResume() method, we toggle on location updates, so we will be informed where
we are now and when we move a significant distance (10 kilometers). When a location is
available—either at the start or based on movement—we retrieve the National Weather
Service data via our updateForecast() method:
private void updateForecast(Location loc) {
String url=String.format(format, loc.getLatitude(),
loc.getLongitude());
HttpGet getMethod=new HttpGet(url);

try {
ResponseHandler<String> responseHandler=new BasicResponseHandler();
String responseBody=client.execute(getMethod,
responseHandler);

buildForecasts(responseBody);
CHAPTER 25: Communicating via the Internet
255
String page=generatePage();

browser.loadDataWithBaseURL(null, page, "text/html",
"UTF-8", null);
}
catch (Throwable t) {
Toast
.makeText(this, "Request failed: "+t.toString(), 4000)
.show();
}
}
The updateForecast() method takes a Location as a parameter, obtained from the
location update process. For now, all you need to know is that Location sports

getLatitude() and getLongitude() methods, which return the latitude and longitude of
the device’s position, respectively.
We hold the URL to the National Weather Service XML in a string resource, and pour in
the latitude and longitude at runtime. Given our HttpClient object created in
onCreate(), we populate an HttpGet with that customized URL, and then execute that
method. Given the resulting XML from the REST service, we build the forecast HTML
page, as described next, and pour that into the WebKit widget. If the HttpClient blows
up with an exception, we provide that error as a Toast.
Parsing Responses
The response you get will be formatted using some system—HTML, XML, JSON, or
whatever. It is up to you, of course, to pick out the information you need and do
something useful with it. In the case of the WeatherDemo, we need to extract the forecast
time, temperature, and icon (indicating sky conditions and precipitation), and generate
an HTML page from it.
Android includes three XML parsers: the traditional W3C DOM parser (org.w3c.dom), a
SAX parser (org.xml.sax), and the XML pull parser (discussed in Chapter 20). It also has
a JSON parser (org.json).
You are also welcome to use third-party Java code, where possible, to handle other
formats, such as a dedicated RSS/Atom parser for a feed reader. The use of third-party
Java code is discussed in Chapter 24.
For WeatherDemo, we use the W3C DOM parser in our buildForecasts() method:
void buildForecasts(String raw) throws Exception {
DocumentBuilder builder=DocumentBuilderFactory
.newInstance()
.newDocumentBuilder();
Document doc=builder.parse(new InputSource(new StringReader(raw)));
NodeList times=doc.getElementsByTagName("start-valid-time");

for (int i=0;i<times.getLength();i++) {
Element time=(Element)times.item(i);

Forecast forecast=new Forecast();
CHAPTER 25: Communicating via the Internet
256

forecasts.add(forecast);
forecast.setTime(time.getFirstChild().getNodeValue());
}

NodeList temps=doc.getElementsByTagName("value");

for (int i=0;i<temps.getLength();i++) {
Element temp=(Element)temps.item(i);
Forecast forecast=forecasts.get(i);

forecast.setTemp(new Integer(temp.getFirstChild().getNodeValue()));
}

NodeList icons=doc.getElementsByTagName("icon-link");

for (int i=0;i<icons.getLength();i++) {
Element icon=(Element)icons.item(i);
Forecast forecast=forecasts.get(i);

forecast.setIcon(icon.getFirstChild().getNodeValue());
}
}
The National Weather Service XML format is curiously structured, relying heavily on
sequential position in lists versus the more object-oriented style you find in formats like
RSS or Atom. That being said, we can take a few liberties and simplify the parsing
somewhat, taking advantage of the fact that the elements we want (start-valid-time

for the forecast time, value for the temperature, and icon-link for the icon URL) are
unique within the document.
The HTML comes in as an InputStream and is fed into the DOM parser. From there, we
scan for the start-valid-time elements and populate a set of Forecast models using
those start times. Then we find the temperature value elements and icon-link URLs
and fill those in to the Forecast objects.
In turn, the generatePage() method creates a rudimentary HTML table with the
forecasts:
String generatePage() {
StringBuffer bufResult=new StringBuffer("<html><body><table>");

bufResult.append("<tr><th width=\"50%\">Time</th>"+
"<th>Temperature</th><th>Forecast</th></tr>");

for (Forecast forecast : forecasts) {
bufResult.append("<tr><td align=\"center\">");
bufResult.append(forecast.getTime());
bufResult.append("</td><td align=\"center\">");
bufResult.append(forecast.getTemp());
bufResult.append("</td><td><img src=\"");
bufResult.append(forecast.getIcon());
bufResult.append("\"></td></tr>");
}
CHAPTER 25: Communicating via the Internet
257

bufResult.append("</table></body></html>");

return(bufResult.toString());
}

The result looks like Figure 25–1.

Figure 25–1. The WeatherDemo sample application
Stuff to Consider
If you need to use Secure Sockets Layer (SSL) protocol, bear in mind that the default
HttpClient setup does not include SSL support. Mostly, this is because you need to
decide how to handle SSL certificate presentation. Do you blindly accept all certificates,
even self-signed or expired ones? Or do you want to ask the users if they really want to
use some strange certificates?
Similarly, the HttpClient component, by default, is designed for single-threaded use. If
you will be using HttpClient from a service or some other place where multiple threads
might be an issue, you can readily set up HttpClient to support multiple threads.
For these sorts of topics, you are best served by checking out the HttpClient web site
for documentation and support.
CHAPTER 25: Communicating via the Internet
258

×