How to send a message from Android to Windows using USB
Asked Answered
D

2

13

I am a complete noob at Android, only at the level of basic (1 or 2 line) Activities activated by buttons, but I would like to create a really simple app that, when I tap the app icon, it fires and forgets a message to a listening server on my Windows 8 PC. The phone is connected as a simple media device, without Kies, via a USB cable.

I can get as far as a message box lying and saying the message was sent. I need to know what kind of comms channel to use, e.g. a COM port or what, and how to send data over that from Android. On the Windows side, once I've established how to communicate, I can help myself.

Dingus answered 13/2, 2014 at 8:29 Comment(1)
Profk have get any idea for COM port commands or any code that android can use to send and recive data from windows.Arabesque
M
18

starting with the desktop side of this application: You can use the ADB (Android debug bridge) to establish a tcp/ip socket connection via port between the device and desktop. The command is :

adb forward tcp:<port-number> tcp:<port-number>

to run this command in your java program, you will have to create a process builder wherein this command ets executed on a child shell.

For windows you may need to use:

process=Runtime.getRuntime().exec("D:\\Android\\adt-bundle-windows-x86_64-20130729\\sdk\\platform-tools\\adb.exe forward tcp:38300 tcp:38300");
        sc = new Scanner(process.getErrorStream());
        if (sc.hasNext()) 
        {
            while (sc.hasNext()) 
                System.out.print(sc.next()+" ");
            System.out.println("\nCannot start the Android debug bridge");
        }
        sc.close();
        }

The function required to execute adb commands :

String[] commands = new String[]{"/bin/sh","-c", command};
        try {
            Process proc = new ProcessBuilder(commands).start();
            BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
            String s = null;
            while ((s = stdInput.readLine()) != null) 
            {
                sb.append(s);
                sb.append("\n");
            }
            while ((s = stdError.readLine()) != null) 
            {
                sb.append(s);
                sb.append("\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

Above method will take the above command as a string and execute it on a child shell

  //Extracting Device Id through ADB
    device_list=CommandExecutor.execute("adb devices").split("\\r?\\n");
    System.out.println(device_list);
    if(device_list.length>1)
    {
        if(device_list[1].matches(".*\\d.*"))
        {
            device_id=device_list[1].split("\\s+");
            device_name=""+CommandExecutor.execute("adb -s "+device_id[0]+" shell getprop ro.product.manufacturer")+CommandExecutor.execute("adb -s "+device_id[0]+" shell getprop ro.product.model");
            device_name=device_name.replaceAll("\\s+"," ");
            System.out.println("\n"+device_name+" : "+device_id[0]);
            device=device_id[0];
            System.out.println("\n"+device);

        }
        else
        {
            System.out.println("Please attach a device");

        }
    }
    else
    {
        System.out.println("Please attach a device");

    }

CommandExecutor is a class which has the execute method in it. The code of the execute method is the same as posted above. This will check if any device is connected and if it connected, it will return it unique id number.

It is preferable to use id number while executing adb commands like :

adb -s "+device_id[0]+" shell getprop ro.product.manufacturer 

OR

adb -s <put-id-here> shell getprop ro.product.manufacturer

Note that '-s' is necesarry after adb.

Then using adb forward commnd you need to establish a tcp/ip socket. Here the desktop will be the client and mobile/device will be the server.

//Create socket connection
    try{
        socket = new Socket("localhost", 38300);
        System.out.println("Socket Created");
        out = new PrintWriter(socket.getOutputStream(), true);
        out.println("Hey Server!\n");

        new Thread(readFromServer).start();
        Thread closeSocketOnShutdown = new Thread() {
            public void run() {
                try {
                    socket.close();
                } 
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        Runtime.getRuntime().addShutdownHook(closeSocketOnShutdown);
    } 
    catch (UnknownHostException e) {
        System.out.println("Socket connection problem (Unknown host)"+e.getStackTrace());
    } catch (IOException e) {
        System.out.println("Could not initialize I/O on socket "+e.getStackTrace());
    }

Then you need read from the server i.e. the device :

private Runnable readFromServer = new Runnable() {

    @Override
    public void run() {
try {
            System.out.println("Reading From Server");
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            while ((buffer=in.readLine())!=null) {
                System.out.println(buffer);
    }catch (IOException e) {
            try {
                in.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
    }

The 'buffer' will contain what device will send from its end of the app.

Now in your mobile application,you will need to open the same connection and siple write data to it out buffer

public class TcpConnection implements Runnable {

public static final int TIMEOUT=10;
private String connectionStatus=null;
private Handler mHandler;
private ServerSocket server=null; 
private Context context;
private Socket client=null;
private String line="";
BufferedReader socketIn;
PrintWriter socketOut;


public TcpConnection(Context c) {
    // TODO Auto-generated constructor stub
    context=c;
    mHandler=new Handler();
}

@Override
public void run() {
    // TODO Auto-generated method stub


    // initialize server socket
        try {
            server = new ServerSocket(38300);
            server.setSoTimeout(TIMEOUT*1000);
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        //attempt to accept a connection
            try{
                client = server.accept();

                socketOut = new PrintWriter(client.getOutputStream(), true);
                socketOut.println("Hey Client!\n");
                socketOut.flush();

                syncContacts();

                Thread readThread = new Thread(readFromClient);
                readThread.setPriority(Thread.MAX_PRIORITY);
                readThread.start();
                Log.e(TAG, "Sent");
            }
            catch (SocketTimeoutException e) {
                // print out TIMEOUT
                connectionStatus="Connection has timed out! Please try again";
                mHandler.post(showConnectionStatus);
                try {
                    server.close();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            } 
            catch (IOException e) {
                Log.e(TAG, ""+e);
            } 

            if (client!=null) {
                try{
                    // print out success
                    connectionStatus="Connection succesful!";
                    Log.e(TAG, connectionStatus);
                    mHandler.post(showConnectionStatus);
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }

}

private Runnable readFromClient = new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            Log.e(TAG, "Reading from server");
            socketIn=new BufferedReader(new InputStreamReader(client.getInputStream()));
            while ((line = socketIn.readLine()) != null) {
                Log.d("ServerActivity", line);
                //Do something with line
            }
            socketIn.close();
            closeAll();
            Log.e(TAG, "OUT OF WHILE");
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
};

public void closeAll() {
    // TODO Auto-generated method stub
    try {
        Log.e(TAG, "Closing All");
        socketOut.close();
        client.close();
        server.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
} 

private Runnable showConnectionStatus = new Runnable() {
    public void run() {
        try
        {
            Toast.makeText(context, connectionStatus, Toast.LENGTH_SHORT).show();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
};
   }
 }
Mendive answered 13/2, 2014 at 9:8 Comment(6)
Wow! Is all this necessary because of the USB, or can I not rather open a straight WLAN socket connection? Surely production apps don't use a debug bridge for networking? But thanks for all the detail.Dingus
I dont know about WLAN sockets..this is how I did it for my application.Mendive
I assume a sockets connection over a Wifi LAN are the same as those over a wired LAN.Dingus
Yes i checked and all this is necessary because the communication is happening through USB and for that we use ADB using Wifi lan sockets or even bluetooth connection will reduce the code by a great dealMendive
@NaveedAli the adb command "adb forward tcp:<port-number> tcp:<port-number>" is the command valueMendive
where is code for android app and windows java app?Particularity
H
3

Using Managed.adb in c#

AndroidDebugBridge bridge = AndroidDebugBridge.
CreateBridge(@"C:\Users\bla\AppData\Local\Android\Sdk\platform-tools\adb.exe", true); 

List<Device> devices = AdbHelper.Instance.
GetDevices(AndroidDebugBridge.SocketAddress); 

devices[0].CreateForward(38300, 38300); 

Then create a server socket on android to that port.

server = new ServerSocket(38300);
                server.setSoTimeout(TIMEOUT * 1000);
                socket = server.accept();

and client socket on C#

  TcpClient clientSocket = new System.Net.Sockets.TcpClient();
                clientSocket.Connect("127.0.0.1", 38300);
Hibernal answered 25/2, 2018 at 19:51 Comment(1)
How to get AndroidDebugBridgeAbel

© 2022 - 2024 — McMap. All rights reserved.