940 likes | 1.07k Vues
This lecture delves into the essentials of communicating over the Internet in mobile programming. We'll explore HTML, HTTP methods (GET and POST), and how to use HttpUrlConnection to retrieve data from the web. Participants will learn how to display HTML in WebViews and fetch data asynchronously using threads. Additionally, we will introduce JSON and Web APIs, essential components for modern mobile app development. Practical examples, including accessing pages and viewing HTML source, will be provided for hands-on understanding.
E N D
Mobile Programming Lecture 14 Communicating via the Internet
Agenda • A look at HTML • HttpUrlConnection • HttpGet • A more in-depth look at XML • Introducing JSON • Introducing Web APIs • ProgrammableWeb.com
A look at HTML • Go to http://www.imdb.com and search for your favorite movie • Right click on the page and view the source • Not surprisingly, you will find that the source behind the page is not easy to read
A look at HTML You can load HTML into a WebView Try this WebView wv = (WebView) findViewById(R.id.webView); wv.loadData("<html><body><h1>Hi Mom!</h1><br/><h2>Dad," + " sup?</h2></body></html>", "text/html", "UTF-8");
A look at HTML • HTTP defines 9 methods/verbs indicating the desired action to be performed on a URL • For now, we will only look at 2 of the verbs • GET • POST
A look at HTML • HTTP GET • Requests a representation of the specified resource. Requests using GET should only retrieve data and should have no other effect • HTTP POST • Submits data to be processed (e.g., from an HTML form) to the identified resource. The data is included in the body of the request.
A look at HTML Get is like a query. You can usually modify the arguments to the query directly Not the same with POST!
A look at HTML What if you want to read this data (the HTML source) in Android?
HttpUrlConnection • used to send and receive data over the web • data may be of any type and length
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); }
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } We will use this WebView to display a page
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } We need to run network routines on a separate thread, otherwise we will get Exceptions
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } To run a block of code on a separate thread (i.e., not on the UI aka main thread)
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } Create an instance of Thread
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } Pass an anonymous inner Runnable class as the argument to the Thread constructor
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } Override the run() method of Runnable
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } Add your code block to the run() method
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } Call start() on the Thread
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } URL object identifies the location of an Internet resource
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } HttpURLConnection used to (send and) receive data over the Internet
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } Get an instance of it by calling openConnection() on the URL
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } Get an InputStream for reading in the data
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } A one-liner that I stole from here for reading in all of the data using the InputStream
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } Release the resources held by the connection
HttpUrlConnection @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView) findViewById(R.id.webView); new Thread(new Runnable() { @Override public void run() { URL url = new URL("http://mobile.cs.fsu.edu/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); data = new java.util.Scanner(in).useDelimiter("\\A").next(); urlConnection.disconnect(); wv.loadData(data, "text/html", "UTF-8"); } }).start(); } data should now contain the HTML returned by the URL. We load the data into the WebView
A look at HTML HTML tells the browser how the server wants to display information to the user • How would the server send this information to your device, efficiently?
HttpUrlConnection See HttpUrlConnectionExample.tar
HttpUrlConnection What happens if we try to open a connection to an invalid URL? URL url = new URL("http://mobiles.cs.fsu.edu/"); with an extra "s" after mobile, instead of URL url = new URL("http://mobile.cs.fsu.edu/");
HttpUrlConnection We need to check the HTTP response code for errors first, then act accordingly
HttpGet HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(); request.setURI(new URI("http://mobile.cs.fsu.edu/androids")); HttpResponse response = client.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); if(statusCode == 200) { in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) sb.append(line + NL); in.close(); browser.loadData(sb.toString(), "text/html", "UTF-8"); }
HttpGet HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(); request.setURI(new URI("http://mobile.cs.fsu.edu/androids")); HttpResponse response = client.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); if(statusCode == 200) { in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) sb.append(line + NL); in.close(); browser.loadData(sb.toString(), "text/html", "UTF-8"); } This takes care of a bunch of mumbo jumbo that you don't want to deal with
HttpGet HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(); request.setURI(new URI("http://mobile.cs.fsu.edu/androids")); HttpResponse response = client.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); if(statusCode == 200) { in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) sb.append(line + NL); in.close(); browser.loadData(sb.toString(), "text/html", "UTF-8"); } Use HttpGet to retrieve whatever information is identified by the request-URI
HttpGet HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(); request.setURI(new URI("http://mobile.cs.fsu.edu/androids")); HttpResponse response = client.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); if(statusCode == 200) { in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) sb.append(line + NL); in.close(); browser.loadData(sb.toString(), "text/html", "UTF-8"); } set the URI!
HttpGet Check this link out to learn more about status codes. 200 means OK! HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(); request.setURI(new URI("http://mobile.cs.fsu.edu/androids")); HttpResponse response = client.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); if(statusCode == 200) { in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) sb.append(line + NL); in.close(); browser.loadData(sb.toString(), "text/html", "UTF-8"); }
HttpGet HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(); request.setURI(new URI("http://mobile.cs.fsu.edu/androids")); HttpResponse response = client.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); if(statusCode == 200) { in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) sb.append(line + NL); in.close(); browser.loadData(sb.toString(), "text/html", "UTF-8"); } If the status is OK, then write the rest of the code that will handle a successful GET
HttpGet HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(); request.setURI(new URI("http://mobile.cs.fsu.edu/androids")); HttpResponse response = client.execute(request); final int statusCode = response.getStatusLine().getStatusCode(); if(statusCode == 200) { in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) sb.append(line + NL); in.close(); browser.loadData(sb.toString(), "text/html", "UTF-8"); } Then you may also wish to handle cases when the status is NOT OK.
HttpGet See HttpGetExample.tar
In-depth Look at XML • XML doesn't replace HTML • XML doesn't do anything • something is done with the XML • You can invent your own tags with XML
In-depth Look at XML • Simplifies data sharing • Simplifies data transport • You can invent your own tags with XML
In-depth Look at XML <?xmlversion="1.0"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
In-depth Look at XML <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="CHILDREN"> <title lang="en">Snow White</title> <author>Brothers Grimm</author> <year>1812</year> <price>39.95</price> </book> </bookstore>
In-depth Look at XML <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="CHILDREN"> <title lang="en">Snow White</title> <author>Brothers Grimm</author> <year>1812</year> <price>39.95</price> </book> </bookstore> "bookstore" is the root element
In-depth Look at XML <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="CHILDREN"> <title lang="en">Snow White</title> <author>Brothers Grimm</author> <year>1812</year> <price>39.95</price> </book> </bookstore> bookstore has 3 children
In-depth Look at XML <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="CHILDREN"> <title lang="en">Snow White</title> <author>Brothers Grimm</author> <year>1812</year> <price>39.95</price> </book> </bookstore> each one is a "sibling" to the other (title, author, year, price)
In-depth Look at XML <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="CHILDREN"> <title lang="en">Snow White</title> <author>Brothers Grimm</author> <year>1812</year> <price>39.95</price> </book> </bookstore> An element may have children (book element has 4 children in this case)
In-depth Look at XML <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="CHILDREN"> <title lang="en">Snow White</title> <author>Brothers Grimm</author> <year>1812</year> <price>39.95</price> </book> </bookstore> and or attributes
In-depth Look at XML <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="CHILDREN"> <title lang="en">Snow White</title> <author>Brothers Grimm</author> <year>1812</year> <price>39.95</price> </book> </bookstore> and/or data
In-depth Look at XML <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="CHILDREN"> <title lang="en">Snow White</title> <author>Brothers Grimm</author> <year>1812</year> <price>39.95</price> </book> </bookstore> attribute values must always be within double quotes
In-depth Look at XML You can use an XML parser in Java to parse an XML file, in order to get the desired information
In-depth Look at XML • How do we get the movie information from IMDB? • We can only hope that someone has made the data available to us via XML