Chapter 10 Networking/Web Service Using HTTP

1. Consuming web services using HTTP

  <1>Downloading Binary Data

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="mirror.android.networing.Networing" >

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"/>

</RelativeLayout>
package mirror.android.networing;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;

public class Networing extends Activity {
    
    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_networking);
        
        new DownloadImageTask().execute("http://www.mayoff.com/5-01cablecarDCP01934.jpg");
    }
    
    private InputStream OpenHttpConnection(String urlString) throws IOException{
        
        InputStream in = null;
        URL url = new URL(urlString);
        URLConnection conn = url.openConnection();
        
        if (!(conn instanceof HttpURLConnection))
            throw new IOException("Not an HTTP connection");
        try{
            HttpURLConnection httpConn = (HttpURLConnection)conn;
            httpConn.setAllowUserInteraction(false);
            httpConn.setInstanceFollowRedirects(true);
            httpConn.setRequestMethod("GET");
            httpConn.connect();
            if(httpConn.getResponseCode() == HttpURLConnection.HTTP_OK){
                in = httpConn.getInputStream();
            }
        }
        catch(Exception ex){
            Log.d("Networking",ex.getLocalizedMessage());
            throw new IOException("Error connecting");
        }
        return in;
    }
    
    private Bitmap DownloadImage(String URL){
        Bitmap bitmap = null;
        try{
            InputStream in = OpenHttpConnection(URL);
            //Decode an input stream into a bitmap
            bitmap = BitmapFactory.decodeStream(in);
            in.close();
        }
        catch(IOException e){
            Log.d("NetworkingActivity", e.getLocalizedMessage());
        }
        return bitmap;
    }
    
    //An asynchronous task is defined by a computation that runs on a background thread 
    //and whose result is published on the UI thread. 
    private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>{

        @Override
        protected Bitmap doInBackground(String... urls) {
            return DownloadImage(urls[0]);
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            ImageView imageView = (ImageView)findViewById(R.id.img);
            imageView.setImageBitmap(result);
        }
    }
}

    

  If you want to download a series of images asynchronously, you can modify the DownloadImageTask class as follows:

package mirror.android.networing;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;

public class Networing extends Activity {
    
    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_networking);
        
        imageView = (ImageView)findViewById(R.id.img);
        
        new DownloadImageTask().execute("http://www.mayoff.com/5-01cablecarDCP01934.jpg",
                                        "http://www.hartiesinfo.net/greybox/Cable_Car_Hartbeespoort.jpg",
                                        "http://www.fantom-xp.com/wallpapers/63/San_Francisco_-_Sunset.jpg");
    }
    
    private InputStream OpenHttpConnection(String urlString) throws IOException{
        
        InputStream in = null;
        URL url = new URL(urlString);
        URLConnection conn = url.openConnection();
        
        if (!(conn instanceof HttpURLConnection))
            throw new IOException("Not an HTTP connection");
        try{
            HttpURLConnection httpConn = (HttpURLConnection)conn;
            httpConn.setAllowUserInteraction(false);
            httpConn.setInstanceFollowRedirects(true);
            httpConn.setRequestMethod("GET");
            httpConn.connect();
            if(httpConn.getResponseCode() == HttpURLConnection.HTTP_OK){
                in = httpConn.getInputStream();
            }
        }
        catch(Exception ex){
            Log.d("Networking",ex.getLocalizedMessage());
            throw new IOException("Error connecting");
        }
        return in;
    }
    
    private Bitmap DownloadImage(String URL){
        Bitmap bitmap = null;
        try{
            InputStream in = OpenHttpConnection(URL);
            //Decode an input stream into a bitmap
            bitmap = BitmapFactory.decodeStream(in);
            in.close();
        }
        catch(IOException e){
            Log.d("NetworkingActivity", e.getLocalizedMessage());
        }
        return bitmap;
    }
    
    //An asynchronous task is defined by a computation that runs on a background thread 
    //and whose result is published on the UI thread. 
    private class DownloadImageTask extends AsyncTask<String, Bitmap, Long>{

        //Perform a computation on a background thread. 
        @Override
        protected Long doInBackground(String... urls) {
            long imageCount = 0;
            for(int i = 0; i < urls.length ; i++){
                Bitmap imagesDownloded = DownloadImage(urls[i]);
                if(imagesDownloded != null){
                    imageCount ++;
                    try{
                        Thread.sleep(3000);
                    }
                    catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
                //publish updates on the UI thread
                publishProgress(imagesDownloded);
            }
            return imageCount;
        }
        
        //Runs on the UI thread after publishProgress is invoked. 
        @Override
        protected void onProgressUpdate(Bitmap... bitmap) {
            imageView.setImageBitmap(bitmap[0]);
        }

        //Runs on the UI thread after doInBackground finished
        @Override
        protected void onPostExecute(Long imageCount) {
            Toast.makeText(getApplication()
                        , "Total " + imageCount + " images downloaded"
                        , Toast.LENGTH_LONG).show();
        }
    }
}

  When you run the preceding code, the images are downloaded in the background and displayed at an interval of three seconds. When the

    last image has been downloaded, the Toast class displays the total number of images downloaded.

 

  <2>Downloading Text Content

package mirror.android.networing;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;

public class Networing extends Activity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_networking);
        
        new DownloadTextTask().execute("http://iheartquotes.com/api/v1/random?max_characters=256&max_lines=10");
    }
    
    private InputStream OpenHttpConnection(String urlString) throws IOException{
        
        InputStream in = null;
        URL url = new URL(urlString);
        URLConnection conn = url.openConnection();
        
        if (!(conn instanceof HttpURLConnection))
            throw new IOException("Not an HTTP connection");
        try{
            HttpURLConnection httpConn = (HttpURLConnection)conn;
            httpConn.setAllowUserInteraction(false);
            httpConn.setInstanceFollowRedirects(true);
            httpConn.setRequestMethod("GET");
            httpConn.connect();
            if(httpConn.getResponseCode() == HttpURLConnection.HTTP_OK){
                in = httpConn.getInputStream();
            }
        }
        catch(Exception ex){
            Log.d("Networking",ex.getLocalizedMessage());
            throw new IOException("Error connecting");
        }
        return in;
    }
    
    private String DownloadText(String URL){
        
        String readStrings = "";
        try {
            InputStream in = OpenHttpConnection(URL);
            InputStreamReader isr = new InputStreamReader(in);
            
            int charReadNumber;
            char[] inputBuffer = new char[2000];
            
            while((charReadNumber = isr.read(inputBuffer)) > 0){
                String readString = String.valueOf(inputBuffer, 0 , charReadNumber);
                readStrings += readString;
                inputBuffer = new char[2000];
            }
            in.close();
        } catch (Exception e) {
            Log.d("Networking", e.getLocalizedMessage());
            return "";
        }
        return readStrings;
    }
    
    //An asynchronous task is defined by a computation that runs on a background thread 
    //and whose result is published on the UI thread. 
    private class DownloadTextTask extends AsyncTask<String, Void, String>{

        //Perform a computation on a background thread. 
        @Override
        protected String doInBackground(String... urls) {
            return DownloadText(urls[0]);
        }

        //Runs on the UI thread after doInBackground finished
        @Override
        protected void onPostExecute(String result) {
            Toast.makeText(getApplication(), result , Toast.LENGTH_LONG).show();
        }
    }
}

    

  

  <3>Accessing Web Services Using the GET Method

  So far, you have learned how to download images and text from the web. The previous section showed how to download some plain text

    from a server. Very often, you need to download XML files and parse the contents (a good example of this is consuming web services).

  Therefore, in this section you learn how to connect to a web service using the HTTP GET method. Once the web service returns a

    result in XML, you extract the relevant parts and display its content using the Toast class.

    

  http://services.aonaware.com/DictService/

  This web method is from a dictionary web service that returns the defi nition of a given word. for example, look up "apple" in this dictionary

  This web method takes a request in the following fomat:

GET /DictService/DictService.asmx/Define?word=string HTTP/1.1
Host: services.aonaware.com
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

  returns a response in the following format:

<?xml version=”1.0” encoding=”utf-8”?>
<WordDefinition xmlns=”http://services.aonaware.com/webservices/”>
  <Word>string</Word>
  <Definitions>
    <Definition>
      <Word>string</Word>
      <Dictionary>
        <Id>string</Id>
        <Name>string</Name>
      </Dictionary>
      <WordDefinition>string</WordDefinition>
    </Definition>
    <Definition>       <Word>string</Word>       <Dictionary>         <Id>string</Id>         <Name>string</Name>       </Dictionary>       <WordDefinition>string</WordDefinition>     </Definition>   </Definitions> </WordDefinition>

  to obtain the definition of a word, you need to establish an HTTP connection to the web method and then parse the XML result that

    is returned.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="mirror.android.getwebservice.NetworkingActivity" >

    <TextView
        android:id="@+id/tv_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
       
     //To set the scrollbars in the vertical direction; android:maxLines=
"30" android:scrollbars="vertical" android:text="@string/hello_world" /> </RelativeLayout>
package mirror.android.getwebservice;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.widget.ScrollerCompat;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class NetworkingActivity extends Activity {

    private TextView textView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_word_definition);
        
        textView = (TextView)findViewById(R.id.tv_show);
     //To enable scroller textView.setMovementMethod(ScrollingMovementMethod.getInstance());
new AccessWebServiceTask().execute("apple"); } private InputStream OpenHttpConnection(String urlString) throws IOException{ InputStream in = null; URL url = new URL(urlString); URLConnection conn = url.openConnection(); if (!(conn instanceof HttpURLConnection)) throw new IOException("Not an HTTP connection"); try{ HttpURLConnection httpConn = (HttpURLConnection)conn; httpConn.setAllowUserInteraction(false); httpConn.setInstanceFollowRedirects(true); httpConn.setRequestMethod("GET"); httpConn.connect(); if(httpConn.getResponseCode() == HttpURLConnection.HTTP_OK){ in = httpConn.getInputStream(); } } catch(Exception ex){ Log.d("Networking",ex.getLocalizedMessage()); throw new IOException("Error connecting"); } return in; } private String WordDefinition(String word){ InputStream in = null; String strDefinition = ""; try {
       //
       //1.obtain a Document(DOM) object from an XML file(XML result returned by web service)
in = OpenHttpConnection("http://services.aonaware.com/DictService/DictService.asmx/Define?word=" + word); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(in); doc.getDocumentElement().normalize(); //Log.d("Mirror_DOC",doc.toString());
       //2.find all the elements with the <Definition> tag
// retrieve all the <Definition> elements NodeList definitionElements = doc.getElementsByTagName("Definition"); //Log.d("Mirror_definitionElements",definitionElements.toString() + ", its length is: " + definitionElements.getLength());
       //3.definition of a word is contained within the <WordDefinition> elment, then proceed to extract all the definitions
// iterate through each <Definition> elements for (int i = 0; i < definitionElements.getLength(); i++) { Node itemNode = definitionElements.item(i); if(itemNode.getNodeType() == Node.ELEMENT_NODE){ // convert the definition node into an Element Element definitionElement = (Element)itemNode; //get all the <WordDefinition> elements under the <Definition> element NodeList wordDefinitionElements = (definitionElement).getElementsByTagName("WordDefinition"); //NodeList wordDefinitionElements = definitionElement.
            //4.The text content of the <WordDefinition> element contains the defi nition of a word,
//iterate through each <Worddefinition> elements for (int j = 0; j < wordDefinitionElements.getLength(); j++) { // convert a <WordDefinition> node into an Element Element wordDefinitionElement = (Element)wordDefinitionElements.item(j); // get all the child nodes under the <WordDefinition> element NodeList textNodes = ((Node)wordDefinitionElement).getChildNodes(); strDefinition += ((Node)textNodes.item(0)).getNodeValue() + ". \n"; } } } } catch (Exception e) { Log.d("NetworkingActivity", e.getLocalizedMessage()); } return strDefinition; } private class AccessWebServiceTask extends AsyncTask<String, Void, String> { protected String doInBackground(String... urls) { return WordDefinition(urls[0]); } protected void onPostExecute(String result) { //Toast.makeText(getBaseContext(), result, Toast.LENGTH_LONG).show(); textView.setText(result); } } }

  Logcat : 5 definitions for the "apple" .

    

  

 

  

  

posted @ 2014-11-21 22:16  Mirrorhanman  阅读(250)  评论(0编辑  收藏  举报