Autore Topic: [facile] HttpBookSearch: AsyncTask, HttpClient, XML parsing, ProgressDialog  (Letto 12248 volte)

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Livello di difficoltà: facile
Versione SDK utilizzata: 1.6
Link al file compresso del progetto eclipse: file in allegato

Posto un'altra applicazione didattica (nel senso che l'ho usata come pretesto per imparare AsyncTask dal tutorial di Qlimax e l'interrogazione di web services con risposte XML).

HttpBookSearch
  • descrizione : Inserito il codice ISBN di un libro, viene fatta una query al web service Google Book Search per ottenere titolo, autore e link alla pagina descrittiva del libro stesso, che può essere automaticamente aperta nel browser.
  • argomenti trattati : AsyncTask, HttpClient, XML parsing, ProgressDialog.
  • permissions : INTERNET
  • avvertenze: essendo didattica, non ho prestato particolare attenzione a gestire tutti gli errori ed il parsing XML è abbastanza grezzo





Layout

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" >

   <TextView  
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="Enter ISBN number (13 consecutive digits)" />

   <LinearLayout
     android:orientation="horizontal"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content" >
      <Button android:id="@+id/btnGet"
        android:text="Get"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
      <EditText android:id="@+id/editIsbn"
        android:text="9788850329212"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
   </LinearLayout>

   <LinearLayout
     android:orientation="vertical"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content" >
      <TextView android:id="@+id/txtTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />      
      <TextView android:id="@+id/txtAuthor"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />      
      <Button android:id="@+id/btnLink"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />      
   </LinearLayout>
   
   <ScrollView
     android:background="#333333"
     android:fillViewport="true"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content">
      <TextView android:id="@+id/txtDebug"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="Application Started" />      
   </ScrollView>

</LinearLayout>

Intestazioni

Codice (Java): [Seleziona]
package com.bradipao.httpbooksearch;

import java.io.IOException;
import java.io.StringReader;
import java.net.URI;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

Activity

Codice (Java): [Seleziona]
public class HttpBookSearch extends Activity {

   // vars
   int nbook=0;
   String result=null;
   HttpClient client=null;
   String title="",author="",link="";
   
   // views
   private ProgressDialog pd;
   private Button btnGet,btnLink;
   private EditText editIsbn;
   private TextView txtTitle,txtAuthor,txtDebug;
   
   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
     
      // imposto le views
      btnGet = (Button)findViewById(R.id.btnGet);
      editIsbn = (EditText)findViewById(R.id.editIsbn);
      txtTitle = (TextView)findViewById(R.id.txtTitle);
      txtAuthor = (TextView)findViewById(R.id.txtAuthor);
      btnLink = (Button)findViewById(R.id.btnLink);
      txtDebug = (TextView)findViewById(R.id.txtDebug);
     
      // listener del button GET
      OnClickListener mGetListener = new OnClickListener() {
         public void onClick(View v) {
            // inizializzo textview di debug
            txtDebug.setText("Application Started");
            // creo una progress dialog
            pd = ProgressDialog.show(HttpBookSearch.this,"Google ISBN query","Connecting...",true,false);
            // creo e avvio asynctask
            HttpGetTask task = new HttpGetTask();
            task.execute(editIsbn.getText().toString());
         }
      };
      btnGet.setOnClickListener(mGetListener);

      // listener del button LINK
      OnClickListener mLinkListener = new OnClickListener() {
         public void onClick(View v) {
            // creo l'intent
            Intent viewIntent = new Intent("android.intent.action.VIEW", Uri.parse(link));
            // avvio l'activity
            startActivity(viewIntent);
         }
      };
      btnLink.setOnClickListener(mLinkListener);
     
   }

AsyncTask

Codice (Java): [Seleziona]
   // my AsyncTask
   private class HttpGetTask extends AsyncTask<String,String,String>  {

      @Override
      protected String doInBackground(String... params) {

         result = null;
         
         // interrogazione del web service
         try {
           
            // aggiorno la progress dialog
            publishProgress("Creating HTTP client and query...");
           
            // creo la richiesta URI di tipo GET
            URI uri;
            uri = new URI("http",null,"books.google.com",-1,"/books/feeds/volumes","q=isbn:"+params[0],null);
            HttpUriRequest get = new HttpGet(uri);
           
            // istanzio il client HTTP
            client = new DefaultHttpClient();
           
            // istanzio il gestore automatico di risposte HTTP
            ResponseHandler<String> responseHandler = new BasicResponseHandler();

            // eseguo la richiesta
            result = client.execute(get,responseHandler);

         } catch (HttpResponseException e) {
            // gestisce le risposte diverse da HTTP code 200
            Log.w("HTTPBOOKSEARCH","HTTP Response Exception : "+e.toString());
         } catch (Exception e) {
            Log.w("HTTPBOOKSEARCH","Error : "+e.toString());
         } finally {
            if (client != null) client.getConnectionManager().shutdown();
         }

         // parsing XML
         if (result!=null) try {
           
            // aggiorno la progress dialog
            publishProgress("Parsing XML response...");
           
            // creo il document builder
            DocumentBuilderFactory dbf;
            dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            // parsing dell'xml
            Document doc = db.parse(new InputSource(new StringReader(result)));
            // esplorazione xml
            NodeList nl = doc.getElementsByTagName("openSearch:totalResults");
            if (nl!=null && nl.getLength()>0) nbook = Integer.parseInt(nl.item(0).getFirstChild().getNodeValue());
            if (nbook>0) {
               title = doc.getElementsByTagName("dc:title").item(0).getFirstChild().getNodeValue();
               author = doc.getElementsByTagName("dc:creator").item(0).getFirstChild().getNodeValue();
               link = "http://books.google.com/books?id="+doc.getElementsByTagName("dc:identifier").item(0).getFirstChild().getNodeValue();
            } else {
               title = "";
               author = "";
               link = "";
            }
           
         } catch (ParserConfigurationException e) {
            Log.w("HTTPBOOKSEARCH","Parser Configuration Exception : "+e.toString());
         } catch (SAXException e) {
            Log.w("HTTPBOOKSEARCH","SAX Exception : "+e.toString());
         } catch (IOException e) {
            Log.w("HTTPBOOKSEARCH","IO Exception : "+e.toString());
         }
         
         return result;
         
      }

      @Override
      protected void onProgressUpdate(String... values) {
         // aggiorno la progress dialog
         pd.setMessage(values[0]);
      }

      @Override
      protected void onPostExecute(String result) {
         // chiudo la progress dialog
         pd.dismiss();

         // aggiorno i campi
         txtTitle.setText("TITLE\n"+title);
         txtAuthor.setText("AUTHOR\n"+author);
         btnLink.setText(link);

         // aggiorno testo di debug
         txtDebug.append("\nRESULT TITLE="+title);
         txtDebug.append("\nRESULT AUTHOR="+author);
         txtDebug.append("\nRESULT WEBLINK="+link);        

      }
   }

}

Bibliografia:
« Ultima modifica: 31 Agosto 2010, 08:30:45 CEST da JD »
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Vytek

  • Translate Team
  • Utente junior
  • **
  • Post: 125
  • Respect: +6
    • Mostra profilo
  • Dispositivo Android:
    Samsung S5
  • Sistema operativo:
    Windows 8.1
Re:HttpBookSearch, applicazione didattica
« Risposta #1 il: 24 Agosto 2010, 12:31:32 CEST »
0
Bellissima e molto utile !!! Io la segnalerei come tutorial.

Un saluto....

Offline blackgin

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1387
  • Respect: +164
    • Google+
    • blackgins
    • blackginsoft
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
  • Sistema operativo:
    Mac OSX 10.8
Re:HttpBookSearch, applicazione didattica
« Risposta #2 il: 24 Agosto 2010, 12:51:16 CEST »
0
Sai cosa potresti fare? Sempre che ti interessi impararlo potresti implementare la lettura da barcode oltre che l'inserimento manuale del numero..
Postate il LogCat LogCat LogCat LogCat LogCat

Offline JD

  • Amministratore
  • Utente storico
  • *****
  • Post: 1600
  • Respect: +232
    • leinardi
    • Mostra profilo
  • Dispositivo Android:
    LG Nexus 5
  • Sistema operativo:
    L'ultima Ubuntu
Re:HttpBookSearch, applicazione didattica
« Risposta #3 il: 24 Agosto 2010, 14:22:29 CEST »
0
Grazie per aver postato i sorgenti :).

PS
In effetti sembra quasi un tutorial :D

Se allegassi lo zip col progetto eclipse si potrebbe tranquillamente spostare in Gestione dei dati :P
« Ultima modifica: 24 Agosto 2010, 14:24:13 CEST da JD »
È stata trovata una soluzione al tuo problema?
Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato ;).
E se hai aperto tu il thread marcalo come risolto cliccando !

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:HttpBookSearch, applicazione didattica
« Risposta #4 il: 24 Agosto 2010, 17:50:21 CEST »
0
Grazie per aver postato i sorgenti :).

Figurati

Purtroppo in gran parte delle realtà italiane (non questa) c'è la convinzione che tutto il codice altrui è bene sia open-source, ma ciò non vale mai per il proprio, che viene spesso custodito gelosamente. In realtà io ho attinto a fonti open-source sul web (incluso questo forum) e mi sembra giusto ricambiare, perchè non ci perdo niente, anzi ci guadagno.  :-)

PS
In effetti sembra quasi un tutorial :D

Se allegassi lo zip col progetto eclipse si potrebbe tranquillamente spostare in Gestione dei dati :P

Allegato.

Modifica pure il titolo e la prima parte del post per adattarlo al formato dei tutorial. Io poi dovrei spiegare un po' i contenuti, anche se per mia documentazione commento molto pesantemente il codice e dovrebbe quasi bastare.

Sai cosa potresti fare? Sempre che ti interessi impararlo potresti implementare la lettura da barcode oltre che l'inserimento manuale del numero..

Effettivamente era nelle mie iniziali intenzioni. Infatti ho preso lo spunto del web service direttamente dal sorgente di BarcodeScanner, di cui Marcoduff ha fatto un ottimo tutorial. Ma per integrare la lettura del barcode avrei dovuto fare debug direttamente sul telefono. Ho provato a vedere come funzionava sul mio Tattoo l'applicazione BarcodeScanner, ed ho visto che la cam non riesce a fare l'autofocus alla distanza necessaria all'applicazione.

Il mese prossimo compro un altro cell e vedo il da farsi.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline MarcoDuff

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1073
  • Respect: +202
    • Google+
    • marcoduff
    • Mostra profilo
    • MarcoDuff's Blog
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    MarcoDuff
  • Sistema operativo:
    Windows 7
Re:HttpBookSearch, applicazione didattica
« Risposta #5 il: 24 Agosto 2010, 18:12:08 CEST »
0
Ho provato a vedere come funzionava sul mio Tattoo l'applicazione BarcodeScanner, ed ho visto che la cam non riesce a fare l'autofocus alla distanza necessaria all'applicazione.

Tranquillo, anche il mio Desire ogni tanto fa le bizze con la messa a fuoco... serve molta luce e mano ferma!  o_O

Offline dessorry

  • Utente normale
  • ***
  • Post: 230
  • Who lived hoping died craping
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire HD
  • Play Store ID:
    dessorry
  • Sistema operativo:
    Windows, Ubuntu, Kubuntu
Re:HttpBookSearch, applicazione didattica
« Risposta #6 il: 31 Agosto 2010, 00:30:29 CEST »
0
Ciao,

prima di tutto complimenti per l'applicazione
mi è servita per impostare la progressdialog ed il thread di lettura (il codice di parsing della pagina già ce l'avevo)
ora ho due domande:
1)su eclipse la app funziona bene ed in 2 max 3 secondi mi trova i contenuti nella pagina sul cellulare ce ne mette dai 5 ai 7 ma questo dipende dal segnale credo, soprattutto accade che mi appaia il messaggio: Interruzione imprevista dell'applicazione. Riprova. e poi c'è il bottone Termina. Dato che in eclipse non accade mai temo che il baco sia dovuto alla connessione, che ne dici?
2)è "lecito" costruire app che vanno e leggere contenuti nel web e li ripropongono al suo interno?credo che sia necessario ottenere il consenso dal proprietario del sito giusto?

spero di non aver sporcato questo thread col mio intervento in tal caso chiedo agli admin di crearne uno nuovo e di spostare questo commmento..

grazie

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:HttpBookSearch, applicazione didattica
« Risposta #7 il: 31 Agosto 2010, 09:33:49 CEST »
0
1)su eclipse la app funziona bene ed in 2 max 3 secondi mi trova i contenuti nella pagina sul cellulare ce ne mette dai 5 ai 7 ma questo dipende dal segnale credo, soprattutto accade che mi appaia il messaggio: Interruzione imprevista dell'applicazione. Riprova. e poi c'è il bottone Termina. Dato che in eclipse non accade mai temo che il baco sia dovuto alla connessione, che ne dici?

Se riesci a vedere il LogCat dovresti trovare un'eccezione che ti mostra la causa.

Però da come lo descrivi potrebbe essere un problema di TIMEOUT. Sarebbe da provare a impostare un timeout maggiore, credo attraverso i parametri di connessione HttpParams. Stasera vedo se riesco a trovare qualcosa.

2)è "lecito" costruire app che vanno e leggere contenuti nel web e li ripropongono al suo interno?credo che sia necessario ottenere il consenso dal proprietario del sito giusto?

A questo quesito ti so rispondere con certezza. Ho fatto uso del web service ufficiale di Google, che espone delle API pubbliche. L'uso di queste API è regolamento da un Terms of Service che ti linko qua sotto, così puoi tranquillamente controllare se la tua applicazione ci rientra.

Terms of Service - Google Book Search APIs - Google Code

spero di non aver sporcato questo thread col mio intervento in tal caso chiedo agli admin di crearne uno nuovo e di spostare questo commmento..

Nono, anzi, fai bene a riportare esperienze dirette ed eventuali migliorie al codice.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline onire

  • Utente junior
  • **
  • Post: 52
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Dream G1, Samsung Galaxy S
  • Sistema operativo:
    Windows Xp
Re:[facile] HttpBookSearch: AsyncTask, HttpClient, XML parsing, ProgressDialog
« Risposta #8 il: 09 Settembre 2010, 14:38:54 CEST »
0
@bradipao
Complimenti per l'articolo.
Premesso che ho iniziato ad usare java solo per poter creare le miei app per android, perdonatemi per quello che sto per dire  :-P

Ho creato una mia classe (in un suo file) il cui costruttore necessita 2 variabili string, non ci sono altri metodi pubblici, ora volendola modificare come AsyncTask, ho provato a scrivere:
Codice (Java): [Seleziona]
public class miaclasse AsyncTask<String,String,String>  {
        public String FullInfo;
        private String newnum;
        private String newpaese = null;

        public miaclase (String numero, String paese) throws IOException
        {......

ma è evidente che mi da errore  :'( , cosa sbaglio?

« Ultima modifica: 10 Settembre 2010, 19:52:20 CEST da onire »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:[facile] HttpBookSearch: AsyncTask, HttpClient, XML parsing, ProgressDialog
« Risposta #9 il: 10 Settembre 2010, 12:17:33 CEST »
0
onire, potresti spiegarmi più in dettaglio il problema?

Cioè, obiettivo del codice che vuoi scrivere, più codice possibile, elenco degli errori che ti da', etc.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline onire

  • Utente junior
  • **
  • Post: 52
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Dream G1, Samsung Galaxy S
  • Sistema operativo:
    Windows Xp
Re:[facile] HttpBookSearch: AsyncTask, HttpClient, XML parsing, ProgressDialog
« Risposta #10 il: 17 Settembre 2010, 17:54:45 CEST »
0
Salve, finalmente sono riuscito ad uasare AsyncTask, ma ci sono delle cose che non ho capito  :-[
In AsyncTask<String,String,String> i 3 string si riferiscono agli argomenti di doInBackground, onProgressUpdate, onPostExecute?
Inoltre params è definito nella funzione chiamante, values e  result in  onProgressUpdate e onPostExecute?

Quando utilizzo l'istruzione publishProgress("Parsing XML response..."); nel blocco doInBackground, mi restituisce questo errore:

The method publishProgress(Integer...) in the type AsyncTask<Void,Integer,Long> is not applicable for the arguments (String)

Confido in un  O:-) che mi perdoni

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:[facile] HttpBookSearch: AsyncTask, HttpClient, XML parsing, ProgressDialog
« Risposta #11 il: 17 Settembre 2010, 18:00:27 CEST »
0
Salve, finalmente sono riuscito ad uasare AsyncTask, ma ci sono delle cose che non ho capito  :-[
In AsyncTask<String,String,String> i 3 string si riferiscono agli argomenti di doInBackground, onProgressUpdate, onPostExecute?

Si esatto.

Citazione
Inoltre params è definito nella funzione chiamante, values e  result in  onProgressUpdate e onPostExecute?

Quando utilizzo l'istruzione publishProgress("Parsing XML response..."); nel blocco doInBackground, mi restituisce questo errore:

The method publishProgress(Integer...) in the type AsyncTask<Void,Integer,Long> is not applicable for the arguments (String)

Se vedi l'errore ti dice che avendo tu definito AsyncTask<Void,Integer,Long>, il metodo publishProgress(Integer...) si aspetta un Integer, ma tu hai passato una String con publishProgress("Parsing XML response...");
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline bricofera

  • Nuovo arrivato
  • *
  • Post: 1
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus One
  • Sistema operativo:
    Windows
Re:[facile] HttpBookSearch: AsyncTask, HttpClient, XML parsing, ProgressDialog
« Risposta #12 il: 25 Novembre 2010, 21:56:56 CET »
0
ciao a tutti, come noterete sono nuovo qui..

Volevo solo fare i più sinceri complimenti a bradipao per questo tutorial.. ho finalmente imparato ad usare i task, e sono stupendi per quello che sto realizzando!

Un grazie di cuore.
ciao!

Offline palladlardo

  • Nuovo arrivato
  • *
  • Post: 1
  • Respect: 0
    • Mostra profilo
Re:[facile] HttpBookSearch: AsyncTask, HttpClient, XML parsing, ProgressDialog
« Risposta #13 il: 09 Dicembre 2010, 18:06:45 CET »
0
Grazie mille

« Ultima modifica: 09 Dicembre 2010, 18:10:01 CET da palladlardo »

Offline gsources75

  • Utente normale
  • ***
  • Post: 327
  • Respect: +9
    • Google+
    • pepigno75
    • devandroid_it
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy Nexus S - Vodafone Smart -BB Bold- Iphone 4-
  • Play Store ID:
    Giuseppe+Sorce
  • Sistema operativo:
    Ubuntu-Windows Seven- Mac Lion
Re:[facile] HttpBookSearch: AsyncTask, HttpClient, XML parsing, ProgressDialog
« Risposta #14 il: 03 Febbraio 2011, 07:12:17 CET »
0
Se dovessi dividere le classi  nel senso che HttpBookSearch vuole ottenere dei dati chiama una classe Generica che fa una query, interroga un db etc e alla fine comunica ad HttpBookSearch i risultati.

L' esigenza come ho spiegato in un altro post è tenere separati la gestione dei dati dalle altre classi. Se invece di recuperare "libri" recuperiamo prodotti in genere o immagini dovremmo scrivere un  AsyncTask per ogni chiamata e questo secondo me non è efficente. Secondo la mia logica OOP, in un mondo perfetto :) io farei

1) Activity

2) classe  che comunica con il webserice

3) classe che fa il parse dei dati

Gli AsyncTask mi possono aiutare con questa logica ? La classe che comunica con il web dovrebbe essere più generica possibile in modo tale da riutilizzarla, anche per altri progetti e altre Activity.

La classe che fa il parse in qualche modo può essere anche generica perchè se è un WebService la risposta sarà sempre uguale tranne per i tag dopo il tag ....Result.


Mi scuso con i moderatori se magari ho fatto cross posting con questo post

http://www.anddev.it/index.php/topic,1981.msg13618.html#msg13618





La domanda stupida è quella che non si fa