940 likes | 1.06k Views
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
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