How to send a message from Android to Windows using USB
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();}@Overridepublic 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(); } }}; } }
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);