Consumindo Web Service em aplicações Android

Publicado por Ricardo Ushisima
30/3/2011
Categoria:
Tags: , ,

O SDK do Android não oferece uma solução fácil e embutida para consumir web services. Neste artigo, vou demonstrar como consumir web service usando a biblioteca KSOAP2.

Vou usar o Web Service que criei no meu artigo Expondo POCO como Web Services usando Spring Framework para criar uma aplicação de conversão de moedas feitas para dispositivos Android.

Só para lembrar, segue a interface do meu web service, que foi desenvolvido em .NET:

using System;

namespace SpringTutorial
{
    public interface ICurrencyService
    {
        decimal Convert(string from, string to, decimal value);
    }
}

Primeiro, vou implementar o serviço de conversão que irá consumir o web service de conversão de moedas desenvolvido anteriormente. O KSOAP2 é uma biblioteca que permite o consumo de web services sem a necessidade de geração de código ou uso de proxies dinâmicos. Lembre-se que a aplicação vai rodar em um dispositivo móvel e proxy dinâmico é um recurso caro computacionalmente.

package br.com.zbra.android.sample;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

public class ConvertService {
	private static final String SOAP_ACTION = "http://zbra.com.br/springtutorial/Convert";
	private static final String METHOD_NAME = "Convert";
	private static final String NAMESPACE = "http://zbra.com.br/springtutorial";
	private static final String URL = "http://192.168.10.103/SpringTutorialService/CurrencyServiceWS.asmx";

	public String Convert(String fromCurrency, String toCurrency, String amount) {
		SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
		request.addProperty("from", fromCurrency);
		request.addProperty("to", toCurrency);
		request.addProperty("value", amount);

		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.dotNet = true;
		envelope.setOutputSoapObject(request);
		try {
			HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
			androidHttpTransport.call(SOAP_ACTION, envelope);
			SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
			return result.toString();
		} catch (Exception e) {
			return e.getMessage();
		}
	}
}

O request é feito usando um SoapObject e cada parâmetro da chamada é uma propriedade do SoapObject. A chamada ao servidor de aplicações é feita usando um HttpTransportSE passando um envelope SOAP com a request gerada. Após a execução do serviço, o envelope irá conter o retorno do serviço. No nosso caso, o resultado é um decimal que é serializado como um SoapPrimitive seguindo o protocolo. Se o retorno fosse um objeto complexo, o retorno seria um SoapObject.

Tendo o serviço implementado, é só chamá-lo no Activity da aplicação Android:

package br.com.zbra.android.sample;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Spinner;

public class Main extends Activity {

	private Spinner fromCurrencySpinner;
	private Spinner toCurrencySpinner;
	private EditText amountEdit;
	private EditText resultEdit;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		bindControls();
	}

	private void bindControls() {
		fromCurrencySpinner = (Spinner) findViewById(R.id.from_currency_edit);
		toCurrencySpinner = (Spinner) findViewById(R.id.to_currency_edit);
		amountEdit = (EditText) findViewById(R.id.amount_edit);
		resultEdit = (EditText) findViewById(R.id.result_edit);
	}

	public void onConvertBtnClick(View v) {
		String fromCurrency = (String) fromCurrencySpinner.getSelectedItem();
		String toCurrency = (String) toCurrencySpinner.getSelectedItem();
		String amount = amountEdit.getText().toString();
		ConvertService service = new ConvertService();
		String result = service.Convert(fromCurrency, toCurrency, amount);
		resultEdit.setText(result);
	}
}

No arquivo AndroidManifest.xml, é necessário dar permissão para a aplicação poder acessar a internet.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	package="br.com.zbra.android.sample" android:versionCode="1"
	android:versionName="1.0">
	<uses-sdk android:minSdkVersion="8" />
	<uses-permission android:name="android.permission.INTERNET"></uses-permission>
	<application android:icon="@drawable/icon" android:label="@string/app_name">
		<activity android:name=".Main" android:label="@string/app_name">
			<intent-filter>
				<action android:name="android.intent.action.MAIN" />
				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
		</activity>
	</application>
</manifest>

Por restrições de espaço e por não ser o escopo do artigo, vou apenas publicar um screenshot da minha aplicação de exemplo.

Vale observar que o consumo de Web Services em dispositivos móveis não é recomendado pela equipe de desenvolvimento do Android devido ao overhead que o processamento do SOAP exige. Se você tem controle sobre o servidor, o ideal é usar arquiteturas baseadas em REST tal como ODATA.

Referencias:

3 Comentários

  • Reply

    Por Luiz em 20 de September de 2011 às 20:58

    Olá Ricardo, interessante a biblioteca KSOAP2. Vou utiliza-la em alguns exemplos e curiosidades que descobrir compartilho aqui no ZBRA.

  • Reply

    Por Renato em 4 de November de 2011 às 15:56

    Estou desenvolvendo uma aplicação e nela eu tenho que buscar um objeto com vários parametro, ex: nome, idade, cpf, endreço. Eu quero apenas mostrar o nome da pessoa, como eu devo fazer? O xml de retorno tem que ter um padrão (header, body) e etc?





Desenvolvido por hacklab/ com WordPress