Páginas

23 de novembro de 2011

Como Usar HttpURLConnection para Receber Dados no Android



No Android existem duas formas de enviar e receber dados usando HTTP. Uma é através do Apache HTTP e a outra através de HttpURLConnection.

No post Como Receber Dados de um WebService no Android demonstrei como receber dados de um webservice utilizando o Apache HTTP (DefaultHttpClient).

Recentemente foi publicado no blog do google Android´s HTTP Clients um post informando que a API do Apache HTTP não está mais sendo atualizada, por ser muito grande e difícil de implementar melhorias sem quebrar as compatibilidades. Por esse motivo eles estão trabalhando na API HttpURLConnection.

A API HttpURLConnection é de uso geral, leve, de um tamanho pequeno e atende a maioria das aplicações.

Em dispositivos com a versão 2.2 (Froyo) ou anteriores a API HttpURLConnection tinha alguns bugs. Da versão 2.3 (Gingerbread) para frente esta API é melhor para o Android porque reduz o uso da rede, melhora a velocidade e economiza bateria.

Resumindo até a versão 2.2 (Froyo) é melhor utilizar o Apache HTTP, para as versões 2.3 (Gingerbread) para frente é melhor utilizar a API HttpURLConnection.

Neste post vou utilizar o mesmo webservice e o mesmo projeto do post Como Receber Dados de um webService no Android alterando somente a forma de receber os dados. Ao invés de utilizar a classe DefaultHttpClient vou utilizar a classe HttpURLConnection, portanto substituir a classe WebService.java do post Como Receber Dados de um webService no Android por:
Listagem 1:
public class WebService {
    private static final int TAM_MAX_BUFFER = 10240; // 10Kbytes
    private String urlWebService;
    
    public WebService(String url) {
        this.urlWebService = url;
    }
    
    public String getEstados(){
        String resultado = "";
        HttpURLConnection urlConnection = null;
        
        try {
          URL url = new URL(urlWebService);
          
          urlConnection = (HttpURLConnection) url.openConnection();
          urlConnection.setDoOutput(true);
          urlConnection.setRequestMethod("POST");
          urlConnection.setRequestProperty("Content-Type", 
                  "text/xml; charset=utf-8");
          urlConnection.setRequestProperty("SOAPAction", 
                  "http://tempuri.org/GetEstados");
                    
          String request = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
              "<soap:Envelope " + 
                  "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
                  "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
                  "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
              "<soap:Body>" +
              "<GetEstadosResponse xmlns=\"http://tempuri.org/\">" +
              "<GetEstadosResult>string</GetEstadosResult>" +
              "</GetEstadosResponse>" +
              "</soap:Body>" +
              "</soap:Envelope>";
          
          OutputStream out = urlConnection.getOutputStream();
          out.write(request.getBytes());
          
          // Verifica se a resposta está ok antes de solicitar os dados
          if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
              InputStream in = new BufferedInputStream(
                      urlConnection.getInputStream());    
              
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(in,
                                "UTF-8"), TAM_MAX_BUFFER);
                
                StringBuilder builder = new StringBuilder();
                
                for (String line = null ; (line = reader.readLine())!= null;) {
                    builder.append(line).append("\n");
                }
                
                resultado = builder.toString();
                
                // Retira a string <?xml version="1.0" encoding="utf-8" ?> 
                // <string xmlns="http://tempuri.org/"> e a tag </GetEstadosResult> 
                // para obter o resultado em Json, já que o webservice está
                // retornando uma string
                Integer firstTagString = resultado.indexOf("<GetEstadosResult");
                Integer posXml = resultado.indexOf(">", firstTagString);
                Integer posTagString = resultado.indexOf("</GetEstadosResult>");
                resultado = resultado.substring(posXml + 1, posTagString + 1);
          }
          else{
              Log.e("WebService", 
                      "ResponseCode: " + urlConnection.getResponseMessage());
          }

        }
        catch(IOException e){
            Log.e("WebService", e.toString());
        }
        finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
       }
        
        return resultado;
    }
}

No método getEstados() é utilizada a classe HttpURLConnection para obter os dados do webservice. Para utilizar esta classe é necessário configurar os métodos setDoOutput(Boolean) que informa se este HttpURLConnection permite output, no nosso caso deve ser setado como true, no método setRequestMethod(String), e setRequestProperty(String) deve ser passado como parâmetro as informações do webservice. Depois é necessário montar a requisição do webservice e através da classe OutputStream escrever os dados no HttpURLConnection.

Antes de ler os dados verificar através do método getResponseCode() se a resposta do HttpURLConnection está OK.