Click or drag to resize

AndroidUsbCableMessagingFactory Class

Messaging system interacting with an Android device via the USB cable.
Inheritance Hierarchy
SystemObject
  Eneter.Messaging.MessagingSystems.AndroidUsbCableMessagingSystemAndroidUsbCableMessagingFactory

Namespace:  Eneter.Messaging.MessagingSystems.AndroidUsbCableMessagingSystem
Assembly:  Eneter.Messaging.Framework (in Eneter.Messaging.Framework.dll) Version: 8.0.0.0 (8.0.0.0)
Syntax
public class AndroidUsbCableMessagingFactory : IMessagingSystemFactory

The AndroidUsbCableMessagingFactory type exposes the following members.

Constructors
  NameDescription
Public methodAndroidUsbCableMessagingFactory
Constructs the messaging which communicates with Android via the USB cable.
Public methodAndroidUsbCableMessagingFactory(Int32, IProtocolFormatter)
Constructs the messaging which communicates with Android via the USB cable.
Top
Properties
  NameDescription
Public propertyConnectTimeout
Sets ot gets timeout to open the connection.
Public propertyOutputChannelThreading
Sets or gets threading mode for output channels.
Public propertyReceiveBufferSize
Size of the buffer in bytes for receiving messages. Default value is 8192 bytes.
Public propertyReceiveTimeout
Sets or gets timeout to receive a message.
Public propertySendBufferSize
Size of the buffer in bytes for sending messages. Default value is 8192 bytes.
Public propertySendTimeout
Sets or gets timeout to send a message.
Top
Methods
  NameDescription
Public methodCreateDuplexInputChannel
Not supported. The known restriction is that Android cannot be client. Therefore, .NET or Java application running on PC cannot be a service using the duplex input chanel for listening. :-(
Public methodCreateDuplexOutputChannel(String)
Creates duplex output channel which can send and receive messages from the duplex input channel using Android USB cable.
Public methodCreateDuplexOutputChannel(String, String)
Creates duplex output channel which can send and receive messages from the duplex input channel using Android USB cable.
Public methodEquals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Protected methodFinalize
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object.)
Public methodGetHashCode
Serves as the default hash function.
(Inherited from Object.)
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Top
Remarks
When Android device is connected to the computer via the USB cable the process adb (Android Debug Bridge) is started on the computer and adbd (Android Debug Bridge Daemon) is started on the Android device. These processes then communicate via the USB cable.

How this messaging works:
  1. Your desktop application sends a message via the output channel created by AndroidUsbCableMessagingFactory
  2. The output channel internally sends the message via TCP to the adb service.
  3. adb service receives data and transfers it via USB cable to adbd.
  4. adbd in the Android device receives data and forwards it via TCP to the desired port.
  5. Android application listening on that port receives the message and processes it.
Notice there is a restrction for this type of communication:
The Android application must be a listener (service) and the computer application must be the client.
Examples
The service on the android side. (implemented in Java)
package eneter.testing;

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;

public class AndroidUsbCableServiceActivity extends Activity
{
    // Eneter communication.
    private IDuplexTypedMessageReceiver<String, String> myEchoReceiver;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Start listening.
        startListening();
    }

    @Override
    public void onDestroy()
    {
        stopListening();

        super.onDestroy();
    }

    private void startListening()
    {
        try
        {
            // Create message receiver.
            IDuplexTypedMessagesFactory aReceiverFactory = new DuplexTypedMessagesFactory();
            myEchoReceiver = aReceiverFactory.createDuplexTypedMessageReceiver(String.class, String.class);

            // Subscribe to receive messages.
            myEchoReceiver.messageReceived().subscribe(new EventHandler<TypedRequestReceivedEventArgs<String>>()
                {
                    @Override
                    public void onEvent(Object sender, TypedRequestReceivedEventArgs<String> e)
                    {
                        // Response back with the same message.
                        try
                        {
                            myEchoReceiver.sendResponseMessage(e.getResponseReceiverId(), e.getRequestMessage());
                        }
                        catch (Exception err)
                        {
                            EneterTrace.error("Sending echo response failed.", err);
                        }
                    }
                });

            // Create TCP messaging.
            // It must listen to IP address 127.0.0.1. You can set desired port e.g. 8090.
            IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
            IDuplexInputChannel anInputChannel = aMessaging.createDuplexInputChannel("tcp://127.0.0.1:8090/");

            // Attach the input channel to the receiver and start listening.
            myEchoReceiver.attachDuplexInputChannel(anInputChannel);
        }
        catch (Exception err)
        {
            EneterTrace.error("OpenConnection failed.", err);
        }
    }

    private void stopListening()
    {
        // Detach input channel and stop listening.
        myEchoReceiver.detachDuplexInputChannel();
    }
}
Examples
The client application communicating with the Android application via the USB cable.
using System;
using System.Windows.Forms;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.AndroidUsbCableMessagingSystem;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;

namespace AndroidEchoClient
{
    public partial class Form1 : Form
    {
        private IDuplexTypedMessageSender<string, string> myEchoSender;

        public Form1()
        {
            InitializeComponent();

            // Echo sender-receiver
            IDuplexTypedMessagesFactory aSenderFactory = new DuplexTypedMessagesFactory();
            myEchoSender = aSenderFactory.CreateDuplexTypedMessageSender<string, string>();

            // Subscribe to get the response.
            myEchoSender.ResponseReceived += OnResponseReceived;

            // Create messaging using the USB cable connected to Android device.
            IMessagingSystemFactory aMessaging = new AndroidUsbCableMessagingFactory();

            // Create output channel.
            // It sets the Android application listens to port 8090.
            IDuplexOutputChannel anOutputChannel = aMessaging.CreateDuplexOutputChannel("8090");
            myEchoSender.AttachDuplexOutputChannel(anOutputChannel);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            myEchoSender.DetachDuplexOutputChannel();
        }

        private void SendBtn_Click(object sender, EventArgs e)
        {
            // Send the message.
            myEchoSender.SendRequestMessage(TextMessageTextBox.Text);
        }

        private void OnResponseReceived(object sender, TypedResponseReceivedEventArgs<string> e)
        {
            // This is not the UI thread, so
            // route displaying to the main UI thread.
            if (InvokeRequired)
            {
                Action aUIUpdate = () => ResponseLabel.Text = e.ResponseMessage;
                Invoke(aUIUpdate);
            }
            else
            {
                ResponseLabel.Text = e.ResponseMessage;
            }
        }

    }
}
See Also