Click here to Skip to main content
15,889,176 members
Articles / Mobile Apps / Android

Android: How to communicate with .NET application via TCP

Rate me:
Please Sign up or sign in to vote.
4.89/5 (89 votes)
13 Mar 2016CPOL4 min read 668.3K   12.2K   273   259
Simple example showing how to communicate between Android and .NET application.

Related articles:

Introduction

The example bellow implements a simple request-response communication between Android and .NET application. The Android application is a simple client using the .NET application as a service to calculate length of the text message.

The example bellow uses Eneter Messaging Framework making the whole communication very simple. (The framework is free for noncommercial use and can be downloaded from http://www.eneter.net. You need to download Eneter for.NET and Eneter for Android. More detailed technical info can be found at technical info.)

340714/CommunicationBetweenAndroidandNET.png

To Run Example

If you use Android Studio:

  1. Download the example for Android Studio (It contains the client project for Android Studio and the service project for Visual Studio).
  2. Open NetService solution in Visual Studio.
  3. If your Visual Stusio supports NuGet packages then just try to build the solution and the Eneter library will be downloaded automatically from NuGet.org server.
    If your Visual Studio does not support NuGet packages then you need to download Eneter Messaging Framework for .NET and unzip it. Then add the reference to the Eneter library. (Right click on 'References' then choose 'Add Reference ...' and navigate to the path where you have unzipped Eneter for .NET and choose the library for .NET 4.0)
  4. Open AndroidNetCommunicationClientActivity in Android Studio.
  5. Download Eneter Messaging Framework for Java and unzip it.
  6. Copy eneter-messaging-android library to AndroidNetCommunicationClientActivity\app\libs.
  7. Right click on the Eneter library and (from the bottom part of the context menu) choose 'Add As Library...'
  8. Start Netervice from Visual Studio.
  9. Start Android client from in Android Studio.

In addition if you use Android Studio 2.3 or higher you need to turn off the 'Instant Run' feature. (The problem is that this feature "secretly" adds the field with the name $change into classes which then causes problems to XmlSerializer.):

  1. Open the Settings or Preferences dialog.
  2. Navigate to Build, Execution, Deployment > Instant Run.
  3. Uncheck the box next to Enable Instant Run.

If you use Eclipse:

  1. Download the example for Eclipse (It contains the client project for Eclipse and the service project for Visual Studio).
  2. Open NetService solution in Visual Studio.
  3. If your Visual Stusio supports NuGet packages then just try to build the solution and the Eneter library will be downloaded automatically from NuGet.org server.
    If your Visual Studio does not support NuGet packages then you need to download Eneter Messaging Framework for .NET and add the reference to the Eneter library. (Right click on 'References' then choose 'Add Reference ...' and navigate to the path where you have unzipped Eneter for .NET and choose the library for .NET 4.0)
  4. Open AndroidNetCommunicationClient in Eclipse.
  5. Download Eneter Messaging Framework for Java and unzip it.
  6. Right click on 'libs' and choose 'Import...' -> 'General/File System' -> 'Next'.
  7. Then click 'Browser' button for 'From directory' and navigate to directory with the Eneter library.
  8. Select the check box and press 'Finish'.
  9. Start Netervice from Visual Studio.
  10. Start Android client from in Android Studio.

TCP on Android

When you implement the communication via TCP on Android, you must count with two specifics:

If the permission is not set, the application is not allowed to communicate across the network. To set the INTERNET permission you must add the following line to AndroidManifest.xml.

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

An example of AndroidManifest.xml allowing communication across the network:

XML
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.client"
    android:versionCode="1"
    android:versionName="1.0" >

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

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".AndroidNetCommunicationClientActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

The emulator acts as a separate device. Therefore, the IP address 127.0.0.1 is the loopback of that device and cannot be used for the communication with other applications running on the same computer as the emulator.

Instead of that you must use a real IP address of the computer or the emulator can use the special address 10.0.2.2 that is routed to 127.0.0.1 (loopback) on the computer. In my example, the Android emulator uses 10.0.2.2 and the .NET service is listening to 127.0.0.1.

  1. You must set INTERNET permission for your Android application!
  2. The IP address 127.0.0.1 (loopback) cannot be set on the Android emulator to communicate with the .NET application!

Android Client Application

The Android client is a very simple application allowing user to put some text message and send the request to the service to get back the length of the text. When the response message is received it must be marshalled to the UI thread to display the result. Also please do not forget to set android.permission.INTERNET.

The whole implementation is very simple with using the Eneter framework:

Java
package net.client;

import eneter.messaging.diagnostic.EneterTrace;
import eneter.messaging.endpoints.typedmessages.*;
import eneter.messaging.messagingsystems.messagingsystembase.*;
import eneter.messaging.messagingsystems.tcpmessagingsystem.TcpMessagingSystemFactory;
import eneter.net.system.EventHandler;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;

public class AndroidNetCommunicationClientActivity extends Activity
{
    // Request message type
    // The message must have the same name as declared in the service.
    // Also, if the message is the inner class, then it must be static.
    public static class MyRequest
    {
        public String Text;
    }

    // Response message type
    // The message must have the same name as declared in the service.
    // Also, if the message is the inner class, then it must be static.
    public static class MyResponse
    {
        public int Length;
    }
    
    // UI controls
    private Handler myRefresh = new Handler();
    private EditText myMessageTextEditText;
    private EditText myResponseEditText;
    private Button mySendRequestBtn;
    
    
    // Sender sending MyRequest and as a response receiving MyResponse.
    private IDuplexTypedMessageSender<MyResponse, MyRequest> mySender;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // Get UI widgets.
        myMessageTextEditText = (EditText) findViewById(R.id.messageTextEditText);
        myResponseEditText = (EditText) findViewById(R.id.messageLengthEditText);
        mySendRequestBtn = (Button) findViewById(R.id.sendRequestBtn);
        
        // Subscribe to handle the button click.
        mySendRequestBtn.setOnClickListener(myOnSendRequestClickHandler);
        
        // Open the connection in another thread.
        // Note: From Android 3.1 (Honeycomb) or higher
        //       it is not possible to open TCP connection
        //       from the main thread.
        Thread anOpenConnectionThread = new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    try
                    {
                        openConnection();
                    }
                    catch (Exception err)
                    {
                        EneterTrace.error("Open connection failed.", err);
                    }
                }
            });
        anOpenConnectionThread.start();
    }
    
    @Override
    public void onDestroy()
    {
        // Stop listening to response messages.
        mySender.detachDuplexOutputChannel();
        
        super.onDestroy();
    } 
    
    private void openConnection() throws Exception
    {
        // Create sender sending MyRequest and as a response receiving MyResponse
        IDuplexTypedMessagesFactory aSenderFactory =
           new DuplexTypedMessagesFactory();
        mySender = aSenderFactory.createDuplexTypedMessageSender(MyResponse.class, MyRequest.class);
        
        // Subscribe to receive response messages.
        mySender.responseReceived().subscribe(myOnResponseHandler);
        
        // Create TCP messaging for the communication.
        // Note: 10.0.2.2 is a special alias to the loopback (127.0.0.1)
        //       on the development machine
        IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
        IDuplexOutputChannel anOutputChannel = 
           aMessaging.createDuplexOutputChannel("tcp://10.0.2.2:8060/");
        
        // Attach the output channel to the sender and be able to send
        // messages and receive responses.
        mySender.attachDuplexOutputChannel(anOutputChannel);
    }
    
    private void onSendRequest(View v)
    {
        // Create the request message.
        MyRequest aRequestMsg = new MyRequest();
        aRequestMsg.Text = myMessageTextEditText.getText().toString();
        
        // Send the request message.
        try
        {
            mySender.sendRequestMessage(aRequestMsg);
        }
        catch (Exception err)
        {
            EneterTrace.error("Sending the message failed.", err);
        }
    }
    
    private void onResponseReceived(Object sender, final TypedResponseReceivedEventArgs<MyResponse> e)
    {
        // Display the result - returned number of characters.
        // Note: Marshal displaying to the correct UI thread.
        myRefresh.post(new Runnable()
            {
                @Override
                public void run()
                {
                    myResponseEditText.setText(Integer.toString(e.getResponseMessage().Length));
                }
            });
    }
    
    private EventHandler<TypedResponseReceivedEventArgs<MyResponse>> myOnResponseHandler
            
         = new EventHandler<TypedResponseReceivedEventArgs<MyResponse>>()
    {
        @Override
        public void onEvent(Object sender,
                            TypedResponseReceivedEventArgs<MyResponse> e)
        {
            onResponseReceived(sender, e);
        }
    };
    
    private OnClickListener myOnSendRequestClickHandler = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            onSendRequest(v);
        }
    };
}

.NET Service Application

The .NET service is a simple console application listening to TCP and receiving requests to calculate the length of a given text.

The implementation of the service is very simple:

C#
using System;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Eneter.Messaging.MessagingSystems.TcpMessagingSystem;

namespace ServiceExample
{
    // Request message type
    public class MyRequest
    {
        public string Text { get; set; }
    }

    // Response message type
    public class MyResponse
    {
        public int Length { get; set; }
    }

    class Program
    {
        private static IDuplexTypedMessageReceiver<MyResponse, MyRequest> myReceiver;

        static void Main(string[] args)
        {
            // Create message receiver receiving 'MyRequest' and receiving 'MyResponse'.
            IDuplexTypedMessagesFactory aReceiverFactory = new DuplexTypedMessagesFactory();
            myReceiver = aReceiverFactory.CreateDuplexTypedMessageReceiver<MyResponse, MyRequest>();

            // Subscribe to handle messages.
            myReceiver.MessageReceived += OnMessageReceived;

            // Create TCP messaging.
            IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
            IDuplexInputChannel anInputChannel = 
               aMessaging.CreateDuplexInputChannel("tcp://127.0.0.1:8060/");

            // Attach the input channel and start to listen to messages.
            myReceiver.AttachDuplexInputChannel(anInputChannel);

            Console.WriteLine("The service is running. To stop press enter.");
            Console.ReadLine();

            // Detach the input channel and stop listening.
            // It releases the thread listening to messages.
            myReceiver.DetachDuplexInputChannel();
        }

        // It is called when a message is received.
        private static void OnMessageReceived(object sender, 
              TypedRequestReceivedEventArgs<MyRequest> e)
        {
            Console.WriteLine("Received: " + e.RequestMessage.Text);

            // Create the response message.
            MyResponse aResponse = new MyResponse();
            aResponse.Length = e.RequestMessage.Text.Length;

            // Send the response message back to the client.
            myReceiver.SendResponseMessage(e.ResponseReceiverId, aResponse);
        }
    }
}

And here are applications communicating together:

340714/AndroidCommunicatesWithNetUI.jpg

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Slovakia Slovakia
My programming path started in 1987 when I got my first computer Sharp MZ-800.
It came with 8 bit CPU Z80, 64Kb RAM and the tape recorder. It was a great machine. I think I still have it somewhere.
I was fascinated and I started to write first programs. Eventually I became developer and software architect. I like innovations and clean nice solutions.

Comments and Discussions

 
AnswerRe: If it support binary streams? Pin
Ondrej_Uzovic20-Jun-13 9:04
Ondrej_Uzovic20-Jun-13 9:04 
GeneralRe: If it support binary streams? Pin
iJam_j27-Nov-13 23:42
iJam_j27-Nov-13 23:42 
GeneralRe: If it support binary streams? Pin
Ondrej_Uzovic28-Nov-13 7:33
Ondrej_Uzovic28-Nov-13 7:33 
QuestionAdding security Pin
Cory Shirts7-Jun-13 9:43
Cory Shirts7-Jun-13 9:43 
AnswerRe: Adding security Pin
Ondrej_Uzovic9-Jun-13 9:38
Ondrej_Uzovic9-Jun-13 9:38 
GeneralRe: Adding security Pin
Cory Shirts10-Jun-13 6:14
Cory Shirts10-Jun-13 6:14 
GeneralThank You Pin
Bobbydoo816-May-13 3:34
Bobbydoo816-May-13 3:34 
QuestionHow to send data from android application to .net web site Pin
Member 986794023-Mar-13 21:05
Member 986794023-Mar-13 21:05 
Hello Sir,
I developed one android application it sends data(username,password) to .net website.
But finding some difficulty in .net webservices. How .net werservices takes data and store into sql server database.Please explain or give some snippets of .net webservices that store data into sql server database which is coming from my android application.

my android code:

package com.example.webservicecalldemo;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {

	private ProgressDialog pd;

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

		pd = new ProgressDialog(this);
	}

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

	/**
	 * This method listens click event for Call Webservice button
	 * TODO: check onClick attribute of button in layout file
	 * @param v
	 */
	public void callWebserviceClick(View v) {
		// Dummy username/password, just to show a demo
		String username = "testuser";
		String password = "testuser";
		
		new DemoWebserviceTask().execute(username, password);
	}

	/*
	 * TODO: Please read about AsyncTask, it is very very useful class in Android
	 */
	private class DemoWebserviceTask extends AsyncTask<String, Void, String> {
		
		@Override
		protected void onPreExecute() {
			pd.setMessage("Please wait....");
			pd.show();
		}

		@Override
		protected String doInBackground(String... params) {
			
			// params come from execute() method of AsyncTask
			String username = params[0];	// testuser
			String password = params[1];	// testuser

			HttpClient httpclient = new DefaultHttpClient();
			// *******************************************************
			// Don't use localhost or 127.0.0.1 to call web-service
			// Reason: localhost or 127.0.0.1 becomes loopback address of device
			// itself.
			// *******************************************************
			// HttpPost httppost = new HttpPost("http://localhost:8425/enterdata/Service1.asmx");

			// *******************************************************
			// Use host address if your web-services are hosted on any server
			// OR use IP address of your machine for testing purpose
			// TODO: Replace 192.168.0.200 with your server IP address 
			// *******************************************************
			HttpPost httppost = new HttpPost("http://localhost:18747/new/uspassWebService.asmx");
			
			ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("username", username));
            nameValuePairs.add(new BasicNameValuePair("password", password));
            try {
				httppost.setEntity((HttpEntity) new UrlEncodedFormEntity(nameValuePairs));
				HttpResponse httpResponse = httpclient.execute(httppost);
				
				if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					HttpEntity entity = httpResponse.getEntity();
					String result = EntityUtils.toString(entity);
					return result;
				} else {
					return null;
				}
				
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			pd.dismiss();
			
			if(result == null) {
				// Show alert message to user because there is some problem in webservice call
				// You didn't get proper result from server.
				pd.setMessage("sending data failed");
				pd.show();
				
				return;
			}
			
			Log.d("Web-service-result", result);
			// Now you can play with your result
			// Enjoy, you get successful response from your web-service
		}
	}
}



Thanks.
AnswerRe: How to send data from android application to .net web site Pin
Ondrej_Uzovic24-Mar-13 0:09
Ondrej_Uzovic24-Mar-13 0:09 
GeneralVery helpful Pin
Bandi Ramesh16-Feb-13 0:03
Bandi Ramesh16-Feb-13 0:03 
QuestionUsing it over the internet instead of locally? Pin
Master_T7-Jan-13 4:55
Master_T7-Jan-13 4:55 
AnswerRe: Using it over the internet instead of locally? Pin
Ondrej_Uzovic20-Jan-13 22:31
Ondrej_Uzovic20-Jan-13 22:31 
AnswerRe: Using it over the internet instead of locally? Pin
Renaud Gauthier12-Mar-13 6:09
Renaud Gauthier12-Mar-13 6:09 
GeneralMy vote of 5 Pin
WebMaster3-Jan-13 18:55
WebMaster3-Jan-13 18:55 
GeneralMy vote of 5 Pin
Member 952628628-Dec-12 7:40
Member 952628628-Dec-12 7:40 
QuestionI use simulator,but does not work. Pin
Member 952628628-Dec-12 7:39
Member 952628628-Dec-12 7:39 
AnswerRe: I use simulator,but does not work. Pin
Ondrej_Uzovic31-Dec-12 23:19
Ondrej_Uzovic31-Dec-12 23:19 
GeneralMy vote of 5 Pin
Serguei_Ko13-Dec-12 22:10
Serguei_Ko13-Dec-12 22:10 
GeneralMy vote of 5 Pin
christoph brändle11-Dec-12 23:21
christoph brändle11-Dec-12 23:21 
GeneralMy vote of 5 Pin
URVISH_SUTHAR19-Dec-12 20:29
URVISH_SUTHAR19-Dec-12 20:29 
QuestionLaunch in Android SDK Pin
BOWLINGBALL4-Dec-12 11:44
BOWLINGBALL4-Dec-12 11:44 
AnswerRe: Launch in Android SDK Pin
Ondrej_Uzovic5-Dec-12 8:36
Ondrej_Uzovic5-Dec-12 8:36 
GeneralRe: Launch in Android SDK Pin
BOWLINGBALL7-Dec-12 7:27
BOWLINGBALL7-Dec-12 7:27 
GeneralRe: Launch in Android SDK Pin
Ondrej_Uzovic8-Dec-12 8:54
Ondrej_Uzovic8-Dec-12 8:54 
GeneralRe: Launch in Android SDK Pin
BOWLINGBALL7-Dec-12 11:22
BOWLINGBALL7-Dec-12 11:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.