Use Android As Mouse – C#.NET – Android 2.0

By | February 28, 2011

After my last post about .NET – Android, I was pretty excited about the possibilities. Therefore, I decided to create a new little “useful” app for my phone.
If your mouse batteries are low and you have to finish something, you can use your phone as a mouse.

How it works on Android:
I created an app which captures the movements on the screen and sends the positions over a socket (UDP) to my PC. My “protocol” supports following commands:

d.click Sending a double click. (Not really necessary.)
click Sending a click. (2x “click” => same as d.click.)
x,y Sending delta x and y. 0,1 or 1,0 etc.
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    	super.onTouchEvent(event);
    	switch(event.getAction()) {
	    	case MotionEvent.ACTION_DOWN: {
	    		final float x = event.getX();
	    		final float y = event.getY();
	    		// last position
	    		this.lastX = x;
	    		this.lastY = y;
	    		// first position
	    		this.firstX = x;
	    		this.firstY = y;
	    		// click time
	    		this.clickDown = new Date();
	    		break;
	    	}
	    	case MotionEvent.ACTION_MOVE: {
	    		// new position
	    		final float x = event.getX();
	    		final float y = event.getY();
	    		
	    		//  get delta
	    		final float deltax = x - this.lastX;
	    		final float deltay = y - this.lastY;
	    		// set last position
	    		this.lastX = x;
	    		this.lastY = y;
	    			    		
				try {
					// prepare message -> x,y
					byte[] message = (deltax + "," + deltay).getBytes("UTF-8");
					// package definition. ip of pc and port.
					this.packet = new DatagramPacket(message, message.length, 
							InetAddress.getByName("192.168.0.150"), 8000);
					// send package
					this.socket.send(this.packet);
				} catch(Throwable e) {
					e.printStackTrace();
				}
	    		break;
	    	}
	    	
	    	case MotionEvent.ACTION_UP: {
	    		// get current position
	    		final float x = event.getX();
	    		final float y = event.getY();
	    		// get delta
	    		final float deltaX = this.firstX - x;
	    		final float deltaY = this.firstY - y;
	    		
	    		Date now = new Date();
	    		byte[] message = null;
	    		
	    		try {
	    			// when the users clicks and holds over 1 second send a double click to the pc.
		    		if (deltaX < this.tolerance[0] && 
	    				deltaX > this.tolerance[1] &&
	    				deltaY < this.tolerance[0] &&
	    				deltaY > this.tolerance[1] &&
	    				now.getTime() - this.clickDown.getTime() >= 1000) {
		    			message = ("d.click").getBytes("UTF-8");
	    			// When the users clicks (not holding) send a normal click to the pc.
		    		} else if (x == this.firstX && y == this.firstY) {
		    			message = ("click").getBytes("UTF-8");
		    		}
		    		if (message != null) {
		    			// prepare and send package -> d.click or click
		    			this.packet = new DatagramPacket(message, message.length, InetAddress.getByName("192.168.0.150"), 8000);
						this.socket.send(this.packet);	
		    		}
				} catch (Throwable e) {
					e.printStackTrace();
	    		}
	    		break;
	    	}
    	}
    	return true;
    }

Application on the PC:
I created an application, which receives the packages and sets the cursor position on the PC:

public partial class MainWindow : Window
{
    // Dll import. -> method mouse_move
    [DllImport("user32.dll")]
    static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

    private EndPoint point;
    private Socket receiveSocket;
    private byte[] recBuffer;
    private int speed = 2;

    // Flags for mouse_event api
    [Flags]
    public enum MouseEventFlagsAPI
    {
        LEFTDOWN = 0x00000002,
        LEFTUP = 0x00000004,
        MIDDLEDOWN = 0x00000020,
        MIDDLEUP = 0x00000040,
        MOVE = 0x00000001,
        ABSOLUTE = 0x00008000,
        RIGHTDOWN = 0x00000008,
        RIGHTUP = 0x00000010
    }

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // initilization and listening
        receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            point = new IPEndPoint(IPAddress.Any, 8000);
        this.recBuffer = new byte[60];
        receiveSocket.Bind(point);
        receiveSocket.BeginReceiveFrom(recBuffer, 0, recBuffer.Length, 
            SocketFlags.None, ref point, 
            new AsyncCallback(MessageReceiveCallback), (object)this);
            
    }
    private void SendClick()
    {
        // Send click to system
        mouse_event((int)MouseEventFlagsAPI.LEFTDOWN, 0, 0, 0, 0);
        mouse_event((int)MouseEventFlagsAPI.LEFTUP, 0, 0, 0, 0);
    }
    private void MessageReceiveCallback(IAsyncResult result)
    {
        EndPoint remote = new IPEndPoint(0, 0);
        string pos = "";

        try
        {
            // get received message.
            pos = Encoding.UTF8.GetString(recBuffer);

            // clicked?
            if (pos.StartsWith("click"))
                this.SendClick();
            // long click = double click
            else if (pos.StartsWith("d.click"))
            {
                this.SendClick();
                this.SendClick();
            }
            // Otherwise move
            else
            {
                // calculate delta
                int deltaX = (int)float.Parse(pos.Substring(0, pos.IndexOf(","))) * this.speed;
                int deltaY = (int)float.Parse(pos.Substring(pos.IndexOf(",") + 1, 
                    pos.IndexOf("\0") + 1 - pos.IndexOf(",") + 1)) * this.speed;

                // set new point
                System.Drawing.Point pt = System.Windows.Forms.Cursor.Position;
                System.Windows.Forms.Cursor.Position = new System.Drawing.Point(pt.X + deltaX, pt.Y + deltaY);
            }
        }
        catch (Exception)
        {
            Console.Write(pos);
        }
        // End and "begin" for next package
        this.receiveSocket.EndReceiveFrom(result, ref remote);
        receiveSocket.BeginReceiveFrom(recBuffer, 0, recBuffer.Length, 
            SocketFlags.None, ref point, 
            new AsyncCallback(MessageReceiveCallback), (object)this);
    }
}

Watch the video! 😉

The C# source code is here
The Java source code is here