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