Всем время от времени хочется странного. Вот мне тоже захотелось такого. А именно – подружить Android-приложение с .NET Web-сервисом – такие сервисы и писать быстрее и доступ к ним потом можно получить из Windows Mobile и Windows Phone 7 без проблем – тоесть одним махом можно решить проблему работы с сервисом для различных мобильных платформ. И вот в этот раз я расскажу о том, как сделать чтобы все это заработало.

Подготовительный этап – Создание Web-сервиса

Для начала создадим простой .NET Web-сервис:
ISampleService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace SampleService
{
    [ServiceContract]
    public interface ISampleService
    {
        [OperationContract]
        double Add(double a, double b, String c);
    }
}

SampleService.asmx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace WebService
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class SampleService : System.Web.Services.WebService
    {
        [WebMethod]
        public double Add(double a, double b, String c)
        {
            return a + b;
        }
    }
}

Затем установим его на Web-сервер (для примера я создал виртуальный каталог на локальном IIS сервисе и установил туда сервис прямо из Visual Studio. После этого URL сервиса у меня получился вот такой:

http://192.168.1.32/SampleService/SampleService.asmx

kSOAP2 – Библиотека для доступа к SOAP-сервисам под Android

Процесс создания Android-приложения описывать не буду. Скажу только ,что после создания приложения необходимо в него добавить библиоеку kSOAP2-Android, которую можно скачать здесь.

После того, как скачали дистрибутив, JAR файл библиотеки нужнно положить в подкаталог lib в каталоге с исходными кодами проекта, а затем в окне свойств проекта в разделе Java Build Path на вкладке Libraries с помощью кнопки Add JARs… добавить его в список используемых библиотек.

Библиотеку добавили, теперь можно начинать кодинг.

Кодинг

kSOAP2 для работы с сервисом необходимы 4 параметра:

  • URL сервиса
  • Имя пространства имен
  • Имя SOAP-операции
  • Имя метода

URL Web-сервиса мы знаем – это адрес ASMX файла

Имя пространства имен можно узнать если открыть в браузере URL Web-сервиса:

Дальше нам надо узнать имя SOAP-операции, а также имя метода. Их можно узнать из WSDL схемы:

Итак, с параметрами подключения разобрались. Поулчаем что-то вроде этого:

private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://192.168.1.32/SampleService/SampleService.asmx";
private static final String SOAP_ACTION = "http://tempuri.org/Add";
private static final String METHOD_NAME = "Add";

Теперь надо как-то наш метод вызывать из приложения и передавать туда параметры.
Добавим на activity два текстовых поля, кнопку и поле для вывода результата:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:focusable="true" android:focusableInTouchMode="true">

<EditText android:layout_height="wrap_content"
			android:layout_width="fill_parent"
			android:layout_margin="5dip"
			android:id="@+id/Num1EditText"
			android:inputType="number"
			android:text="2"></EditText>
<EditText android:layout_height="wrap_content"
			android:layout_width="fill_parent"
			android:layout_marginBottom="5dip"
			android:layout_marginLeft="5dip"
			android:layout_marginRight="5dip"
			android:id="@+id/Num2EditText"
			android:inputType="number"
			android:text="3"></EditText>
<Button android:text="="
			android:layout_height="wrap_content"
			android:layout_width="fill_parent"
			android:layout_marginLeft="5dip"
			android:layout_marginRight="5dip"
			android:id="@+id/CallServiceButton"></Button>
<TextView android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:textSize="24dip"
			android:textStyle="bold"
			android:layout_marginLeft="7dip"
			android:layout_marginRight="7dip"
			android:gravity="fill_vertical|fill_horizontal"
			android:id="@+id/ResultTextView"></TextView>
</LinearLayout>

Ну вот, теперь пишем обработчик для кнопки, в котором вызываем Web-сервис.

	OnClickListener mCallServiceButtonListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			try
			{
				double a = Double.parseDouble(mNum1EditText.getText().toString());
				double b = Double.parseDouble(mNum2EditText.getText().toString());
				double result = callService(a, b);
				mResultTextView.setText(String.valueOf(result));
			}
			catch(Exception e) {
				e.printStackTrace();
				mResultTextView.setText(SOAPTest.this.getString(R.string.message_error));
			}
		}
	};

	double callService(double a, double b) throws Exception {
		double result = 0;
		do
		{
			SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

			PropertyInfo pa = new PropertyInfo();
			pa.setName("a");
			pa.setValue(new Double(a).toString());

			PropertyInfo pb = new PropertyInfo();
			pb.setName("b");
			pb.setValue(new Double(b).toString());

			PropertyInfo pc = new PropertyInfo();
			pc.setName("c");
			pc.setValue("test");

			request.addProperty(pa);
			request.addProperty(pb);
			request.addProperty(pc);

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

			envelope.setOutputSoapObject(request);
			HttpTransportSE androidHttpTransport = new AndroidHttpTransport(URL);
			androidHttpTransport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");

			androidHttpTransport.call(SOAP_ACTION, envelope);
			SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
			result = Double.parseDouble(resultsRequestSOAP.getProperty("AddResult").toString());
		}
		while(false);
		return result;
	}

Не забываем обратить внимание на магический флаг envelope.dotNet – без него к .NET сервису подключиться не получится.
Также есть проблемы с подключением к WCF-сервисам. У меня так и не получилось вызвать метод из WCF-сервиса (судя по тикетам проекта ksoap2-android, у многих та же проблема, но говорят что все-таки как-то можно…)

Еще есть проблема с численными параметрами. У меня упорно не хотело сериализировать параметры типа double, пришлось передавать их в виде строки (судя по примерам, все так делаю, видимо так и надо).

Скачать исходный код примера.

Previous ArticleNext Article
Технический директор IT-Dimension, компании-разработчика кросс-платформенного программного обеспечения

Leave a Reply

Your email address will not be published. Required fields are marked *

К.

Кто здесь?

Жизнь свою этот блог начал по одной простой причине: слишком много вопросов… Задают их везде: на работе, по ICQ, знакомые и вобще разные люди. Задумывалось все это для того чтобы собрать как можно больше интересного о разработке для мобильных устройств, и чтобы весь собранный материал помог хотя бы от части этих вопросов, о которых я говорил ранее, избавиться.
Итак, блог о программировании, для программистов и людей им сочуствующих. Информация намечается разная и о разных мобильных платформах. Что из этого получится будет видно дальше.

О.

Ой-Ой-Ой! Google запретил использовать Android-устройства в качетсве модема!

Не ну надо же такому случиться! Google опять делает странное. Как сообщает CNET, T-Mobile не понравилась идея использования G1 в качестве модема, а Google из-за этого удалил все приложения, реализующие эту функцию, из Android Market. В T-Mobile настаивают, что использование такого рода приложений нарушает условия партнерского соглашения с Google.

Не очень, правда, понятно, раньше сообщалось, что Google сможет удалять ПО со смартфонов пользователей. Неизвестно, удалили они их со смартфонов или оставили.

Меня, как пользователя, такой подход ну очень огорчает. Как раз вот подумывал заказать себе девелоперскую версию G1, но недавно совсем Google запретил использование на этих устройствах приложений из Android Marker. Решил немного подождать и попробовать обычный G1, но после этой новости желание покупать это устройство отпало вобще.

Я пользуюсь Интернетом через коммкникатор постоянно, можно сказать, я живу там. По пути на работу – почитать почту, ответить всем в Skype/ICQ/Jabber. Дома вобще отказался от стационарного доступа к Интернет, пользую EDGE и коммуникатор в качестве модема. Не будь этой возможности, вобще не знаю что и делал бы.

С такими выходками Google Android потеряет какую-бы то ни было привлекательность для конечных пользователей. А ведь обидно, эта платформа позиционируется как открытая. Вот такая “открытость” получается. Вместо заботы о пользователях, идут на поводу у операторов. Обидно…