IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

En aquesta pàgina s'indica com implementar aplicacions que es connectin a la xarxa utilitzant el protocol HTTP.

Permisos

Cal tenir en compte que per realitzar operacions de xarxa, el fitxer de manifest de la nostra aplicació ha de tenir definits els següents permisos:

 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Clients HTTP

La majoria d'aplicacions Android connectades a internet utilitzen el protocol HTTP per enviar i rebre dades.

Android ofereix dos clients HTTP:

HttpURLConnection
Apache HttpClient

Tots dos suporten HTTPS, streaming uploads i downloads, timeouts configurables, IPv6, i connection pooling. Es recomana l'ús de HttpURLConnection per aplicacions des de la versió Gingerbread o superior.

Recursos:

Comprovar la connexió de xarxa

Abans de realitzar una connexió de xarxa, és una bona pràctica comprovar que el vostre dispositiu està connectat utilitzant el mètode:

getActiveNetworkInfo()

i

isConnected()

De les classes:

ConnectivityManager

i

NetworkInfo

Vegem un exemple:

public void myClickHandler(View view) {
    ...
    ConnectivityManager connMgr = (ConnectivityManager) 
        getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnected()) {
        // fetch data
    } else {
        // display error
    }
    ...
}

Recursos:

Threads i operacions de xarxa

Vegeu Android Threads per a més informació

Les operacions de xarxa poden implicar retards imprevisibles, i per tant, és imprescindible realitzar les operacions de connexió de xarxa en Threads independents del UI thread per evitar que la nostra aplicació es pengi o tingui un comportament que doni una mala experiència final al usuari.

La classe AsyncTask proporciona una de les formes més senzilles de fer-ho.

Anem a veure un exemple on el mètode:

myClickHandler() 

invoca:

DownloadWebpageTask().execute(stringUrl)

La classe DownloadWebpageTask és una subclasse d'AsyncTask. DownloadWebpageTask implementa els següents mètodes:

El codi és:

public class HttpExampleActivity extends Activity {
    private static final String DEBUG_TAG = "HttpExample";
    private EditText urlText;
    private TextView textView;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);   
        urlText = (EditText) findViewById(R.id.myUrl);
        textView = (TextView) findViewById(R.id.myText);
    }

    // When user clicks button, calls AsyncTask.
    // Before attempting to fetch the URL, makes sure that there is a network connection.
    public void myClickHandler(View view) {
        // Gets the URL from the UI's text field.
        String stringUrl = urlText.getText().toString();
        ConnectivityManager connMgr = (ConnectivityManager) 
            getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            new DownloadWebpageText().execute(stringUrl);
        } else {
            textView.setText("No network connection available.");
        }
        //http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html
    }

     // Uses AsyncTask to create a task away from the main UI thread. This task takes a 
     // URL string and uses it to create an HttpUrlConnection. Once the connection
     // has been established, the AsyncTask downloads the contents of the webpage as
     // an InputStream. Finally, the InputStream is converted into a string, which is
     // displayed in the UI by the AsyncTask's onPostExecute method.
     private class DownloadWebpageText extends AsyncTask {
        @Override
        protected String doInBackground(String... urls) {
              
            // params comes from the execute() call: params[0] is the url.
            try {
                return downloadUrl(urls[0]);
            } catch (IOException e) {
                return "Unable to retrieve web page. URL may be invalid.";
            }
        }
        // onPostExecute displays the results of the AsyncTask.
        @Override
        protected void onPostExecute(String result) {
            textView.setText(result);
       }
    }
    ...
}

Al següent apartat podeu veure el detall del mètode downloadUrl

La seqüència d'esdeveniments és la següent:

  • When users click the button that invokes myClickHandler(), the app passes the specified URL to the AsyncTask subclass DownloadWebpageTask.
  • The AsyncTask method doInBackground() calls the downloadUrl() method.
  • The downloadUrl() method takes a URL string as a parameter and uses it to create a URL object.
  • The URL object is used to establish an HttpURLConnection.
  • Once the connection has been established, the HttpURLConnection object fetches the web page content as an InputStream.
  • The InputStream is passed to the readIt() method, which converts the stream to a string.
  • Finally, the AsyncTask's onPostExecute() method displays the string in the main activity's UI.

Recursos:

Connectar-se i descarregar-se dades (download)

La connexió es realitzar amb una petició HTTP de tipus GET i es descarreguen les dades i es llegeixen amb getInputStream()

Vegem un exemple de mètode downloadUrl:

// Given a URL, establishes an HttpUrlConnection and retrieves
// the web page content as a InputStream, which it returns as
// a string.
private String downloadUrl(String myurl) throws IOException {
    InputStream is = null;
    // Only display the first 500 characters of the retrieved
    // web page content.
    int len = 500;
        
    try {
        URL url = new URL(myurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        // Starts the query
        conn.connect();
        int response = conn.getResponseCode();
        Log.d(DEBUG_TAG, "The response is: " + response);
        is = conn.getInputStream();

        // Convert the InputStream into a string
        String contentAsString = readIt(is, len);
        return contentAsString;
        
    // Makes sure that the InputStream is closed after the app is
    // finished using it.
    } finally {
        if (is != null) {
            is.close();
        } 
    }
}

Cal tenir en compte que el mètode:

getResponseCode()

retorna el status code de la connexió el que permet depurar la connexió (404 és el coi Not Foud, 200 el codi de tot correcte, 500 un error de servidor, etc...). Vegeu HTTP i HTTP Status codes.

Al següent apartat vegem la conversió a text del InputStream utilitzant el mètode readIt.

Convertir el InputStream a String

Les dades descarregades poden ser de diferents tipus (vegeu mime types). Per exemple, de tipus binari i una imatge:

InputStream is = null;
...
Bitmap bitmap = BitmapFactory.decodeStream(is);
ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setImageBitmap(bitmap);

En canvi per descarregar un text, per exemple un HTML:

// Reads an InputStream and converts it to a String.
public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
    Reader reader = null;
    reader = new InputStreamReader(stream, "UTF-8");        
    char[] buffer = new char[len];
    reader.read(buffer);
    return new String(buffer);
}

Vegeu també

Enllaços externs