WEBVTT 00:00:00.123 --> 00:00:06.268 [MUSIC] 00:00:06.268 --> 00:00:09.883 (University of Maryland) 00:00:10.854 --> 00:00:14.625 (Programming Mobile Applications for Android Handheld Systems) 00:00:15.639 --> 00:00:20.854 One of the defining characteristics of modern hand held systems is that they can 00:00:20.854 --> 00:00:26.266 keep us connected and networked without tethering us to a single location. 00:00:27.453 --> 00:00:30.400 In this lesson, we'll explore the software and 00:00:30.420 --> 00:00:36.254 programming practices that you'll need to connect your applications to the network. 00:00:37.091 --> 00:00:40.707 So I'll start this lesson by discussing networking in general. 00:00:41.262 --> 00:00:46.329 That discussion will focus on connecting your applications to the internet using 00:00:46.329 --> 00:00:55.587 the Hypertext Transfer Protocol or HTTP specifically by using HTTP GET requests. 00:00:56.827 --> 00:00:59.815 After that, I'll present several classes that 00:00:59.815 --> 00:01:03.075 Android provides to support this kind of networking. 00:01:04.005 --> 00:01:07.623 And lastly, I'll discuss how your applications can process the 00:01:07.623 --> 00:01:12.295 data they receive in response to these HTTP GET requests. 00:01:12.616 --> 00:01:17.148 In particular, I'll talk about two popular data formatting languages. 00:01:17.362 --> 00:01:22.365 One, the Javascript Object Notation Language, or JSON. 00:01:22.880 --> 00:01:27.602 And two, the Extensible Markup Language, or XML. 00:01:28.248 --> 00:01:31.712 And I'll talk about how you parse, or make sense, of 00:01:31.712 --> 00:01:35.832 these HTTP responses when they're formatted in one of these languages. 00:01:37.906 --> 00:01:41.104 So early handheld devices gave us mobility. 00:01:41.337 --> 00:01:46.444 You could move from one place to another, and still perform useful computation. 00:01:47.161 --> 00:01:48.029 However, 00:01:48.029 --> 00:01:51.823 their networking capabilities were primitive by today's standards. 00:01:52.755 --> 00:01:57.380 Now moving forward, today's devices combine powerful processors 00:01:57.380 --> 00:02:02.617 with fast network connections over WiFi and cellular networks. 00:02:03.495 --> 00:02:07.530 Handheld applications will therefore often want to make use 00:02:08.125 --> 00:02:13.138 of these networking capabilities to access and provide data, and services. 00:02:13.138 --> 00:02:18.244 Now, to help you do this, Android includes 00:02:18.244 --> 00:02:24.831 a variety of networking support classes, including the Socket and URL classes, 00:02:24.841 --> 00:02:26.903 in the Java.net packages. 00:02:27.561 --> 00:02:35.757 The HttpRequest and HttpResponse classes, in the org.apache packages. 00:02:36.616 --> 00:02:42.451 And the URI, AndroidHttpClient, and AudioStream classes, 00:02:42.743 --> 00:02:44.998 in the android.net packages. 00:02:46.166 --> 00:02:50.037 In this lesson we're going to look at several of these classes, 00:02:50.400 --> 00:02:54.956 using each of them to implement the same example application. 00:02:55.590 --> 00:02:58.869 And this application interacts with an internet service 00:02:59.226 --> 00:03:02.835 to get information about earthquakes that have occurred 00:03:02.835 --> 00:03:05.589 in a particular geographic region. 00:03:06.213 --> 00:03:10.519 And as you'll see, that data is returned in various formats. 00:03:10.868 --> 00:03:14.808 Now initially we'll just display the downloaded text as is. 00:03:15.518 --> 00:03:19.128 Later on in the lesson, I'll show you how to process that data 00:03:19.485 --> 00:03:22.884 to extract just the information that you want. 00:03:23.527 --> 00:03:25.294 Oh, and, and one other thing. 00:03:25.599 --> 00:03:26.888 As you'll see in a second, 00:03:27.101 --> 00:03:30.427 because this data includes geographic information, 00:03:30.801 --> 00:03:35.672 it's really begging to be displayed on a map, rather than as text. 00:03:35.672 --> 00:03:39.737 Now, we won't do that in this lesson, but keep this in mind, 00:03:39.737 --> 00:03:44.728 because we'll come back to this when we get to the lesson on maps and location. 00:03:45.744 --> 00:03:49.816 So in order to make this application work, the code needs to create 00:03:49.816 --> 00:03:55.951 an HTTP request, send it to a server computer, retrieve the results, 00:03:56.335 --> 00:04:00.988 and then display those results. Android provides several classes for 00:04:00.988 --> 00:04:05.736 helping with this. Three we'll talk about now are 00:04:05.736 --> 00:04:11.623 the Socket class, the HttpUrlConnection class 00:04:12.023 --> 00:04:15.189 and the AndroidHttpClient. 00:04:20.490 --> 00:04:23.910 I'll launch the networking socket application. 00:04:25.277 --> 00:04:26.363 As you can see, 00:04:26.628 --> 00:04:31.760 this application initially displays a single button labeled LoadData. 00:04:32.674 --> 00:04:36.106 When I press that button, the application will issue 00:04:36.106 --> 00:04:40.573 an HTTP GET request to an external server. 00:04:41.076 --> 00:04:44.978 And that server will respond with some complex text 00:04:45.388 --> 00:04:48.064 containing the requested earthquake data. 00:04:49.187 --> 00:04:50.008 Okay. 00:04:50.398 --> 00:04:57.331 So now I'll press the Load Data button and there you can see the requested data. 00:04:58.601 --> 00:05:02.942 Let's look at the source code to see what it took to get that data. 00:05:03.283 --> 00:05:05.797 Now here I've opened the application in the IDE. 00:05:08.259 --> 00:05:11.297 Now I'll open the main activity for this application. 00:05:13.376 --> 00:05:16.774 And here I'm showing the listener for the Load Data button. 00:05:18.684 --> 00:05:23.775 When this button is pressed, the application will create, and then execute, 00:05:23.775 --> 00:05:30.365 an AsyncTask called HttpGetTask. Let's look at that class. 00:05:31.725 --> 00:05:36.855 The HttpGetTask class first declares some variables, 00:05:37.040 --> 00:05:41.141 they're used in creating an HTTP GET Request. 00:05:42.917 --> 00:05:47.730 When the execute method is called, on the HttpGetTask, 00:05:48.480 --> 00:05:50.670 the doInBackground method is called. 00:05:51.986 --> 00:05:54.975 And that method begins by creating a new socket 00:05:55.611 --> 00:06:02.004 that will be connected to the host computer, api.geonames.org, 00:06:02.858 --> 00:06:08.664 on the standard http port, port 80. Next, the code gets 00:06:08.664 --> 00:06:14.137 the socket's output stream, and then writes the HTTPGETCOMMAND. 00:06:15.101 --> 00:06:19.846 And this string will be sent to the host computer, which interprets it 00:06:19.846 --> 00:06:23.993 as an HTTPGetRequest, and then responds 00:06:23.993 --> 00:06:27.441 by sending back the appropriate response data. 00:06:28.593 --> 00:06:32.927 And then this code continues by getting the socket's input stream 00:06:33.723 --> 00:06:37.235 And by passing it to a method called readStream. 00:06:38.629 --> 00:06:42.508 The readStream method ultimately reads the response data 00:06:42.761 --> 00:06:48.854 from the socket's InputStream and then returns the response as a single string. 00:06:50.385 --> 00:06:52.424 And this string is passed to the 00:06:52.424 --> 00:06:57.692 onPostExecute method which executes on the main thread 00:06:58.535 --> 00:07:01.754 and which displays the response in the text view. 00:07:02.485 --> 00:07:07.170 If we return back to the application, you'll notice that the response text 00:07:07.488 --> 00:07:13.005 includes not only the earthquake data, but also the HTTP response headers. 00:07:13.904 --> 00:07:17.554 Now normally, I wouldn't want to display that text here. 00:07:17.942 --> 00:07:20.365 I really just want to show you the earthquake data. 00:07:20.777 --> 00:07:24.162 So in the case, I should have parsed the response 00:07:24.517 --> 00:07:26.858 and pulled out just the data that I wanted. 00:07:28.528 --> 00:07:31.665 In addition, you might have noticed I didn't write any of the 00:07:31.665 --> 00:07:36.566 error handling code that you'd really need to make this application robust. 00:07:37.584 --> 00:07:42.442 And these points capture pretty well the trade-offs of using sockets. 00:07:42.442 --> 00:07:46.372 They're very low level: you can write whatever you want on the socket, 00:07:46.981 --> 00:07:50.904 but in return, you have to handle all the many details 00:07:50.908 --> 00:07:54.855 of making the HTTP requests, all the error handling, 00:07:55.197 --> 00:07:58.642 and all the processing of the HTTP responses. 00:08:02.160 --> 00:08:08.265 The next implementation we'll look at uses the HttpUrlConnection class. 00:08:08.904 --> 00:08:12.801 This class provides a higher-level interface that handles more 00:08:12.801 --> 00:08:17.034 of the networking details than the socket class does. 00:08:17.630 --> 00:08:21.463 But as we'll see in a moment, it also has a less flexible API 00:08:21.911 --> 00:08:27.566 than our last option, the Android HTTP client class. 00:08:28.480 --> 00:08:32.122 Now, having said that, I'll also point out that the Android team 00:08:32.122 --> 00:08:36.959 is not actively working on the Android HTTP client anymore. 00:08:36.959 --> 00:08:41.535 And is putting its efforts into improving this class going forward. 00:08:42.032 --> 00:08:45.052 So let's look at the example application 00:08:45.052 --> 00:08:50.687 implemented this time with the HttpURLConnection class. 00:08:51.476 --> 00:08:52.236 ... 00:08:52.236 --> 00:08:53.075 ... 00:08:53.075 --> 00:08:56.616 Now I'll launch the NetworkingURL application. 00:08:57.279 --> 00:09:00.201 As before, this application initially displays 00:09:00.201 --> 00:09:02.884 a single button labeled Load Data. 00:09:04.115 --> 00:09:08.498 And as before, when I press on that button the application will issue 00:09:08.498 --> 00:09:15.328 an HTTP GET request to an external server, and that server will respond 00:09:15.328 --> 00:09:19.763 with some complex text, containing the requested earthquake data. 00:09:20.314 --> 00:09:22.223 Okay, so now I'll press the 00:09:22.223 --> 00:09:23.550 Load Data button. 00:09:24.622 --> 00:09:28.805 There you can see the requested data, appearing in a text view. 00:09:29.630 --> 00:09:34.757 Notice, however, that this time, the HTTP response headers have been stripped out. 00:09:36.524 --> 00:09:39.095 Let's look at the source code and see how this works. 00:09:41.149 --> 00:09:44.237 Now, here I've got the application opened in the IDE. 00:09:45.167 --> 00:09:48.749 Now, I'll open the main activity for this application. 00:09:49.756 --> 00:09:53.156 And here, I'm showing the listener for the load data button. 00:09:54.382 --> 00:09:59.285 As before, when this button is pressed, the application will create and then 00:09:59.285 --> 00:10:06.749 execute an AsyncTask called, HttpGetTask. Let's look at that class. 00:10:08.706 --> 00:10:13.942 When the execute method is called on HTTPGetTask, the doInBackground method 00:10:13.942 --> 00:10:19.120 is invoked. That method begins by creating a new URL object, 00:10:19.717 --> 00:10:25.087 and passing a URL string for the desired service as a parameter. 00:10:26.480 --> 00:10:29.475 The code then calls the open connection method 00:10:29.475 --> 00:10:35.251 on the URL object, which returns an httpUrlConnection. 00:10:35.868 --> 00:10:41.115 This object is then stored in a variable called HttpURLConnection. 00:10:42.394 --> 00:10:47.998 The code continues by getting the HttpURLConnection's input stream, 00:10:48.562 --> 00:10:51.407 and by passing it through the readStream method. 00:10:52.440 --> 00:10:56.726 And as before, the readStream method reads the response data 00:10:56.726 --> 00:11:00.842 from the socket's input stream, and then returns the response, 00:11:01.132 --> 00:11:06.663 as a single string. This time however, the HTTP URL connection 00:11:07.036 --> 00:11:13.780 strips off the HTTP response headers and handles the error checking for you. 00:11:14.888 --> 00:11:18.810 Now this string is then passed to the onPostExecute method 00:11:19.674 --> 00:11:22.797 which displays the response in a text view. 00:11:24.772 --> 00:11:31.674 The third class is Android HTTP client. This class is an implementation of the 00:11:31.674 --> 00:11:38.783 Apache project's DefaultHttpClient and it allows a great deal of customization. 00:11:39.184 --> 00:11:44.388 In particular, the class breaks an HTTP transaction into 00:11:44.978 --> 00:11:50.613 a request object and into a response object. So you can create subclasses 00:11:50.613 --> 00:11:55.092 that customize the handling of requests and their responses. 00:11:55.517 --> 00:11:58.697 Now, by this point, you know what the application looks like, 00:11:58.928 --> 00:12:02.712 so let's jump straight into the code and look at the implementation. 00:12:05.050 --> 00:12:11.607 Now, here I've got the networking Android HTTP client application opened in the IDE. 00:12:12.753 --> 00:12:16.439 Now, I'll open the main activity for this application. 00:12:17.045 --> 00:12:20.786 And let's go right to the HTTP get task class. 00:12:22.160 --> 00:12:24.415 That class begins by creating a new 00:12:24.415 --> 00:12:31.193 AndroidHttpClient object by calling the classes newInstance method. 00:12:32.340 --> 00:12:36.352 Now, when the doInBackground method is called, the code creates 00:12:36.352 --> 00:12:42.775 an HttpGet object, passing in the URL string for that request. 00:12:43.484 --> 00:12:46.691 Next, it creates a ResponseHandler object. 00:12:47.105 --> 00:12:53.896 This object is responsible for handling the response to the HttpGet request. 00:12:53.896 --> 00:12:57.508 In this case, the ResponseHandler is of type 00:12:57.508 --> 00:13:02.446 basicResponseHandler, which will return the response's body. 00:13:03.288 --> 00:13:07.580 Now we'll see a more complex ResponseHandler later in this lesson. 00:13:08.919 --> 00:13:12.387 And finally, the request and the ResponseHandler 00:13:12.667 --> 00:13:15.066 are passed into the execute method, 00:13:15.457 --> 00:13:18.927 which sends the request, gets the response, 00:13:19.824 --> 00:13:21.968 passing it through the ResponseHandler. 00:13:23.014 --> 00:13:24.702 And the result of all this 00:13:24.702 --> 00:13:28.570 is then passed on to onPostExecute, 00:13:28.971 --> 00:13:31.731 which displays the response in a text field. 00:13:31.731 --> 00:13:36.246 [BLANK_AUDIO]