CODIGO PROYECTO: AppPixelproServicioWeb Proyecto Android - Servicio Web I. Alcances del Proyecto a. Ide Eclipse Indigo 3.7 b. Api 10-17, Versión Android 2.3.3 A 4.2.2 c. Jdk 1.6 II. Conceptos Relacionados al Proyecto Android - Servicio Web. Consumiento Web Services SOAP en Android con ksoap2 SOAP (Simple Object Access Protocol, Protocolo de Acceso simple a objetos). Especificación XML para la formación de los mensajes intercambiados entre los sistemas distribuidos y la red. Este protocolo deriva de un protocolo creado por David Winer, XML-RPC en 1998. Los mensajes debían tener un formato determinado empleando XML para encapsular los parámetros de la petición. El mensaje está compuesto de tres partes: un sobre, encabezado y el cuerpo. El sobre envuelve al mensaje y contiene el encabezado y el cuerpo; el encabezado es un elemento opcional que provee información para el enrutamiento del mensaje; el cuerpo contiene datos etiquetados como XML. 1
Decimos que SOAP es uno de lo protocolos para comunicación de datos más usados auspiciado por la W3C, existiendo multitud de servicios web implementados bajo esta tecnología. Partiendo de esta situación es importante tener unos conocimientos de partida que nos permita enfrentarnos al uso de los mismos en los proyectos que emprendamos. A continuación lo guiaremos en el uso de ksoap2-android, es una library adaptado para su uso en Android. WSDL (Web Service Definition Language, Lenguaje de descripción de servicios web). Especificación XML para la formación del documento de descripción de un servicio web. Identifica los métodos, funciones y parámetros necesarios para invocar un determinado servicio. Así, un usuario puede crear una aplicación cliente que comunica con el servicio web. Una vez creado nuestro proyecto Android deberemos bajarnos la librería en cuestión y incluirla en nuestro build path: http://code.google.com/p/ksoap2-android/source/browse/#svn/m2- repo/com/google/code/ksoap2-android/ksoap2-android-assembly/ Para utilizar un servicio web debemos declarar las siguientes variables: // Metodo que queremos ejecutar en el servicio web private static final String Metodo = "GetCitiesByCountry"; // Namespace definido en el servicio web private static final String namespace = "http://www.webservicex.net"; // namespace + metodo private static final String accionsoap = "http://www.webservicex.net/getcitiesbycountry"; // Fichero de definicion del servcio web private static final String url = "http://www.webservicex.net/globalweather.asmx"; Una vez tenemos claros estos parámetros necesarios para las peticiones pasamos al siguiente paso. El protocolo SOAP se basa en cinco pasos básicamente, definir la petición (request), configurar un sobre (envelope) (define que hay en el mensaje y como procesarlo), definir el canal de transporte, hacer la llamada y recoger los datos. A continuación os mostramos el fragmento de código en el que realizaríamos estos pasos y que incluiríamos en aquel sitio donde deseáramos realizar la petición: 2
try { // Modelo el request SoapObject request = new SoapObject(namespace, Metodo); request.addproperty("param", "valor"); // Paso parametros al WS // Modelo el Sobre SoapSerializationEnvelope sobre = new SoapSerializationEnvelope(SoapEnvelope.VER11); sobre.dotnet = true; sobre.setoutputsoapobject(request); // Modelo el transporte HttpTransportSE transporte = new HttpTransportSE(url); // Llamada transporte.call(accionsoap, sobre); // Resultado SoapPrimitive resultado = (SoapPrimitive) sobre.getresponse(); Log.i("Resultado", resultado.tostring()); catch (Exception e) { Log.e("ERROR", e.getmessage()); NOTA: Para el consumo de servicios web es necesaria la conexión a Internet y por tanto deberemos solicitar dicho permiso en el manifiesto. <uses-permission android:name="android.permission.internet"/> III. Activitys (Archivos.Java), Creados en el Siguiente Orden : 1. CargaDatosWS.java package com.pixelpro; import org.ksoap2.soapenvelope; import org.ksoap2.serialization.soapobject; import org.ksoap2.serialization.soapserializationenvelope; import org.ksoap2.transport.httptransportse; public class CargaDatosWS { public String getclima(string ciudad,string pais){ String res=null; //Se crea un objeto de tipo SoapObjecto, este objeto permite hacer el llamado al WS SoapObject rpc; rpc = new SoapObject("http://www.webserviceX.NET", "GetWeather"); //De acuerdo a la documentación del ws, hay 2 parámetros que debemos pasar nombre de la ciudad y del país //Para obtener información del WS, se puede consultar http://www.webservicex.net/globalweather.asmx?wsdl //Parametros que se envia al WS rpc.addproperty("cityname", ciudad); rpc.addproperty("countryname", pais); //Definimos el Protocolo SOAP para traer la información del WS 3
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); //Seteamo el WS al protocolo SOAP envelope.bodyout = rpc; //Definimos el Lenguaje utilizado en el WS, para este proyecto.net envelope.dotnet = true; //Serializamos la data envelope.encodingstyle = SoapSerializationEnvelope.XSD; //Para acceder al WS se crea un objeto de tipo HttpTransportSE, esto es propio de la librería KSoap HttpTransportSE androidhttptransport= null; try { //Página que publica WS String conexion = "http://www.webservicex.net/globalweather.asmx"; androidhttptransport = new HttpTransportSE(conexion); androidhttptransport.debug = true; //Llamado al servicio web, "GetWeather" es el método que queremos invocar. androidhttptransport.call("http://www.webservicex.net/getweather", envelope); //Respuesta del Servicio web res = envelope.getresponse().tostring(); catch (Exception e){ System.out.println(e.getMessage()); res=e.getmessage(); return res; 2. ClimaActivity.java package com.pixelpro; import android.app.activity; import android.app.progressdialog; import android.content.context; import android.os.asynctask; import android.os.bundle; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.textview; import android.widget.toast; public class ClimaActivity extends Activity { private ProgressDialog pd; private TextView ciudad; private TextView pais; private Button boton1; private String res; private Context context; public void oncreate(bundle savedinstancestate) { 4
super.oncreate(savedinstancestate); context=this; setcontentview(r.layout.climaactivity); ciudad=(textview)findviewbyid(r.id.nombreciudad); pais=(textview)findviewbyid(r.id.nombrepais); boton1=(button)findviewbyid(r.id.button1); //Se establece listener para nuestro botón boton1.setonclicklistener(listener); private OnClickListener listener = new OnClickListener() { public void onclick(view arg0) { // Usamos un AsyncTask(Tarea), para poder mostrar una ventana de por favor espere, mientras se consulta el servicio web new DownloadTask2().execute(""); pd = ProgressDialog.show(context, "Por favor espere...","consultando Clima", true, false); ; //Tarea en Background private class DownloadTask2 extends AsyncTask<String, Void, Object> { protected Integer doinbackground(string... args) { CargaDatosWS ws=new CargaDatosWS(); //Se invoca nuestro método que retorna el clima res=ws.getclima(ciudad.gettext().tostring(), pais.gettext().tostring()); return 1; protected void onpostexecute(object result) { //Se elimina la pantalla de por favor espere. pd.dismiss(); //Se muestra mensaje con la respuesta del servicio web en formato xml Toast.makeText(context,"Clima: "+res,toast.length_long).show(); super.onpostexecute(result); 5
IV. Archivos Layout (.xml) : 1. climaactivity.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:background="#666aaa" android:orientation="vertical" > <TextView android:text="datos " /> <TextView android:id="@+id/textview1" android:text="pais" android:textappearance="?android:attr/textappearancemedium" /> <EditText android:id="@+id/nombrepais" android:ems="10" android:hint="digite Nombre del pais" > <requestfocus /> </EditText> <TextView android:id="@+id/textview2" android:text="ciudad" android:textappearance="?android:attr/textappearancemedium" /> 6
<EditText android:id="@+id/nombreciudad" android:ems="10" android:hint="digite nombre Ciudad" /> <Button android:id="@+id/button1" android:layout_margintop="20dp" android:text="consultar" /> </LinearLayout> V. AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.pixelpro" android:versioncode="1" android:versionname="1.0" > <uses-sdk android:minsdkversion="10" android:targetsdkversion="17" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name="com.pixelpro.climaactivity" 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> <uses-permission android:name="android.permission.internet" /> </manifest> 7