Inicio Android Acceso a Servicios Web SOAP en Android (2/2)

Acceso a Servicios Web SOAP en Android (2/2)

por sgoliver

En el artículo anterior del curso vimos cómo construir un servicio web SOAP haciendo uso de ASP.NET y una base de datos externa SQL Server. En este segundo artículo veremos cómo podemos acceder a este servicio web desde una aplicación Android y probaremos todo el sistema en local para verificar su correcto funcionamiento.

En primer lugar hay que empezar diciendo que Android no incluye «de serie» ningún tipo de soporte para el acceso a servicios web de tipo SOAP. Es por esto por lo que vamos a utilizar una librería externa para hacernos más fácil esta tarea. Entre la oferta actual, la opción más popular y más utilizada es la librería ksoap2-android. Esta librería es un fork, especialmente adaptado para Android, de la antigua librería kSOAP2. Este framework nos permitirá de forma relativamente fácil y cómoda utilizar servicios web que utilicen el estándar SOAP. La última versión de esta librería en el momento de escribir este artículo es la 2.6.0, que puede descargarse desde este enlace.

Agregar esta librería a nuestro proyecto Android es muy sencillo. Si tenemos una versión reciente del plugin de Android para Eclipse, una vez tenemos creado el proyecto en Android bastará con copiar el archivo .jar en la carpeta libs de nuestro proyecto. Si tu versión del plugin es más antigua es posible que tengas que además añadir la librería al path del proyecto. Para ello accederemos al menú “Project / Properties” y en la ventana de propiedades accederemos a la sección “Java Build Path“. En esta sección accederemos a la solapa “Libraries” y pulsaremos el botón “Add External JARs…“. Aquí seleccionamos el fichero jar de la librería ksoap2-android (en este caso “ksoap2-android-assembly-3.6.0-jar-with-dependencies.jar”) y listo, ya tenemos nuestro proyecto preparado para hacer uso de la funcionalidad aportada por la librería.

Como aplicación de ejemplo, vamos a crear una aplicación sencilla que permita añadir un nuevo usuario a la base de datos. Para ello añadiremos a la vista principal dos cuadros de texto para introducir el nombre y teléfono del nuevo cliente (en mi caso se llamarán txtNombre y txtTelefono respectivamente) y un botón (en mi caso btnEnviar) que realice la llamada al método NuevoCliente del servicio web pasándole como parámetros los datos introducidos en los cuadros de texto anteriores.

No voy a mostrar todo el código necesario para crear esta vista y obtener las referencias a cada control porque no tiene ninguna particularidad sobre lo ya visto en multitud de ocasiones en artículos anteriores del curso (en cualquier caso al final del artículo podéis descargar todo el código fuente para su consulta). Lo que nos interesa en este caso es la implementación del evento onClick del botón btnEnviar, que será el encargado de comunicarse con el servicio web y procesar el resultado.

Lo primero que vamos a hacer en este evento es definir, por comodidad, cuatro constantes que nos servirán en varias ocasiones durante el código:

  • NAMESPACE. Espacio de nombres utilizado en nuestro servicio web.
  • URL. Dirección URL para realizar la conexión con el servicio web.
  • METHOD_NAME. Nombre del método web concreto que vamos a ejecutar.
  • SOAP_ACTION. Equivalente al anterior, pero en la notación definida por SOAP.

Aunque los valores se podrían más o menos intuir, para conocer exactamente los valores que debemos asignar a estas constantes vamos a ejecutar una vez más el proyecto de Visual Studio que construimos en el artículo anterior y vamos a acceder a la página de prueba del método NuevoCliente. Veremos algo parecido a lo siguiente:

constantes-soap

En la imagen anterior se muestran resaltados en rojo los valores de las cuatro constantes a definir, que en nuestro caso concreto quedarían de la siguiente forma:

String NAMESPACE = "http://sgoliver.net/";
String URL="http://10.0.2.2:1473/ServicioClientes.asmx";
String METHOD_NAME = "NuevoClienteSimple";
String SOAP_ACTION = "http://sgoliver.net/NuevoClienteSimple";

Como podéis comprobar, y esto es algo importante, en la URL he sustituido el nombre de máquina localhost por su dirección IP equivalente, que en el caso de aplicaciones Android ejecutadas en el emulador se corresponde con la dirección 10.0.2.2, en vez de la clásica 127.0.0.1. Además debes verificar que el puerto coincide con el que estás utilizando en tu máquina. En mi caso el servicio se ejecuta sobre el puerto 1473, pero es posible que en tu caso el número sea distinto.

Los siguientes pasos del proceso serán crear la petición SOAP al servicio web, enviarla al servidor y recibir la respuesta. Aunque ya dijimos que todo este proceso sería casi transparente para el programador, por ser ésta la primera vez que hablamos del tema me voy a detener un poco más para intentar que entendamos lo que estamos haciendo y no solo nos limitemos a copiar/pegar trozos de código que no sabemos lo que hacen.

Volvamos a la página de prueba del método web NuevoCliente. Justo debajo de la sección donde se solicitan los parámetros a pasar al método se incluye también un XML de muestra de cómo tendría que ser nuestra petición al servidor si tuviéramos que construirla a mano. Echémosle un vistazo:

estructura-peticion-soap

Una vez más he marcado varias zonas sobre la imagen, correspondientes a las tres partes principales de una petición de tipo SOAP. Empezando por la «parte interna» del XML, en primer lugar encontramos los datos de la petición en sí (Request) que contiene el nombre del método al que queremos llamar, y los nombres y valores de los parámetros en entrada. Rodeando a esta información se añaden otra serie de etiquetas y datos a modo de contenedor estándar que suele recibir el nombre de Envelope. La información indicada en este contenedor no es específica de nuestra llamada al servicio, pero sí contiene información sobre formatos y esquemas de validación del estándar SOAP. Por último, durante el envío de esta petición SOAP al servidor mediante el protocolo HTTP se añaden determinados encabezados como los que veis en la imagen. Todo esto junto hará que el servidor sea capaz de interpretar correctamente nuestra petición SOAP, se llame al método web correcto, y se devuelva el resultado en un formato similar al anterior que ya veremos más adelante. Aclarada un poco la estructura y funcionamiento general de una petición SOAP veamos lo sencillo que resulta realizarla desde nuestra aplicación Android.

En primer lugar crearemos la petición (request) a nuestro método NuevoCliente. Para ello crearemos un nuevo objeto SoapObject pasándole el namespace y el nombre del método web. A esta petición tendremos que asociar los parámetros de entrada mediante el método addProperty() al que pasaremos los nombres y valores de los parámetros (que en nuestro caso se obtendrán de los cuadros de texto de la vista principal).

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

request.addProperty("nombre", txtNombre.getText().toString());
request.addProperty("telefono", txtTelefono.getText().toString());

El segundo paso será crear el contenedor SOAP (envelope) y asociarle nuestra petición. Para ello crearemos un nuevo objeto SoapSerializationEnvelope indicando la versión de SOAP que vamos a usar (versión 1.1 en nuestro caso, como puede verse en la imagen anterior). Indicaremos además que se trata de un servicio web .NET activando su propiedad dotNet. Por último, asociaremos la petición antes creada a nuestro contenedor llamando al método setOutputSoapObject().

SoapSerializationEnvelope envelope =
	new SoapSerializationEnvelope(SoapEnvelope.VER11);

envelope.dotNet = true;

envelope.setOutputSoapObject(request);

Como tercer paso crearemos el objeto que se encargará de realizar la comunicación HTTP con el servidor, de tipo HttpTransportSE, al que pasaremos la URL de conexión a nuestro servicio web. Por último, completaremos el proceso realizando la llamada al servicio web mediante el método call().

HttpTransportSE transporte = new HttpTransportSE(URL);

try
{
	transporte.call(SOAP_ACTION, envelope);

	//Se procesa el resultado devuelto
	//...
}
catch (Exception e)
{
	txtResultado.setText("Error!");
}

Tras la llamada al servicio ya estamos en disposición de obtener el resultado devuelto por el método web llamado. Esto lo conseguimos mediante el método getResponse(). Dependiendo del tipo de resultado que esperemos recibir deberemos convertir esta respuesta a un tipo u otro. En este caso, como el resultado que esperamos es un valor simple (un número entero) convertiremos la respuesta a un objeto SoapPrimitive, que directamente podremos convertir a una cadena de caracteres llamado a toString(). Más adelante veremos cómo tratar valores de retorno más complejos.

SoapPrimitive resultado_xml =(SoapPrimitive)envelope.getResponse();
String res = resultado_xml.toString();

if(res.equals("1"))
	txtResultado.setText("Insertado OK");

Y listo, con esto ya tenemos preparada la llamada a nuestro servicio web y el tratamiento de la respuesta recibida.

Un detalle más antes de poder probar todo el sistema. Debemos acordarnos de conceder permiso de acceso a internet a nuestra aplicación, añadiendo la linea correspondiente al Android Manifest:

<uses-permission android:name="android.permission.INTERNET"/>

Pues bien, para probar lo que llevamos hasta ahora podemos ejecutar ambos proyectos simultáneamente, en primer lugar el de Visual Studio para iniciar la ejecución del servidor local que alberga nuestro servicio web (hay que dejar abierto el explorador una vez que se abra), y posteriormente el de Eclipse para iniciar nuestra aplicación Android en el Emulador. Una vez están los dos proyectos en ejecución, podemos rellenar los datos de nuestro cliente en la aplicación Android y pulsar el botón «Enviar» para realizar la llamada al servicio web e insertar el cliente en la base de datos (que por supuesto también deberá estar iniciada). Si todo va bien y no se produce ningún error, deberíamos poder consultar la tabla de Clientes a través del SQL Server Management Studio para verificar que el cliente se ha insertado correctamente.

captura-insert

En la imagen vemos cómo hemos insertado un nuevo cliente llamada ‘cliente7’ con número de teléfono ‘7777’. Si consultamos ahora nuestra base de datos Sql Server podremos comprobar si el registro efectivamente se ha insertado correctamente.

sqlserver-datos

Algo importante que quiero remarcar llegados a este punto. El código anterior debe funcionar correctamente sobre un dispositivo o emulador con versión de Android anterior a la 3.0. Sin embargo, si intentamos ejecutar la aplicación sobre una versión posterior obtendremos una excepción de tipo NetworkOnMainThread. Esto es debido a que en versiones recientes de Android no se permite realizar operaciones de larga duración directamente en el hilo principal de la aplicación. Para solucionar esto y que nuestra aplicación funcione bajo cualquier versión de Android será necesario trasladar el código que hemos escrito para llamar al servicio web a una AsyncTask que realice las operaciones en segundo plano utilizando un hilo secundario. El curso contiene un capitulo dedicado a describir con más detalle las tareas asíncronas o AsyncTask, por lo que en este caso me limitaré a poner cómo quedaría nuestro código dentro de la AsyncTask.

//Tarea Asíncrona para llamar al WS de consulta en segundo plano
private class TareaWSConsulta extends AsyncTask<String,Integer,Boolean> {

    private Cliente[] listaClientes;

    protected Boolean doInBackground(String... params) {

    	boolean resul = true;

    	final String NAMESPACE = "http://sgoliver.net/";
	final String URL="http://10.0.2.2:1473/ServicioClientes.asmx";
	final String METHOD_NAME = "ListadoClientes";
	final String SOAP_ACTION = "http://sgoliver.net/ListadoClientes";

	SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

	SoapSerializationEnvelope envelope =
           new SoapSerializationEnvelope(SoapEnvelope.VER11);
	envelope.dotNet = true;

	envelope.setOutputSoapObject(request);

	HttpTransportSE transporte = new HttpTransportSE(URL);

	try
	{
		transporte.call(SOAP_ACTION, envelope);

		SoapObject resSoap =(SoapObject)envelope.getResponse();

		listaClientes = new Cliente[resSoap.getPropertyCount()];

		for (int i = 0; i < listaClientes.length; i++)
		{
	           SoapObject ic = (SoapObject)resSoap.getProperty(i);

	           Cliente cli = new Cliente();
	           cli.id = Integer.parseInt(ic.getProperty(0).toString());
	           cli.nombre = ic.getProperty(1).toString();
	           cli.telefono =
                        Integer.parseInt(ic.getProperty(2).toString());

	           listaClientes[i] = cli;
   	       }
	}
	catch (Exception e)
	{
		resul = false;
	}

       return resul;
   }

   protected void onPostExecute(Boolean result) {

    	if (result)
    	{
	    	//Rellenamos la lista con los nombres de los clientes
		final String[] datos = new String[listaClientes.length];

		for(int i=0; i<listaClientes.length; i++)
			 datos[i] = listaClientes[i].nombre;

		ArrayAdapter<String> adaptador =
		    new ArrayAdapter<String>(MainActivity.this,
		        android.R.layout.simple_list_item_1, datos);

		lstClientes.setAdapter(adaptador);
    	}
    	else
    	{
    		txtResultado.setText("Error!");
    	}
    }
}

Como podemos ver, prácticamente todo el código se ha trasladado al método doInBackground() de la tarea, salvo la parte en la que debemos actualizar la interfaz de usuario tras la llamada que debe ir al método onPostExecute().

Por su parte, una vez creada la tarea asíncrona, en el evento click del botón nos limitaremos a instanciar la tarea y ejecutarla llamando a su método execute().

btnConsultar.setOnClickListener(new OnClickListener() {

	@Override
	public void onClick(View v) {
		TareaWSConsulta tarea = new TareaWSConsulta();
	        tarea.execute();
	}
});

Con esto, ya sabemos realizar una llamada a un servicio web SOAP que devuelve un valor de retorno sencillo, en este caso un simple número entero. Lo siguiente que vamos a ver será como implementar la llamada a un método del servicio web que nos devuelva un valor algo más complejo. Y esto lo vamos a ver con la llamada al método web ListadoClientes() que recordemos devolvía un array de objetos de tipo Cliente.

En este caso, la llamada al método web se realizará de forma totalmente análoga a la ya comentada. Donde llegarán las diferencias será a la hora de tratar el resultado devuelto por el servicio, comenzando por el resultado del método getResponse() de ksoap. En esta ocasión, dado que el resultado esperado no es ya un valor simple sino un objeto más complejo, convertiremos el resultado de getResponse() al tipo SoapObject, en vez de SoapPrimitive como hicimos anteriormente. Nuestro objetivo será generar un array de objetos Cliente (lo llamaremos listaClientes) a partir del resultado devuelto por la llamada al servicio.

Como sabemos que el resultado devuelto por el servicio es también un array, lo primero que haremos será crear un array local con la misma longitud que el devuelto, lo que conseguiremos mediante el método getPropertyCount(). Tras esto, iteraremos por los distintos elementos del array devuelto mediante el método getProperty(ind), donde ind será el índice de cada ocurrencia. Cada uno de estos elementos será a su vez otro objeto de tipo SoapObject, que representará a un Cliente. Adicionalmente, para cada elemento accederemos a sus propiedades (Id, Nombre, y Telefono) una vez más mediante llamadas a getProperty(), con el índice de cada atributo, que seguirá el mismo orden en que se definieron. Así, getProperty(0) recuperará el Id del cliente, getProperty(1) el nombre, y getProperty(2) el teléfono. De esta forma podremos crear nuestros objetos Cliente locales a partir de estos datos. Al final de cada iteración añadimos el nuevo cliente recuperado a nuestro array. Veamos como quedaría todo esto en el código, donde seguro que se entiende mejor:

SoapObject resSoap =(SoapObject)envelope.getResponse();

Cliente[] listaClientes = new Cliente[resSoap.getPropertyCount()];

for (int i = 0; i < listaClientes.length; i++)
{
       SoapObject ic = (SoapObject)resSoap.getProperty(i);

       Cliente cli = new Cliente();
       cli.id = Integer.parseInt(ic.getProperty(0).toString());
       cli.nombre = ic.getProperty(1).toString();
       cli.telefono = Integer.parseInt(ic.getProperty(2).toString());

       listaClientes[i] = cli;
}

En nuestra aplicación de ejemplo añadimos un nuevo botón y un control tipo lista (lo llamo lstClientes), de forma que al pulsar dicho botón rellenemos la lista con los nombres de todos los clientes recuperados. La forma de rellenar una lista con un array de elementos ya la vimos en los artículos dedicados a los controles de selección, por lo que no nos pararemos a comentarlo. El código sería el siguiente (Nota: sé que todo esto se podría realizar de forma más eficiente sin necesidad de crear distintos arrays para los clientes y para el adaptador de la lista, pero lo dejo así para no complicar el tutorial con temas ya discutidos en otros artículos):

//Rellenamos la lista con los nombres de los clientes
final String[] datos = new String[listaClientes.length];

for(int i=0; i<listaClientes.length; i++)
    datos[i] = listaClientes[i].nombre;

ArrayAdapter<String> adaptador =
    new ArrayAdapter<String>(ServicioWebSoap.this,
        android.R.layout.simple_list_item_1, datos);

lstClientes.setAdapter(adaptador);

Por último, vamos a ver cómo llamar a un método web que recibe como parámetro algún objeto complejo. Para ilustrarlo haremos una llamada al segundo método de inserción de clientes que implementamos en el servicio, NuevoClienteObjeto(). Recordemos que este método recibía como parámetro de entrada un objeto de tipo Cliente.

Para poder hacer esto, lo primero que tendremos que hacer será modificar un poco nuestra clase Cliente, de forma que ksoap sepa cómo serializar nuestros objetos Cliente a la hora de generar las peticiones SOAP correspondientes. Y para esto, lo que haremos será implementar la interfaz KvmSerializable en nuestra clase Cliente. Para ello, además de añadir la cláusula implements correspondiente tendremos que implementar los siguientes métodos:

  • getProperty(int indice)
  • getPropertyCount()
  • getPropertyInfo(int indice, HashTable ht, PropertyInfo info)
  • setProperty(int indice, Object valor)

El primero de ellos deberá devolver el valor de cada atributo de la clase a partir de su índice de orden. Así, para el índice 0 se devolverá el valor del atributo Id, para el índice 1 el del atributo Nombre, y para el 2 el atributo Teléfono.

@Override
public Object getProperty(int arg0) {

	switch(arg0)
        {
        case 0:
            return id;
        case 1:
            return nombre;
        case 2:
            return telefono;
        }

	return null;
}

El segundo de los métodos, deberá devolver simplemente el número de atributos de nuestra clase, que en nuestro caso será 3 (Id, Nombre y Telefono):

@Override
public int getPropertyCount() {
	return 3;
}

El objetivo del tercero será informar, según el índice recibido como parámetro, el tipo y nombre del atributo correspondiente. El tipo de cada atributo se devolverá como un valor de la clase PropertyInfo.

@Override
public void getPropertyInfo(int ind, Hashtable ht, PropertyInfo info) {
	switch(ind)
        {
        case 0:
            info.type = PropertyInfo.INTEGER_CLASS;
            info.name = "Id";
            break;
        case 1:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "Nombre";
            break;
        case 2:
            info.type = PropertyInfo.INTEGER_CLASS;
            info.name = "Telefono";
            break;
        default:break;
        }
}

Por último, el método setProperty() será el encargado de asignar el valor de cada atributo según su índice y el valor recibido como parámetro.

@Override
public void setProperty(int ind, Object val) {
	switch(ind)
        {
        case 0:
            id = Integer.parseInt(val.toString());
            break;
        case 1:
            nombre = val.toString();
            break;
        case 2:
            telefono = Integer.parseInt(val.toString());
            break;
        default:
            break;
        }
}

Mediante estos métodos, aunque de forma transparente para el programados, ksoap será capaz de transformar nuestros objetos Cliente al formato XML correcto de forma que pueda pasarlos como parámetro en las peticiones SOAP a nuestro servicio.

Por su parte, la llamada al servicio también difiere un poco de lo ya comentado a la hora de asociar los parámetros de entrada del método web. En este caso, construiremos en primer lugar el objeto Cliente que queremos insertar en la base de datos a partir de los datos introducidos en la pantalla de nuestra aplicación de ejemplo. Tras esto crearemos un nuevo objeto PropertyInfo, al que asociaremos el nombre, valor y tipo de nuestro cliente mediante sus métodos setName(), setValue() y setClass() respectivamente. Por último, asociaremos este cliente como parámetro de entrada al servicio llamando al metodo addProperty() igual que hemos hecho en las anteriores ocasiones, con la diferencia de que esta vez lo llamaremos pasándole el objeto PropertyInfo que acabamos de crear. Además de esto, tendremos también que llamar finalmente al método addMapping() para asociar de alguna forma nuestro espacio de nombres y nombre de clase «Cliente» con la clase real java. Veamos el código para entenderlo mejor:

Cliente cli = new Cliente();
cli.nombre = txtNombre.getText().toString();
cli.telefono = Integer.parseInt(txtTelefono.getText().toString());

PropertyInfo pi = new PropertyInfo();
pi.setName("cliente");
pi.setValue(cli);
pi.setType(cli.getClass());

request.addProperty(pi);

SoapSerializationEnvelope envelope =
    new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;

envelope.setOutputSoapObject(request);

envelope.addMapping(NAMESPACE, "Cliente", cli.getClass());

Todo esto lo haremos en un nuevo botón añadido a la aplicación de ejemplo (Enviar2), cuyo efecto tendrá que ser idéntico al que ya creamos para la llamada al método web NuevoClienteSimple(), aunque como acabamos de ver su implementación es algo diferente debido a los distintos parámetros de entrada utilizados.

Como imagen final veamos una captura de la pantalla final de nuestra aplicación de ejemplo, donde vemos los tres botones implementados, junto al resultado de la ejecución de cada uno, el mensaje «Insertado OK» de los métodos de inserción, y la lista de clientes recuperada por el método de consulta.

demo-ws-soap-android

Espero que estos dos últimos artículos sobre servicios web SOAP y Android os sirvan para tener un ejemplo completo, tanto de la parte servidor como de la parte cliente, que os sirva de base para crear nuevos sistemas adaptados a vuestras necesidades.

Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la página del curso en GitHub.

Curso de Programación Android en PDF

Este curso también está disponible en PDF. Descubre cómo conseguirlo…

¿Te ha sido de utilidad el Curso de Programación Android? ¿Quieres colaborar de forma económica con el proyecto? Puedes contribuir con cualquier cantidad, unos céntimos, unos euros, cualquier aportación será bienvenida. Además, si tu aportación es superior a una pequeña cantidad simbólica recibirás como agradecimiento un documento con la última versión del curso disponible en formato PDF. Sea como sea, muchas gracias por colaborar!

Más información:

También te puede interesar

150 comentarios

Desarrollo en Android | sgoliver.net blog 27/02/2012 - 19:32

[…] […]

Responder
Jesús 27/02/2012 - 21:52

Perfecta la explicación y muy útil!

Responder
Fabián García 28/02/2012 - 16:27

Me hubiera gustado que generaras un lista con el nombre y numero de teléfono, que aun no entiendo como crear listas con mas de un elemento, pero lo compensas con la explicacion de los objetos complejos en kSoap2Android.

Muchas gracias por el tutorial :D!!

Responder
Iskael 09/03/2012 - 1:54

Muy buen post y muy útil, seria conveniente si pudieses que nos enseñaras a como consumir algun WS con seguridad al menos con el escenario básico Username y Token con ksoap.

Muy buen tuto.
Gracias.

Responder
oscar 13/03/2012 - 1:22

tengo problemas con el URL pongo mi direccion IP pero veo que le pones un puerto 1473 y yo no se de donde sacar mi puerto pero me yo pongo de la siguiente manera y me sale error nose porque nesecito ayuda «http://192.168.1.35/ServicioClientes.asmx»;
ese numero es mi IP

Responder
YoGo 16/03/2012 - 4:00

1. Hola Fabián García…

mira todos los campos de la clase están en listaClientes

si quieres mostrar el Telefono has algo así en esta parte:

// Rellenamos la lista con los nombres de los clientes
final String[] datos = new String[listaClientes.length];

for (int i = 0; i < listaClientes.length; i++)
datos[i] = listaClientes[i].nombre + ""
+ listaClientes[i].telefono;

2. Hola oscar …

http://localhost:11049/ServicioClientes.asmx

Dices que tienes http://192.168.1.35/ServicioClientes.asmx
cuando deberias tener http://localhost:1234/ServicioClientes.asmx

sustituyendo 1234 por tu tu puerto

el puerto lo podemos ver en varias partes:

1. en la bandeja de notificación al lado del reloj, debe de haber un icono de ASP.NET Develovent Server – Port XXXX

2. Al ejecutar en VS2010 el ejemplo ServicioClientes te abre en tu navegador por defecto la pagina web, mira en su dirección url hay también debes ver el puerto.

como lo estamos probando en el emulador debes colocar http://10.0.2.2:1234/ServicioClientes.asmx (sustituyendo 1234 por el puerto correcto)

Nota es importante para los que se descargue el proyecto modificar todo lo que se dice en el tuto.
desde la configuración del SQL Server hasta la creación de la DB.

Yo por mi parte ahora lo que quiero es probarlo en mi móvil, ya hice la novatada y lo probé así y obvio dio error por lo de IP, así que me tocara configurar una IP con Hamachi o un servidor DNS.

Me gustaría contar con ayuda de Sergio o alguien que sepa algo para poder probarlo en un terminal real.

Muchas gracias por compartir, y ahora para el REST que dicen que es mas popular/fácil/rápido que
SOAP.

Responder
hector 19/03/2012 - 8:09

Me util todo, me ha funcionado, pero me gustaría saber como hacerlo funcionar desde el dispositivo movil real

Responder
pelirroja191186 20/03/2012 - 9:32

Hola en que versión de android has hecho esto, yo la haga en la 4.0 y no funciona y en la 2.3 funciona perfecto, he estado leyendo y he encontrado q ksoap solo funciona hasta la 2.3 has escuchado algo?, si es asi como conecto mi android(4.0) con sql server o my sql pues directo aunque no es lo mas conveniente me pasa lo mismo en la 2.3 perfecto y en la 4.0 no va.
un saludin ojala alguien pueda ayudarme

Responder
admin 20/03/2012 - 13:52

Hola pelirroja191186, en principio no hay ningún problema para utilizar ksoap2-android sobre cualquier versión de Android (al menos hasta la 4.0).

Cuando ejecutas el código sobre Android 4.0 ¿obtienes una excepción de tipo NetworkOnMainThreadException? Si es así tu problema puede ser que estás intentando acceder al servicio web desde el hilo principal de la aplicación (por ejemplo directamente en la implementación de un evento de botón o similar). Desde la versión 3.0 de Android (API level 11) no es posible realizar operaciones de red desde el hilo principal (en inglés Main-Thread o UI-Thread), por lo que tendrás que ejecutar el código de acceso al servicio desde otro hilo, por ejemplo haciendo uso de una tarea asíncrona (AsyncTask). Por si te interesa hablaré de este tema en un próximo artículo del curso.

Saludos.

Responder
hector 21/03/2012 - 3:30

tengo una duda, como se hace si quiero enviar una imagen desde android a un webservice?

Responder
MelDj 22/03/2012 - 22:36

Hola, me sucedía lo mismo que a peliroja191186 probare hacer la llamada en otro hilo. Gracias por las lecciones.

Saludos,

Responder
charrito 02/04/2012 - 0:37

a la hora de provarlo en mi android no funcionaba, asi que mi solucion fue montar el asp.net en un servidor, en mi caso utilice mi equipo como uno, con la erramienta IIS. y funciono de maravilla…

Responder
Antonio Jesus 10/04/2012 - 14:02

Estoy usando en vez del emulador un teléfono Android en modo depuración conectado por cable USB al emulador y reconocido por éste. ¿Me podrías decir que dirección IP tengo que poner en este caso?

Responder
kisler 11/04/2012 - 13:53

charrito podrias explicar mas o menos en que consiste lo que has hecho para poder acceder con mi telefono movil? es que tengo el mismo problema y no lo consigo.

Un saludo

Responder
Rafa 16/04/2012 - 3:57

Todo me iba de maravilla hasta que llegue a este capitulo.
Tengo problemas con la ejecucion de la aplicacion. El Web services levanta perfecto pero la aplicacion no encuentra el Ksoap2
me da este error:

04-16 02:50:33.130: E/dalvikvm(301): Could not find class ‘org.ksoap2.serialization.SoapObject’, referenced from method rafa.sanchez.ServicioWebSoap$1.onClick

mas adelante cuando hago clic en cualquier boton me suelta esta otra cosa:

04-16 02:54:01.128: E/AndroidRuntime(301): java.lang.NoClassDefFoundError: org.ksoap2.serialization.SoapObject

Creo que no instale bien este Ksoap. Ayuda por favor!

Ah felicidades al autor de este maravilloso blog,

Responder
Bull 16/04/2012 - 11:36

Rafa, tengo exactamente el mismo problema que tú… estoy googleando a ver si encuentro solución…

Responder
Bull 16/04/2012 - 12:19

Rafa, creo que lo tengo resuelto.

Si os aparece un mensaje similar a:

04-16 11:15:04.700: E/AndroidRuntime(2471): java.lang.NoClassDefFoundError: org.ksoap2.serialization.SoapObject

Eso es porque la librería no se ha exportado a vuestro móvil o máquina virtual. Para que haga eso, id al proyecto, Propiedades, sección Java Build Path, pestaña Order and Export, y marcáis la librería a exportar (en mi caso, «ksoap2-android-assembly-2.6.0.jar-with-dependencies.jar»)

Responder
charrito 23/04/2012 - 17:59

Disculpa la demora Kisler, primero que nada yo estoy trabajando con windows7 profesional. hay que instalar y activar IIS, sige los pasos de este link:

http://czacariasvelez.blogspot.mx/2010/08/instalacion-y-configuracion-de-iis-en.html

En nuestra aplicación de IIS agregaremos una nueva aplicación, a la cual se le asignara un nombre y creara una carpeta que contendrá el proyecto al que deseas tener acceso por medio de la red.
A continuacion iremos a nuestra carpeta contenedora de nuestro proyecto que contiene los servicios web, una vez en ésta, copiaremos los siguientes archivos y carpetas: “bin, service1, web, web.debug, web.release”, estos archivos los pegaremos en la carpeta creada para nuestro proyecto en el IIS. Después de echo esto, vamos a el navegador de internet y ponemos lo siguiente “http://localhost/ProyectoT/Service1.asmx” , la parte que descrita como ProyectoT equivale al nombre de nuestra aplicación creada en el IIS, la parte de Service1.asmx es la que contiene nuestros servicios web.
NOTA: Para que esto funcione correctamente hay que dar permisos en el firewall o desactivarlo.

con esto funcionara en una red local.
si deseas tener acceso desde otras redes hay que configurar el router.

Saludos, cualquier duda comenta?

Responder
pelirroja191186 25/04/2012 - 10:55

Hola me he demorado un poco en escribir pero es decir ese era el problema que no deja hacerlo en el hilo principal con un ansytask funciona perfecto, muchas gracias por todo y si alguien lo necesita que me diga para postearlo saludos

Responder
pelirroja191186 25/04/2012 - 11:29

Hola tengo otro problema, habia dejado este tema un tiempo pues estaba trabajando en otra cuestion y ahora cuando vuelvo a retomar veo que me da el error de appplication has stoped fui depurando a ver donde y solo con poner esta linea me salta
request = new SoapObject(NAMESPACE, METHOD_NAME);
noo se si es alguna libreria que al reinstalar omiti o donde puede estar el error.
alquien me ayuda por fis, saludos y muchas gracias

Responder
pelirroja191186 25/04/2012 - 15:18

Hola nuevamente, ya lo resolvi es que no me estaba cogiendo bien la biblioteca ksoap no se que pasaba pero la elimine y volví a agregarla y me funciono perfectamente, muchas gracias por todo saluditos

Responder
bitman120 30/04/2012 - 23:25

Hola todo el ejemplo me va bien, pero cuando quiero haces la consulta para listar me este erro:

04-30 22:21:24.264: D/Al inicio(421): El error es: SoapFault – faultcode: ‘soap:Server’ faultstring: ‘System.Web.Services.Protocols.SoapException: El servidor no puede procesar la solicitud. —> System.Data.SqlClient.SqlException: The parameterized query ‘(@nombre nvarchar(4000),@telefono int)INSERT INTO Clientes (Nomb’ expects the parameter ‘@nombre’, which was not supplied.

alguien sabe que podría ser?

Responder
bitman120 30/04/2012 - 23:30

Para mi comentario anterior, fue un error cuando cambie los valores para el webservice.

Responder
jaime 03/05/2012 - 15:28

Hola un saludo, muy buen blog, bueno al grano, alguien podria hablar mas del tema del funcionamiento real de esta aplicación en el telefono si alguien podria explicar en general de como hacerlo se lo agradeceria mucho
de ante mano gracias y un saludo

Responder
Carlos Corona 09/05/2012 - 18:03

Hola! Muy buen curso! Muy completo! Me ha servido de mucho. A mí todo me funcionó perfecto lo de la configuración y demás, pero he tenido problemas al intentar envíar un dato que no es un string. En mi webService de dotNet, tengo definido un método como sigue:

public int NuevoAlbumSimple(string titulo, decimal precio, string art){

}

El detalle está en que cuando intento realizar:

request.addProperty(«titulo», «Algun nombre»);
request.addProperty(«precio», 10.5);
request.addProperty(«art», «htttp://sgoliver.net/»);

Me envía un error diciendo que 10.5 no se puede serializar… intenté convertilo a Double y a Float, pero me marca lo mismo…

hay alguna manera de solucionarlo?

Responder
Program 15/05/2012 - 10:59

Hola, llevo 2 o 3 días siguiendo este tutorial, y para el listado, modificaciones e inserciones no tengo problema, pero para la eliminación si.

Si tengo un listado y selecciono un Item, como debería hacerlo para pasar el id (o algun valor identificativo) al Soap y eliminarlo?

Desde Web si me funciona, así que el problema es principalmente en la programación Android, me esta volviendo loca ya el tema xD

Responder
Damaris 17/05/2012 - 12:17

Que habría que poner en

String NAMESPACE = «http://microsoft.com/webservices/»;
/** Esta dirección IP solo funciona en el emulador */
String URL=»http://localhost:4011/ServicioCoches.asmx»;
String METHOD_NAME = «EliminarCocheEntradas»;
String SOAP_ACTION = «http://microsoft.com/webservices/EliminarCocheEntradas»;

URL para que funcione desde un dispositivo movil real?

Responder
colymore 21/05/2012 - 15:52

Buenisimo Oliver

Responder
BERNARDO H 21/05/2012 - 16:58

hola, muy bueno el tuto, me funciono excelente, luego segui los enlaces de los compañeros sobre como configurar IIS por ejemplo para las pruebas en telefonos reales y llegue hasta el siguiente video en youtube donde se muestra como publicar nuestro sitio y convertir nuestra maquina en servidor, (complementa lo expuesto por charrito) lo adjunto para quienes lo quieran ver:

http://www.youtube.com/watch?v=eE6BJb1_to0

Responder
Jarmesto 29/05/2012 - 17:06

Hola a todos!!! me da un error de este tipo: ArrayIndexOutBoundOutexception: Array Index out of range: 0.

for (int i = 0; i < ListaAprobaciones.length; i++)
{
SoapObject ic = (SoapObject)resSoap.getProperty(i);

Aprobaciones cli = new Aprobaciones();

cli.No_Documento = ic.getProperty(0).toString();
cli.Fecha_Factura = ic.getProperty(1).toString();
cli.No_Proveedor= ic.getProperty(2).toString();
cli.Nombre_Proveedor = ic.getProperty(3).toString();
cli.IdFacturaE_factura = ic.getProperty(4).toString();
cli.IdFacturaEdas = ic.getProperty(5).toString();
cli.ImporteFactura = ic.getProperty(6).toString();
cli.Aprobador = ic.getProperty(7).toString();
cli.Fecha_Aprobacion= ic.getProperty(8).toString();

ListaAprobaciones[i]=cli;

Podeis ayudarme? gracias

Responder
Jarmesto 31/05/2012 - 12:49

Solucionado , Gracias!!

Responder
Harry 08/06/2012 - 21:26

Hola, alguien podria decirme como usar el AsyncTask, estoy tratando de agregarlo a la aplicación pero no logro que se conecte a la Base de datos, llega al servicio web pero no me esta enviando bien el parámetro, llega como nulo y si pruebo con un script que no necesite recibir un parametro me sale que ha ocurrido un error en doInBackground. Gracias de antemano. Saludos.

Responder
Elver Florez 26/06/2012 - 16:09

Buenas,
Necesito alguien que me colabore con un par de aplicaciones en Android, que me ayude a hacerlas o que me ayude con los errores que me salen. Mi correo es eflorez09@gmail.com para explicarle mejor de que se trata a quien este interesado. Ya le envie un correo a sgoliver pero no me contesto. Agradezco la pronta de respuesta.

Responder
sgoliver 26/06/2012 - 16:20

Hola Elver, no siempre puedo atender todos los correos que me llegan con consultas sobre desarrollo en Android. Te sugiero que expongas tus dudas y consultas en el foro de la web (http://www.sgoliver.net/foro), donde otros lectores del blog quizá puedan ayudarte. Saludos.

Responder
Elver Florez 03/07/2012 - 16:07

Volvi, ya pude avanzar, tenia un error con la libreria, eso era todo, pero ahora estoy cargando en listview una tabla estados (idestado, descripcion). en el listview se muestra la descripcion y con el metodo setOnItemClickListener puedo saber cual fue el item que se selecciono pero como hago para saber cual es el idestado de ese item? agradezco de nuevo su ayuda

Responder
Benjamin 03/07/2012 - 16:53

Saludos!!
Antes que nada te agradezco que te tomes el tiempo de subir toda la informacion y realizar estos ejemplos Felicidades por tu Blog esta genial.
No tienes idea de todo lo que estuve batallando tratando de regresar mas de un valor de un servicioWeb y usarlo en una aplicacion android y este tutorial me dejo todo claro y esta super bien explicito, la verdad te agradezco bastante y que bueno que te tomas el tiempo para hacer el conocimiento posible muchas gracias.

Responder
Hector Ibarra 05/07/2012 - 18:43

Hola, como puedo hacer para ejecutar dos servicios web al mismo tiempo, ya que tengo que hacer dos consultas de diferentes lugares, pero quiero mostrarlas en la misma actividad.

gracias.

Responder
Fabián 12/07/2012 - 16:29

Hola, alguien podría explicar lo de AsyncTask? es que me da el error de NetworkOnMainThreadException y no sé como resolverlo. Gracias!

Responder
sgoliver 12/07/2012 - 16:59

Hola Fabian, estoy en ello, los próximos artículos serán sobre tareas en segundo plano: hilos, Asynctask y servicios. No tendrás que esperar mucho. Saludos.

Responder
Viviana 19/07/2012 - 18:16

hola estoy intentango jalar datos de un servidor web pero no puedo acceder a los datos eel sw me debuelve un dataset como le podria hacer para acceder a los datos y vaciarlos en la pantalla????

Responder
glading 20/07/2012 - 2:45

Hola charrito, Bernando:
He realizado hasta donde ustedes dicen de publicar en un web service de ISS y me funciona perfecto. Pero quiero saber como configurar en android , osea en HttpPost(«http://localhost/Api/Clientes/Cliente»); que deberia colocar si quiero que funcione desde mi celular, en una misma red..Gracias! y excelente tutorial, felciitaciones!

Responder
Maximiliano 25/07/2012 - 6:06

Hola, te agradezco tus post son realmente utiles, yo tengo una pregunta:
Se puede usar este mismo webservice para comunicarse con una base de datos en MySql??
Y otra aprovechando la maldad como podria implementarlo para una autenticacion de personas ?? Gracias y saludos

Responder
David 02/08/2012 - 22:10

Un saludo a todos
tengo un problema con el la aplicación
me ejecuta lael web service sin problemas,pero la aplicacion android cuando lo ejecuto me despliega el siguiente error:
The aplicaction Android Servicio Web Soap (process .net.prueba.android) has stopped unexpectedly. Please try again.

Gracias por su ayuda

Responder
Andres Gomez 13/08/2012 - 2:06

hola tengo una pregunta desde la pc sirve fenomenal pero cuando creo el .apk e instalo el programa en una tablet Android no realiza los registros que seria lo mas afectivo para que funcione desde la tablet.

Gracias por la Ayuda

Responder
Guillermo 02/09/2012 - 22:33

Hola, como puedo hacer para poder accerder desde la direccion ip del equipo, por defecto me abre esta direccion en el navegador http://localhost:1473/ServicioClientes.asmx
pero si quiero acceder a traves de IP ej: http://192.168.1.2:1473/ServicioClientes.asmx
no encuentra la direccion. me falta algun paso mas?

Responder
Edel Custodio 19/09/2012 - 17:35

Guillermo, ya publicaste tu servicio en el IIS? de ser así no es necesario que le coloques el numero de puerto.

Responder
Juan 20/09/2012 - 12:25

Hola como podria enviar en el soapObject en un property un Array? Gracuas

Responder
miriam 25/09/2012 - 19:18

Mil gracias!!!

Responder
Juan Luis 26/09/2012 - 18:45

Buenas tardes, en realidad muy util el bloq, lo he copiado igual, desde la creacion de la tabla, el ws y el proyecto en eclipse, PERO al tratar de ejecutar con mi emulador y Android 2.2 me sale el siguiente error:

«Sorry
The application android servicio web soap (processsnet.sgoliver.android) has stopped unexpectedly. Please try again.»

POR FAVOR AYUDA…

Responder
nelsito_android 20/10/2012 - 23:16

hola, quiero aportar con una respuesta y con una pregunta!! :)
Inicialmente tuve el problema en que ksoap no se reconocía. eso lo solucioné cuando copie la libreria como recurso dentro del proyecto y desde ahi generé los pasos para importar el JAR.
mi consulta: he realizado lospasos para consumir WSnet sin problemas desde el emulador y desde varios moviles. sin embargo para un WSphp sólo lo he logrado en el emulador. qué podrá estar pasando cuando intento conectar con el WSphp desde los moviles. es raro. ojalá alguien tenga una respuesta o por ultimo alguna teoría. si establecemos una propiedad net=true; se necesitará alguna definision o proceso adicional al ser un WS PHP SOAP???????
Saludos.

Responder
makiina 23/10/2012 - 18:18

Buenas tenía una duda

String SOAP_ACTION = «http://sgoliver.net/NuevoClienteSimple»;

no se si la direccion debe existir o vale cualquiera con tal de que en el webservice definamos el namespace de esa manera. ¿Como debo hacerlo sino?

Gracias

Responder
Leandro 31/10/2012 - 4:00

Flaco te felicito!, la verdad que lo explicaste muy facil y completo!, y me costo encontrar una solucion en google, deberia ser el primer resultado del buscador!
Ya me pongo a hacer mi proyecto!

Responder
Miguel 23/11/2012 - 14:24

Hola!!
hice el ejemplo, el web service me funciona perfectamente, pero al momento de invocarlo desde android no funciona
cuando oprimo debug aparece la interfaz y todo, pero al presionr (consultar, nuevocliento) me aparece esto en la pantalla.
http://oi49.tinypic.com/641aqa.jpg
el cual si oprimo no, se cancela y si presiono si se desconfigura totalmente mi entorno de eclipse.
cuando presiono ejecutar, aparece toda la interfaz, pero al consultar, me sale que el proyecto se ha detenido.

que podría hacer??. Cómo soluciono este problema. Muchisimas gracias.

Responder
Geonick 27/11/2012 - 23:32

Miguel, ese no es un problema… lo que te duce basicamente, es que como estas corriendo la aplicacion en modo debugg te pregunta si quieres que la interfaz (de eclipse) cambie a modo debug, este modo se utiliza para poder identificar bien lo errores y tener un mayor control de los procesos… si quieres ver si funciona correctamente correlo como aplicacion, osea boton derecho en el proyecto run as… «android aplicattion»

Responder
Carlos 29/11/2012 - 10:17

Cuando corro la aplicacion, ya sea en mi android o en el emulador, al momento de hace una consulta o enviar datos, me sale el aviso que se cerro inesperadamente, que hago?

Responder
j@s 03/12/2012 - 5:48

Hey me da el mismo error no puedo hacer nada!! ayuda

Responder
olman 05/01/2013 - 17:17

Seguí todo el tutorial, con la única diferencia que no utilice los clásicos .asmx sino que utilice los WebService WCF, y todo va bien, ya me comunico con el servidor, el problema, es que trato de enviar un objeto ya que el metodo del WS recibe un objeto como parametro, lo creo, Ksoap2 lo serializa bien, pero al servidor solo llega null, no consigo que el objeto llegue de forma correcta.

Responder
leos 16/01/2013 - 0:19

hola he estado siguiendo este tutorial y esta exelente, me surge el siguiente problema quiero mandar datos de fraccionarios y la clase propertyInfo no contiene algun parametro que me permita trabajar con clases de double o float

Responder
hp 17/01/2013 - 1:39

hola buen post,
al correr el programa en el emulador marca un error y este se cierra.
en el logcat me aparece lo siguiente:

Could not find class ‘org.ksoap2.serialization.SoapObject’, referenced from method com.example.wssoapandroid.MainActivity$1.onClick

la libreria ya la agregue en el build path cual y no encuentro qe puede ser

Responder
hp 18/01/2013 - 1:04

ya solucione el error anterior pero ahora siempre que entra en el try-catch me regresa error! en cualquiera de los 3 botones, ya probe el webservice y todo bien
la unica diferencia es que son hechos en vb no en c#

cual podria ser el error para qe hace qe entre en el cath???

Responder
beto 19/01/2013 - 20:39

quisiera saber como traerme una imagen por medio del web service y mostrarla en mi app de android alguien sabe como ???

Responder
beto 22/01/2013 - 23:18

tengo en mi BD los datos de un producto nombre e imagen
y quiero recuperarlos por medio de un web service y a su ves mostrar el nombre del producto y su imagen en mi aplicacion de android..
hay alguna forma de enviar la imagen con este mismo ejemplo???

Responder
Yerlak 20/02/2013 - 0:03

Qué tal amigo? Llevo días tratando de solucionar y ver un error en el que la aplicación me explota en esta línea: SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

Qué crees que pueda ser?

Responder
Nogard 20/02/2013 - 0:36

Excelente Blog Felicitaciones

Responder
cristina 15/03/2013 - 20:25

Hola,
Gracias por el post, está super bueno, pero tengo el mismo problema que tuvo HP al principio, me gustaria que nos cuente como lo solucionó.

Gracias!!

Responder
cristina 18/03/2013 - 15:37

Hola,
Ya he resulto mis problemas por lo tanto comparto la solución:
1. – La libreria deben copiarla dentro del proyecto, en la carpera libs ya que de lo contrario la aplicación en modo run no encuentra la ruta (pues se supone que está ejecutandose en el teléfono)
2.- NO olvidar incorporar esta línea:
3.- NO olvidar cambiar localhost por 10.0.2.2

Gracias y espero que le sirva el recordatorio

Responder
cristina 18/03/2013 - 15:39

Esta era la línea

Responder
cristina 18/03/2013 - 15:39

ups no se ve, pero es la de los permisos a internet que se agrega al manifiesto

Responder
Alejo 25/03/2013 - 16:07

Hola, primero que todo muchas gracias por el tutorial, voy en la interfaz y entre a esta seccion para realizar una pregunta haber si alguien me puede colaborar, necesito hacer una aplicacion con reconocimiento ocr y no encuentro la api o las librerias para realizar el desarrollo si alguien sabe o conoce algun sitio donde me puedan orientar les agradeceria enormemente.

Responder
JOSE MANUEL 29/03/2013 - 4:26

Lo único que me queda por saber es como se convierte en un servicio de windows, la dll que queda después de compilar el proyecto.
Gracias anticipadas por la ayuda.

Responder
JOSE MANUEL 30/03/2013 - 1:05

Bueno lo de la Dll no viene al caso. Gracias Cristina, poniendo la librería jar en el directorio lib del proyecto, e importándola de nuevo he conseguido que funcione la inserción del registro.
Muchas gracias.

Responder
JOSE MANUEL 30/03/2013 - 1:07

Por cierto para que os funcione bien en el emulador olvidaros de ponerle el puerto 1473 que viene en el ejemplo porque no os funcionará

Responder
JOSE MANUEL 01/04/2013 - 16:10

Estoy todavía con la inserción de un registro y desde el emulador me funciona todo OK, pero cuando pongo la pagina en inet o en la red local para entrar desde el teléfono no consigo que me funcione.

Responder
LL 03/04/2013 - 4:18

tengo el mismo problema que hp aun despues de haber hecho los pasos que nos presenta cristina me sigue regresando al error ¿alguien me podria dar una explicación o la forma en que se puede solucionar el problema?

Responder
Rul 05/04/2013 - 8:59

Ante todo muchas gracias por tu curso la verdad que lo voy siguiendo y esta muy bien explicado y muy completo.

Mi duda surge a raíz de como resolveríamos la invocación desde android si el webservice al que queremos acceder requiere de un certificado por temas de encriptación de la información.

Un saludo y muchas gracias.

Responder
Ariel 20/04/2013 - 20:09

Hola, muchas gracias por el tutorial lo he seguido y funciona perfecto, luego he intentado hacer otra app siguiendo igual el tutorial y no me funciona, tengo lo siguiente en el WS:
una clase reserva
con 4 atributos:
id,persona, fecha, comentario.

tengo una función addreserva( Reserva reserva)

en el proyecto de android también tengo otra clase con esas mismas características y que ademas implementa la interfaz KvmSerializable como dice el tutorial, mi problema esta en que cuando envió la petición me da error y me dice algo así como que estoy intentando enviar un objeto no serializable. no se si todas las clases se pueden serializar o si hay alguna otra manera de hacerlo.

Un saludo :D

Responder
Leo 24/04/2013 - 0:27

Amigo en el emulador y el dispositivo obtengo:

la aplicación se ha interrumpido inesperadamente inténtalo de nuevo

Responder
Jose Antonio 03/05/2013 - 20:22

Deben de ser identicos el objeto de android y el objeto del webservices en java ?

tengo un objeto con 30 atributo y dos array list

Responder
juamorfer 06/05/2013 - 15:38

Buenas!

Bueno manual!

Pero tengo un problema en la conexión,he seguido todos los pasos pero no consigo que se conecte.
Alguna solución?

Gracias!

Responder
juamorfer 06/05/2013 - 15:40

Error que me sale es el siguiente:

failed to connect to /10.0.2.2 (port 5379) after 20000ms

Responder
juamorfer 06/05/2013 - 15:43

También tengo agregada el permiso de internet en el manifest

Responder
Rul 10/05/2013 - 7:45

Buenos días,

De nuevo gracias por tus tutoriales la verdad es que estoy aprendiendo una barbaridad con ellos.

Mi pregunta es alguien lo ha probado a ejecutar este ejemplo en un móvil con android 4.0 o superior, es que ha mi me da error y leyendo por internet parece ser que dicen que ahora las peticiones webservice se tienen que lanzar como en segundo plano o en otro hilo de ejecución que no sea el principal.

Si he dicho algo que no es perdonar, pero es lo poco que he podido ir averiguando.

Un saludo.

Responder
Alan El Mago 23/05/2013 - 0:55

LA SOLUCIÓN:

Para los que descargaron el código como yo sigan estos pasos.

1.- Efectivamente hay que poner la librería ksoap2 dentro de la carpeta de tu proyecto pero esta carpeta no existe. Entonces hay que crearla.

En mi caso esta es la ruta donde descargue el código:

C:\Users\I\\android-ws-soap\android-ws-soap\

Justo aquí creamos la carpeta «lib» para que quede así:

C:\Users\I\\android-ws-soap\android-ws-soap\lib

copiamos el ksoap2.

2.- Vayan a las propiedades de su proyecto, en el JAVA Build Path. En caso que ya exista el ksoap2 hay que eliminarlo seleccionándolo y clic en Remove.

Despues agregen un External JAR y jalen el k2soap que esta dentro del proyecto.

3.- verifiquen que estos parametros sean los mismos del Visual Studio.
En mi caso yo cambie la ruta a la default del Visual.

NAMESPACE = «http://tempuri.org/»;
URL=»http://10.0.2.2:1473/ServicioClientes.asmx»;
METHOD_NAME = «NuevoClienteSimple»;
SOAP_ACTION = «http://tempuri.org/NuevoClienteSimple»;

Eso es todo.

PD: Muchas gracias por compartir tu conocimiento. Nosotros haremos lo mismo.

Responder
jackfido 14/06/2013 - 6:18

Buenas noches desde Monterrey, Mx. El motivo de mi visita basicamente es preguntar, mmm que debo hacer para ejecutar mi prueba en un dispositivo real, tengo mi aplicacion con un login, como de costumbre en varias aplicaciones, el WCF esta hospedado localmente en mi PC, estoy conectado al wireless de mi casa tanto en mi smartphone como en mi pc, pero no he logrado conectarme desde mi telefono a mi WCF en la PC, alguna idea, es posible esto?

Responder
jordi 25/06/2013 - 11:56

El tuto esta genial. Pero ahora necesito crear un login y pass y autentificarme mediante webservice. Pero nose como relacionarlo con lo del tutorial expuesto. Help me plz!

Responder
Miguel 03/07/2013 - 10:00

Buenos días.
Primero darte las gracias por el buen blog que tienes, la verdad que me ha evitado muchos quebraderos de cabeza.
Lo segundo es preguntarte si conoces la forma de pasar a través del SoapObject un objeto propio.

Por ejemplo: ObjetoCliente { String sUser; String sPass};

Un saludo.

Responder
Alavaros 15/07/2013 - 20:35

Buenas! Primero gracias por estos tutoriales.

He seguido este tutorial al pie de la letra, pero me gustaría consumir el servicio web desde el móvil, ¿como puedo hacerlo, que debo cambiar para poder probarlo con el dispositivo conectado al ordenador?

Saludos.

Responder
Acceso a Servicios Web REST en Android (2/2) | sgoliver.net blog 17/07/2013 - 19:43

[…] ya dijimos en el apartado anterior sobre servicios SOAP, a partir de la versión 3 de Android no se permite realizar operaciones de larga duración dentro […]

Responder
Carlos 12/08/2013 - 22:33

Saludos a todos… El blog es espectacular… Tengo un problema con una aplicación android que trabaja con geoposicionamiento y acceso a servicios SOAP para sincronizar la información grabada en SQLite… Corre perfecto en celulares, pero al querer correrlo en tablets no conecta a internet para hacer la sincronización.. Algún comentario al respecto

Responder
Notificaciones Push Android: Google Cloud Messaging (GCM). Introducción | sgoliver.net blog 18/08/2013 - 11:50

[…] a modo de almacén de datos, y aprovechando que ya hemos visto como crear servicios web SOAP y llamarlos desde aplicaciones Android, vamos a utilizar uno de éstos para la comunicación entre cliente y servidor (paso […]

Responder
Notificaciones Push Android: Google Cloud Messaging (GCM). Implementación Cliente (Nueva Versión) | sgoliver.net blog 18/08/2013 - 12:46

[…] apartado anterior, sirviéndonos para ello de la librería ksoap2, tal como ya describimos en el capítulo sobre servicios web SOAP en […]

Responder
elizabeth 21/08/2013 - 19:30

Hola! tambien me parece genial la explicacion, muchas gracias!, sin embargo de acuerdo a lo que entiendo esto solo funciona en linea, pero que hay si lo que necesito es que la informacion quede almacenada en el dispositivo android y la sincronizacion solo se ejecute bajo demanda? me pueden recomendar algun tutorial, ejemplo, articulo, porfavor? saludos y gracias!

Responder
elizabeth 21/08/2013 - 22:34

para ese caso me parece que entonces lo que se tiene que sincronizar es la base de datos del sqlite con la de sql server

Responder
daniel 26/08/2013 - 20:43

Gracias por tus tutoriales (y) pero una pregunta, como puedo acceder a los metodos corriendo la App desde el celular, no logro hacerlo aun poniendo la ip de la maquina :s
Gracias :v

Responder
Bryam 05/09/2013 - 17:27

Alguien me podria pasar el link directo para descagar este proyecto o decirme los pasos para descargarlo desde aca ? es para entender un poco mas el Tutorial

gracias

Responder
Roland 22/09/2013 - 11:40

Hola, lo primero agradecer a sgoliver el magnífico curso sobre android. He realizado los pasos del tutorial de servicios web SOAP y no he tenido ningún problema a la hora de ejecutarlo en el emulador. Sin embargo, a la hora de ejecutarlo en mi dispositivo no funciona, la aplicación se abre bien pero a la hora de enviar información o consultarla me sale el mensaje de error que se programó en el código. He cambiado la dirección local del emulador http://10.0.0.2:58566/ServicioClientes.asmx por http://127.0.0.1/ServicioClientes.asmx no se si esto es correcto. Gracias de antemano y un saludo.

Responder
Guimel 30/09/2013 - 15:30

Gracias por este tuto realmente funciona a la perfección eres lo máximo

Responder
Cynthia 12/10/2013 - 17:17

Excelente tutorial!!! Muy bien explicado, gracias !!!

Responder
walter 27/10/2013 - 22:22

quisiera que me des una ayuda amigo el ejemplo funciona perfecto pero cuando yo envió un objeto con atributo de tipo Date desde la aplicación android al servicio web no funciona no se como recibirlo en el servicio web ya que ahí simplemente el atributo lo declare de tipo Datetime que lo lógico no se si habrá diferencias entre el Date de java y el Datetime de c# espero su respuesta!! y la ayuda que necesito por que llevo dándole vueltas mas de una semana.

Responder
Kevin 02/11/2013 - 20:08

Creé mi propio WS y no me funcionaba con el emulador, en cambio, descargué el WS que estaba en el codigo y me funcionó perfecto, la pregunta es, ¿por qué?

Cuando abri el WebService (WS) que está en el ejemplo, este se abrió en el puerto 1473 (cosa que se puede comprobar en la URL del navegador cuando uno le da ejecutar en Visual Studio), pero al ejecutar el WS que o hice, este se abria en el puerto 63619, y al poner reemplazar el codigo del puerto en el codigo Android, no inserta.

Si puedo solucionarlo, les avisaré.

Responder
Kevin 02/11/2013 - 20:12

https://github.com/sgolivernet/curso-android-src Para descargar todo el código de los tutoriales (por si acaso)

Responder
Luis Ventura 07/11/2013 - 3:44

Hola!, esta genial el tutorial he estado desarrollando una aplicación que correo cañón desde el emulador pero TENGO UN PROBLEMA cuando he probado publicando mi servicio y conectarme desde un smartphone la aplicación se me cae cuando trato de enviar una cadena muy larga al Servicio SOAP publicado.

He tratado de hacerme un toma pedidos, me logeo sin problemas traigo algunos productos, pero cuando trato de enviar el pedido se cae la aplicación y se me cierra la aplicación cosa que no sucede en el EMULADOR.

Haber si alguien puede darme alguna recomendación.
Gracias.

Responder
william ochoa 25/11/2013 - 3:30

Hola, excelente tutorial y explicaste muy bien lo del error NetworkOnMainThread. comparto este pedazo de código que hace que si permita realizar tareas de larga duración en el hilo principal:

if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}

Hay que colocarlo en el OnCreate del MainActivity.java. Y lo que hace es, cambiar las políticas estrictas de los hilos(Threads) a modo «permitir todo».
Con eso ya no es obligación hacer operaciones Async.

Saludos =)

Responder
dan 25/11/2013 - 5:49

Hola compañeros!!!

he cambiado lo de la ip a 10.0.2.2, el puerto.. pero nada

Yo he copiado el código tal cual, pero en cualquiera de los 3 botones me manda error, al entrar en el try-catch por lo visto me manda directo un false y un ioException: http request failed, Http status 400

he tratado de buscar por qué el 400, pero singo sin encontrar algo, no sé si a alguien le pasó algo similar??

Responder
josue 25/11/2013 - 19:07

Muy bueno el post, felicidades por tan grandiosa explicación.

Saludos.

Responder
Jordi 03/12/2013 - 17:39

Hola,

Estoy tratando de conectarme a mi webservice como se hace en este codigo, cambiando el namesapce, la url etc..

Al momento de conectarme me sale este error : Http request failed: Status 401

Alguien tiene alguna idea? He probado de poner la autenticacion pero no funciona.

Gracias

Responder
Diego 16/12/2013 - 17:20

Excelente explicación, podrían ayudarme con esto?

Estoy consumiendo un WS, la primera vez me funciona y responde correctamente, la siguiente vez me sale un error HTTP request failed, HTTP status: -1, la siguiente ya funciona correctamente y la siguiente se presenta el mismo error, así sucesivamente.

El error en mención es:
12-16 16:00:04.927: W/System.err(227): org.ksoap2.transport.HttpResponseException: HTTP request failed, HTTP status: -1 12-16 16:00:04.927: W/System.err(227): at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:237) 12-16 16:00:04.927: W/System.err(227): at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:118) 12-16 16:00:04.938: W/System.err(227): at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:113) 12-16 16:00:04.938: W/System.err(227): at com.cnt.gis.ServiceActivity.getFahrenheit(ServiceActivity.java:137) 12-16 16:00:04.938: W/System.err(227): at com.cnt.gis.ServiceActivity$AsyncCallWS.doInBackground(ServiceActivity.java:89) 12-16 16:00:04.938: W/System.err(227): at com.cnt.gis.ServiceActivity$AsyncCallWS.doInBackground(ServiceActivity.java:1)

Responder
antonio 24/12/2013 - 1:51

tengo un problema , por favor les pido ayuda, mi sale este error
http request falled, http status: 400

Responder
Pedro Novales 27/12/2013 - 21:48

Hola. Gracias por su tiempo el curso me ha sido de gran ayuda !!!
Tiene alguna experiencia con los tipos de dato Enum a la hora de implementar KvmSerializable ???
El asunto es que estoy usando implementando el metodo CheckDomainAvailability de https://sandbox.domainbox.net/?WSDL y en los parametros hay un tipo de dato Enum, y cuando hago la llamada androidHttpTransport.call(SOAP_ACTION, envelope); pues me lanza el error java.lang.RuntimeException: Cannot serialize: GA (que es precisamente el Enum)
Gracias de antemano por su ayuda !!!

Responder
Sergio Zorrilla 23/01/2014 - 19:58

Que tal, muchas gracias por este tutorial el cual lo encuentro muy bien explicado.
Me surge una duda cuando recibo los datos me manda un error cuando debugeo despues de pasar la linea de condigo : » SoapObject resSoap (SoapObject)envelope.getResponse() ;» el mensaje que me marca es el siguiente : » SoapFault – faultcode: ‘soap:Server’ faultstring: ‘El servidor no puede procesar la solicitud. —> Referencia a objeto no establecida como instancia de un objeto.’ faultactor: ‘null’ detail: org.kxml2.kdom.Node@40d21ae8 »
Me podrias ayudar con este error.

Responder
Ernesto 24/01/2014 - 14:59

Hola:
estoy tratando de consumir un servicio que me retorna una serie de objetos de una base de datos y cuando creo SoapObject responce = (SoapObject)envelope.getResponce(); me da error dice que java.util.Vector, me imagino sea pk lo tengo ke guardar en un array no ?
Saludos

Responder
edwin 14/02/2014 - 16:29

Gracias, por el curso ha sido de gran ayuda, pero tengo un inconveniente , necesito enviar a un webservice un listado de objetos o de string para poder actualizar una base de datos , he buscado en Internet pero los pocos ejemplos que he visto no funcionan y es poca la información al respecto , te agradezco cualquier ayuda.

Gracias,

edwin

Responder
John 21/02/2014 - 4:39

Hola !
Quería en primer instancia felicitarte por tan excelente aporte.
y segundo he probado el proyecto y bueno en cualquier consulta me sale el mensaje error, creo que puede ser el puerto que mencionas al principio
http://10.0.2.2:1473. Podrías indicarme como saber el numero de puerto posible que esta en mi maquina. Gracias

Responder
Carlos 23/02/2014 - 1:34

Buenas tardes estoy tratando de conectar mi WebService con Android, el problema es que cuando lo ejecuto desde el Emulador funciona perfectamente y cuando lo ejecuto desde mi celular no funciona, entonces lo ejecute a modo de Debug y me sale error en esta linea
—-transporte.call(SOAP_ACTION, envelope);
y en el mensaje de error no sale nada

alguna referencia de como hacer que funcione directo en en el móvil y no en el emulador?

Responder
David García 03/03/2014 - 3:27

Hola, este post me ha sido de mucha utilidad. Lo que pones en él me funciona bien. La situación es a la hora de hacer la llamada (transporte.call(SOAP_ACTION, envelope);) que me lanza una excepción de tipo:
¨SSLHandshakeException¨ con el mensaje ¨java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.¨

Estuve buscando en internet y veo que este tipo de excepción ocurre cuando el certificado del servidor al que tratas de acceder es un certificado auto firmado. Una de las respuestas que vi a esta situación era importar el certificado en cuestión a la aplicación. En caso de saber cómo hacer esto, me pudieras ayudar? Muchas gracias. Espero su respuesta.

Responder
md 08/03/2014 - 20:54

hola, muy buen tutorial, tenia una consulta, si el código funciona igual cuando quiero trabajar con fragments en vez de un activity normal o debe cambiar algo?

Responder
JHandal 12/03/2014 - 15:50

Excelente Blog!!!!Congrats

necesito correrlo com API Target 3.3.3 Gingerbread,pero no compila.
I tried all the usual solutions(Support library,clean&build)
R file is not generated!!!!

Responder
alejandro 15/04/2014 - 14:57

muy buen articulo, muchas gracias por compartir el conocimiento

Responder
SySnow 17/04/2014 - 0:43

Felicidades por el trabajo que has realizado y con el que has ayudado ademas de a mí, seguramente a muchas mas personas, ahora sobre el tema…
Tengo entendido que aquí recuperas los datos

final String[] datos = new String[listaClientes.length];

for(int i=0; i<listaClientes.length; i++)
datos[i] = listaClientes[i].nombre;

ArrayAdapter adaptador =
new ArrayAdapter(MainActivity.this,
android.R.layout.simple_list_item_1, datos);

lstClientes.setAdapter(adaptador);

Mi duda es, ¿como puedo acceder a los otros valores que no sea solo el de nombre?, ya que en el proyecto que estoy debo mandar el ID por medio de un Intent, pero no se como acoplar esto a lo que necesito, gracias por la información

Responder
esteban montenegro 01/05/2014 - 14:41

Saludos

Gracias por los tutoriales. Te comento que tengo el mismo problema de Carlos:
Cuando ejecuto desde el Emulador funciona perfectamente y cuando lo ejecuto desde mi celular no funciona, y el error se produce en la linea :
—-transporte.call(SOAP_ACTION, envelope);

y en el mensaje de error no sale nada.
Agradeceria inmensamente cualquier colaboraciòn.

Responder
henry 15/05/2014 - 18:59

hola, muchas gracias por la informacion, tengo una duda.

como controlo el: transport.call(SOAP,envelope);

porque si es que no se logra conectar con el servicio aqui es donde se detiene la aplicacion.

quisiera hacer una condicion y evaluar si es que hay conexion o no?

Muchas gracias.

Responder
Crozz 03/06/2014 - 8:34

Excelente explicación, mejor no se pude muchas gracias

Responder
Fab1122 02/07/2014 - 18:22

Hola tengo un problema…estoy trabajando con un web service q esta en la web…hago tal como esta en el tutorial…pero revise que me da un problema cuando uso SoapObject resultString= (SoapObject) envelope.getResponse();
en lugar de ese uso SoapPrimitive resultString = (SoapPrimitive) envelope.getResponse();
y hay no e brinca el error me puedes ayudar xq ese error???

gracias

pd.- necesito separar los datos en otras variables para poder almacenar en una base de datos del dispositivo

Responder
Caro 20/08/2014 - 23:58

Buenas…primero le agradezco esa buena explicacion del tuto…yo soy nueva en el tema de los web service….mi pregunta puntual es puedo crear los web services en eclipse para el servidor jboss 6?

Disculpe la ignorancia…pero cree uno con jbossWS y no encuentro los el valor de las cuatro constantes….les agradezco me aclaren si estoy al enfocada al intentar crear los servicios web soap con eclipse para el servidor jboss

Responder
Jonathan 02/09/2014 - 16:03

Ya me funciona en el emulador de Android pero aún no me funciona en el cel, alguien sabe cual es la dirección que hay que colocar en como localhost?

Porque tengo entendido que la 10.0.2.2 es para el emulador pero no funciona en un dispositivo real.

final String URL = «http://10.0.2.2:51367/ServicioClientes.asmx»;

Responder
Jonathan Sosa 09/09/2014 - 20:30

Jonathan la dirección de localhost es la 127.0.0.1

Responder
Jose Carlos 12/09/2014 - 21:22

Hola solo una pregunta , el listado de clientes lo obtienes de un datatable o como ?

Responder
Julio 09/10/2014 - 21:19

DIEGO !!!! se pudo solucionar el siguiente problema «Estoy consumiendo un WS, la primera vez me funciona y responde correctamente, la siguiente vez me sale un error HTTP request failed, HTTP status: -1, la siguiente ya funciona correctamente y la siguiente se presenta el mismo error, así sucesivamente.»

Le agradeceria mucho tengo el mismo inconveniente.

Responder
Chin 21/10/2014 - 21:24

Buenas,

El tutorial me sirvio de mucho para crear mi propio Servidor Web y App y todo funciona muy bien en el emulador. Lo intenté correr desde un equipo mobil y no funciono como esperaba.

Mi duda es, que me falta para poder correr la aplicación desde un equipo móbil?

Responder
Luis 30/10/2014 - 22:28

Alguien sabria ¿como cargar un NewDataSet en android?

Responder
Horacio 11/11/2014 - 2:52

Bueno el blog y lo esplicado ..pero tengo una duda sobre este tema como hago para que mi webservice lo pruebe localmente sin acceso a internet por que solo tengo la direccion: localhost:1035/Service1.asmx y el namespace http://tempuri.org/ que biene por defecto ..como podria ejecutarlo localmente ..mi metodo se llama insertCliente ..lo probe usando como el tutorial pero con este namespace por defecto pero no me registraba nada en la BD ..por favor que solucion alternativa me podrian dar ..si tienen una me la podrian informar por el correo gracias
adelante con el blog…

Responder
Enzo 12/11/2014 - 23:26

Buenas, antes de nada agradecer el tiempo por los tutoriales son muy buenos realmente.

Al momento de ejecutar la aplicación solo me dan los mensajes de error de los else del código, que puedo estar configurando mal?.

Muchas gracias.

Responder
PJ 26/02/2015 - 1:46

Lo primero felicitaciones por los tutoriales, y luego quiero comentar un problema que tengo creo que pasa a más personas, pero la solución real no la encuentro. A ver si me podéis ayudar.

Tengo creado un servicio web en .NET desde la plantilla de visualStudio y modificando el hola mundo para que reciba un parámetro y en función del valor de un resultado. El servicio está publicado y desde el formulario de pruebas pones valores y da la respuesta correcta.

Programé un apps haciendo uso del servicio y no funcionaba. Modifique el servicio web para que cuando no se recibiera el parámetro diera una salida por defecto.

Ahora funciona y siempre me retorna la salida por defecto, es como si no entendiera el parámetro que se le pasa.

He observado que en el Body añade dos atributos id y con el espacio de nombres: http://schemas.xmlsoap.org/soap/encoding/ el atributo: root=»1″

¿qué problema puedo tener?

Muchas gracias, PJ

Responder
Jesus 04/03/2015 - 21:27

Hola muy buenas tardes
muchas gracias por el tutorial me esta ayudando bastane una pregunta tengo el webservice ejecuandoce con el pueto 1880 y al proyecto le agrego al url el puerto 1880 pero me aparece un erro de reques http status 400 como saber si es el puerto o alguna configuracion del IIS de ante mano muchas gracias

Responder
Javier 15/04/2015 - 9:06

Me ha encantado el tuto, ahora bien, a ver si consigo que alguien me aporte algo de luz en mi duda.

Todo lo expuesto en este tutorial me funciona correctamente, no obstante, me gustaría saber como consumir en mi aplicación android variables que se definen con la palabra clave OUT en el WebMethod; acorde con este ejemplo me invento el escenario; sería algo así:

[WebMethod]
public void ComprasCliente(Cliente cliente, out List nombresProductos, out int dineroGastado)
{
//Lo que proceda
}

Imaginaos que quiero recoger en mi app de Android el listado de los productos que ha comprado un cliente y el dinero total que lleva gastado. Pues bien, en esta situación, ¿alguien sabría guiarme acerca de como recoger estas dos variables definidas como parámetros «out»?

Gracias de antemano compañeros, y especialmente gracias al creador del tutorial, simplemente genial!

Responder
juan david burbano 27/04/2015 - 16:23

hola, necesito de su ayuda, trato de conectarme al webservice pero no me devuelve un resultado, no se si es por el puerto o como hago la conexion, el codigo esta bien pero no me devuelve el resultado del metodo del webservice. por favor necesito ayuda gracias saludos desde popayan colombia.

Responder
Fescobar 29/05/2015 - 13:03

Excelente, muchas gracias por la explicación.

Responder
ricardo 02/06/2015 - 20:04

gracias amigo

Responder
Curso Programación Android por Salvador Gómez – Indice de Contenidos | Miguel Moyetones 17/06/2015 - 21:26

[…] Servicios Web SOAP en Android (2/2) [v3] […]

Responder
Raul Eduardo Perez 29/09/2015 - 21:16

Muy buen articulo, sin embargo quisiera saber si podría ayudarme ya que tengo un error y no he podido solucionarlo. Le explico: en mi caso yo necesito enviar un objeto Encuesta(que tiene atributos como codigo, nombre y un atributo de tipo persona que es el encuestado) sin embargo me dice que el objeto no es serializable. Gracias por su tiempo!

Responder
RaulGutierrez 12/10/2015 - 19:06

Hola muchas gracias por el post, la verdad me ha servido mucho con los servicios que he consumido, pero me queda una duda, al llamar a servicios cuya url empieza con http todo esta muy bien y muy claro, pero al querer llamar a uno con una url que comienza con https (modo seguro) me regresa un error, no se si exista otro protocolo o sea el mismo para consumir servicios desde una direccion https saludos

Responder
rudy 11/01/2016 - 22:05

Buenas tardes, como le mando como parametro un ArrayList de algun tipo de objetos en especifico, no he encontrado la forma.

AYUDA!!!

Responder
benjamin 11/02/2016 - 1:36

como le hago si quiero mostar los demas elementos de la lista osea telefono e id

Responder
Edson Gamboa 12/04/2016 - 4:14

no entra a onPostExecute, retorna el valor protected Boolean doInBackground(String… params)
pero al hacer el return se termina la ejecucion

Responder
Edson Gamboa 12/04/2016 - 4:18

no entra en onPostExecute, aqui va mi codigo, se termina la ejecicion al hacer el return en doInBackgroud, ayuda he buscado por todos lados y no he podido solucionar este error

package cl.aaii.puntomarketapp;

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

import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;

public class MainActivity extends Activity {

private Button btnIngresar;
private EditText txtUsuario;
private EditText txtPassword;
private ProgressBar progressBar;
private ListView lstLogin;

// referencia a la clase
variables_publicas variables = new variables_publicas();
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

txtUsuario = (EditText) findViewById(R.id.txtUsuario);
txtPassword = (EditText) findViewById(R.id.txtPassword);
btnIngresar = (Button) findViewById(R.id.btnIngresar);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
lstLogin = (ListView) findViewById(R.id.lstLogin);

btnIngresar.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
btnIngresar.setClickable(false);
//paso los parametros usuario y password para validaciòn
new LeeLogin().execute(new String[]{txtUsuario.getText().toString(), txtPassword.getText().toString()});
}
});
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}

@Override
public void onStart() {
super.onStart();

// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
«Main Page», // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity’s content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse(«http://host/path»),
// TODO: Make sure this auto-generated app URL is correct.
Uri.parse(«android-app://cl.aaii.puntomarketapp/http/host/path»)
);
AppIndex.AppIndexApi.start(client, viewAction);
}

@Override
public void onStop() {
super.onStop();

// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
«Main Page», // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity’s content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse(«http://host/path»),
// TODO: Make sure this auto-generated app URL is correct.
Uri.parse(«android-app://cl.aaii.puntomarketapp/http/host/path»)
);
AppIndex.AppIndexApi.end(client, viewAction);
client.disconnect();
}

//Clase interna que extiende de AsyncTask
private class LeeLogin extends AsyncTask {
private Login[] login; //Arreglo para recibir al usuario
Integer progreso, contar; // inicializo para barra de progreso

//Mètodo que se ejecutarà antes de la tarea en segundo plano, normalmente utilizado para iniciar el entorno gràfico
@Override
protected void onPreExecute() {
Toast.makeText(getBaseContext(), R.string.Iniciando_Sesion_barra_cargado, Toast.LENGTH_SHORT).show();//Toast indicando inicio de sesiòn
progreso = 0;
contar = 0;
}

//Este mètodo se ejecutarà despuès y serà el que ejecute el còdigo en segundo plano
@Override
protected Boolean doInBackground(String… params) {
progreso = 20;
publishProgress(progreso);
final String NAMESPACE = variables.namespace;
final String URL = variables.direccionIp + «/ServicioClientes.asmx»;
final String METHOD_NAME = «Login»;
final String SOAP_ACTION = variables.namespace + «Login»;

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

request.addProperty(«user», params[0]);
request.addProperty(«password», params[1]);
progreso = 40;
publishProgress(progreso);

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;

envelope.setOutputSoapObject(request);

HttpTransportSE transporte = new HttpTransportSE(URL);
progreso = 60;
publishProgress(progreso);

try {
transporte.call(SOAP_ACTION, envelope);
SoapObject respuesta = (SoapObject) envelope.getResponse();
progreso = 80;
publishProgress(progreso);

login = new Login[respuesta.getPropertyCount()];

for (int i = 0; i < login.length; i++) {
SoapObject ic = (SoapObject) respuesta.getProperty(i);

Login log = new Login();
log.idUser = Integer.parseInt(ic.getProperty(0).toString());
log.nombre = ic.getProperty(1).toString();
log.apellidos = ic.getProperty(2).toString();

login[i] = log;
contar++;
}
if (contar == 0) {
return false;
}
progreso = 100;
publishProgress(progreso);
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
return false;
}
return true;
}

@Override
protected void onProgressUpdate(Integer… values) {
progressBar.setProgress(values[0]); //voy seteando la barra de progreso
}

@Override
protected void onPostExecute(Boolean res) {//A este mètodo se le llama cada vez que termine la tarea en segundo plano.
if (res) {
// mostramos la respuesta en un toast
Toast.makeText(getBaseContext(), R.string.bienvenido, Toast.LENGTH_SHORT).show();
//Rellenamos la lista con el nombre y apellido del usuario
final String[] datos = new String[login.length];

for (int i = 0; i < login.length; i++)
datos[i] = login[i].nombre + " " + login[i].apellidos;

ArrayAdapter adaptador = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, datos);
lstLogin.setAdapter(adaptador); //lleno lista con nombre y apellido del usuario
btnIngresar.setClickable(true); //activo el boton
Intent intent=new Intent(«android.intent.action.BarraCargado»); //llamo a nueva entidad
startActivity(intent);
} else {
Toast.makeText(getBaseContext(), R.string.error_login, Toast.LENGTH_SHORT).show();
}
}
}
}

Responder
Alejandro Heads 30/09/2016 - 15:24

Excelente Tutorial, Primero que todo muchas gracias,
el envío y el almacenamiento de la información a BD, se realiza sin problemas
Pero me genera Error, al subir Archivo, como a carpeta del Servidor, Como en Byte a la base,
Posees un link para este metodo ?

Gracias…

Responder
alberto luis cabezudo martinez 07/11/2016 - 18:29

La información relacionada aún funciona, fue publicado en el 2012 y estoy trabajando con Android Studio con Lolipop, queria saber si este recurso aún está vigente.
Para los que no trabajamos con un webservice de .net cómo haríamos?
A propósito, excelente recurso, el mejor que he conseguido.

Responder
Eugenio Peña 12/12/2016 - 3:53

Gracias por el Aporte, se que ya han pasado años pero me sirvió para empezar a usarlo.

Tengo una duda sobre como garantizar recibir respuesta del Web Services ya que en ocasiones debido a poca señal de Internet (4g o wiffy) se envía la petición pero no recibo la respuesta aun cuando en el log de mi Web Services veo que se tardo menos de 1 segundo en responden. Por este motivo me quedo con un dato Null de respuesta en mi aplicacion, tengo un timeout de 3 minutos al invocar el Web Services.

SoapObject resp = null;
HttpTransportSE transporte = new HttpTransportSE(Proxy.NO_PROXY, URL, 30000);
transporte.debug = true;
System.setProperty(«http.keepAlive», «false»);
// Llamada
transporte.call(request.getSoapAction(), SOBRE);
resp = (SoapObject) SOBRE.getResponse();
respons = request.respuesta(resp,actividad);

Responder
Daniel Zamudio 12/01/2017 - 21:13

alguien sabe ¿qué pasa si el consumo de servicios web se realiza en el thread de la UI (principal) y no en uno secundario?

Responder

Dejar un comentario

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información. Aceptar Más Información

Política de Privacidad y Cookies