Páginas

Pesquisar neste blog

28 de fevereiro de 2019

Como Receber Dados de um WebService no Android

Neste post vou demonstrar como tratar informações vindas de um webservice desenvolvido em .NET em uma aplicação Android. 

O webservice utilizado nesta aplicação é o mesmo publicado no post Retornando Dados em Json com WebService .NET. Este WebService retorna a relação de estados do Brasil juntamente com as informações de área, capital e abreviação em formato Json.

A aplicação Android vai receber as informações do webservice, tratar os dados e exibir  a relação de estados em um ListView.

A aplicação possui duas classes Principal.java e WebService.java. Na classe WebService.java foi criado o método getEstados() que se conecta ao WebService e retorna os dados em uma String que contêm as informações formatas em Json. (Listagem 1).

Listagem 1:
public class WebService {
    private static final int TIMEOUT_CONEXAO = 20000; // 20 segundos
    private static final int TIMEOUT_SOCKET = 30000; // 30 segundos
    private static final int TAM_MAX_BUFFER = 10240; // 10Kbytes
    private String url;
    
    public WebService(String url) {
        this.url = url;
    }
    
    public String getEstados(){
        String parserbuilder = "";
        
        try{
            HttpParams httpParameters = new BasicHttpParams();
            
            // Configura o timeout da conexão em milisegundos até que a conexão
            // seja estabelecida
            HttpConnectionParams.setConnectionTimeout(httpParameters, 
                    TIMEOUT_CONEXAO);
            
            // Configura o timeout do socket em milisegundos do tempo 
            // que será utilizado para aguardar os dados
            HttpConnectionParams.setSoTimeout(httpParameters, 
                    TIMEOUT_SOCKET);   
            
            HttpClient httpclient = new DefaultHttpClient(httpParameters);
            HttpPost httppost = new HttpPost(url + "/GetEstados");
    
            HttpResponse response = httpclient.execute(httppost);
            
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(response.getEntity().getContent(),
                            "UTF-8"), TAM_MAX_BUFFER);
            
            StringBuilder builder = new StringBuilder();
            
            for (String line = null ; (line = reader.readLine())!= null;) {
                builder.append(line).append("\n");
            }
            
            parserbuilder = builder.toString();
            
            // Retira a string <?xml version="1.0" encoding="utf-8" ?> 
            // <string xmlns="http://tempuri.org/"> e a tag </string> 
            // para obter o resultado em Json, já que o webservice está
            // retornando uma string
            Integer firstTagString = parserbuilder.indexOf("<string");
            Integer posXml = parserbuilder.indexOf(">", firstTagString);
            Integer posTagString = parserbuilder.indexOf("</string>");
            parserbuilder = parserbuilder.substring(posXml + 1, posTagString + 1);
        
        }catch(ClientProtocolException e){
            Log.e("WebService", e.toString());
        }
        catch(IOException e){
            Log.e("WebService", e.toString());
        }
        
        return parserbuilder;    
    }
}
No método getEstados() foi utilizada a classe BasicHttpParams() para configurar os timeouts de conexão, e as classes DefaultHttpClient(HttpParams) e HttpPost(String) para fazer uma requisição tipo Post no WebService.

A informação retornada pelo WebService .NET é um Xml que retorna uma String com dados no formato Json. Para facilitar a obtenção das informações no formato Json, optei em tratar a String retornada pelo WebService de modo a ter somente a informação no formato Json.

Na classe Principal.java no método onCreate(Bundle) foi chamada a classe WebService() e feito o tratamento para exibir os estados no ListView. (Listagem 2)

Listagem 2:
public class Principal extends ListActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        List<String> estados = new ArrayList<String>();
        
        // o endereço http://localhost no emulador deve
        // se chamado como http://10.0.2.2, porque o
        // endereço http://localhost ou http://127.0.0.1
        // é utilizado pelo próprio emulador
        WebService webService = 
            new WebService("http://10.0.2.2:4362/websitejson/service.asmx");
        
        // Obtêm a resposta do webservice
        String resultado = webService.getEstados();
        
        try {
            // Utiliza a classe JSONArray para obter as
            // informações e separar o campo que será
            // utilizado no listview
            JSONArray json = new JSONArray(resultado);
            
            for (int i = 0; i < json.length(); i++) {
                JSONObject jsonObj = json.getJSONObject(i);
                
                // Insere o estado na lista de estados
                estados.add(jsonObj.getString("Nome"));
            }
            
        } catch (JSONException e) {
            Log.e("WebService", e.toString());
        }
        finally{
            setListAdapter(new ArrayAdapter<String>(this, 
                    android.R.layout.simple_list_item_1, estados));
        }
        
    }
}
O webservice está rodando no localhost (127.0.0.1) porta 4362, mas para chamar o webservice no emulador do android não pode ser utilizado o IP 127.0.0.1 porque este IP é utilizado no emulador, por isso na URL utilizar o IP 10.0.2.2.

Para obter somente os estados utilizei as classe JSONArray e JSONObject para extrair a informação desejada. 

Antes de rodar a aplicação não esquecer de dar permissão de acesso à internet no arquivo AndroidManifest.xml.
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
A aplicação rodando vai exibir a seguinte tela:

tela1

A API utilizada HttpDefaultClient é melhor para dispositivos que utilizam a versão 2.2 (Froyo) ou anterior do Android. Para as versões 2.3 (Gingerbread) ou superior é melhor utilizar a API HttpURLConnection. O post Usando HttpURLConnection para Receber Dados no Android demonstra como utilizar esta API.