Skip to content

October 15, 2010

46

Android USB connection to PC

Back a while ago I wrote a post regarding USB cable communication between an Android smartphone and the host machine. I promised some code back then, but forgot to put it. Here is some sample code now.

1a. To enable this to work, the host computer must do what is called port forwarding. The Android debug bridge has this all figured out, you just need to execute the command. What it does, if it executes successfully, is forward all communication targeting localhost on the specified port to the smartphone at the specified port. So, after this, to get a connection, all you have to do is connect to “localhost” on that port you wrote there.

C:\android-sdk-windows\tools\adb.exe forward tcp:38300 tcp:38300

Note: the ports do not have to be the same, I just used the same port for convenience; also you can use any port that will work, the numbers are not special in anyway.

1b. You can also run this directly from your program. Here’s an example of how to do it:

/**
* Runs the android debug bridge command of forwarding the ports
*
*/
private void execAdb() {
// run the adb bridge
try {
Process p=Runtime.getRuntime().exec("C:\\android-sdk-windows\\tools\\adb.exe forward tcp:38300 tcp:38300");
Scanner sc = new Scanner(p.getErrorStream());
if (sc.hasNext()) {
while (sc.hasNext()) System.out.println(sc.next());
Print.fatalError("Cannot start the Android debug bridge");
}
} catch (Exception e) {
Print.fatalError(e.toString());
}
}

2. The server socket needs to be on the smartphone. Not exactly sure why that is, but I couldn’t get this thing to work when it was on the host. My guess is that it has something to do with the way port forwarding works.
Also, it’s usually a good idea to put this part on a separate thread so it doesn’t lock up your UI. The Android tutorial talks more about that in UI design so I won’t.
The sample code that follows does two things. First, it creates a server socket to listen for connections. Second, it actually waits for a connection to be established. It then announces this and goes on to the next class. If in 10 seconds no connection occurs, it times out and stops trying.

NOTE: the following code will not run by itself, because the UI is in an XML file that’s not included, but it should give you a pretty good idea of what the phone code should look like; other than the UI it’s all the code you need.


public class Connection extends Activity implements OnClickListener {

public static final String TAG=”Connection”;
public static final int TIMEOUT=10;
Intent i=null;
TextView tv=null;
private String connectionStatus=null;
private Handler mHandler=null;
ServerSocket server=null;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.connection);

//Set up click listeners for the buttons
View connectButton = findViewById(R.id.connect_button);
connectButton.setOnClickListener(this);

i = new Intent(this, Connected.class);
mHandler=new Handler();
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.connect_button:
tv = (TextView) findViewById(R.id.connection_text);
//initialize server socket in a new separate thread
new Thread(initializeConnection).start();
String msg=”Attempting to connect…”;
Toast.makeText(Connection.this, msg, msg.length()).show();
break;
}
}

private Runnable initializeConnection = new Thread() {
public void run() {

Socket client=null;
// initialize server socket
try{
server = new ServerSocket(38300);
server.setSoTimeout(TIMEOUT*1000);

//attempt to ccept a connection
client = server.accept();
Globals.socketIn=new Scanner(client.getInputStream());
Globals.socketOut = new PrintWriter(client.getOutputStream(), true);
} catch (SocketTimeoutException e) {
// print out TIMEOUT
connectionStatus=”Connection has timed out! Please try again”;
mHandler.post(showConnectionStatus);
} catch (IOException e) {
Log.e(TAG, “”+e);
} finally {
//close the server socket
try {
if (server!=null)
server.close();
} catch (IOException ec) {
Log.e(TAG, “Cannot close server socket”+ec);
}
}

if (client!=null) {
Globals.connected=true;
// print out success
connectionStatus=”Connection was succesful!”;
mHandler.post(showConnectionStatus);

startActivity(i);
}
}
};

/**
* Pops up a “toast” to indicate the connection status
*/
private Runnable showConnectionStatus = new Runnable() {
public void run() {
Toast.makeText(Connection.this, connectionStatus, Toast.LENGTH_SHORT).show();
}
};
}

 

3. The host machine application will then obviously implement a client socket. I use a PrintWriter to write stuff to the output stream and a Scanner to parse what’s coming through the input stream. Obviously there are many other ways to handle this.
Here’s the code I used:


/**
* Initialize connection to the phone
*
*/
public void initializeConnection(){
//Create socket connection
try{
socket = new Socket("localhost", 38300);
out = new PrintWriter(socket.getOutputStream(), true);
//in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
sc=new Scanner(socket.getInputStream());

// add a shutdown hook to close the socket if system crashes or exists unexpectedly
Thread closeSocketOnShutdown = new Thread() {
public void run() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Runtime.getRuntime().addShutdownHook(closeSocketOnShutdown);
} catch (UnknownHostException e) {
Print.fatalError(“Socket connection problem (Unknown host)”+e.getStackTrace());
} catch (IOException e) {
Print.fatalError(“Could not initialize I/O on socket “+e.getStackTrace());
}
}

4. Putting it all together
So, this is what you have to do (in this order).
- The adb port forwarding command must run on the host computer
- The Android application needs to run, setup a server socket on localhost (on the 2nd port used in the adb command) and then wait to get a connection
- The host computer needs to open up a client socket on localhost (on the 1st port used in the adb command) and connect to the Android phone
- Done! Communicate over sockets as usual.

Hope it’s useful to someone out there! If you have problems trying to get this code working, let me know in the comments and I’ll help you out. When I have time, I will try to actually make two small programs that demonstrate the behavior, but it might be a while before I can do that, life has been very busy lately.

46 Comments Post a comment
  1. Carl
    Nov 18 2010

    Thanks for this post. I am a novice programmer. I get errors in
    these statements – “Globals cannot be resolved..”

    Globals.socketIn=new Scanner(client.getInputStream());
    Globals.socketOut = new PrintWriter(client.getOutputStream(), true);
    …..
    Globals.connected=true;

    please can you help me out.

  2. Nov 18 2010

    Hi Carl,

    As I said, that sample code above is for illustration only, it will not run by itself because I copied it out of a larger project.

    In my project Globals is a class which contains a bunch of global variables, that’s all. Go ahead and remove “Globals.” from all of these and just declare them in your program.
    Scanner socketIn; PrintWriter socketOut; boolean connected;

    Let me know if you need more help.
    If I have time I will write a sample project that you can actually download and run to show how this works.

    GL!
    a.

  3. Carl
    Nov 18 2010

    Thank you anothem..I’ll try it and let you know.

  4. Carl
    Nov 19 2010

    Thanks so much. It works! :)

    now, that the communication of the pc with the smartphone is established. I’m trying to get a program to send commands to the smartphone, like click events on a specific positions, etc., Any ideas ?

    Thanks again..

  5. Nov 20 2010

    Np, I’m happy you got it working.

    I can’t help you too much with what you’re trying to do there, but I wrote a post about a tool for showing the Android screen just this week (and I think it allows some control as well).

    The tool is open source so maybe you want to check it out and see how they solve some of these problems and get some ideas.

    Best,
    -a.

  6. laxman
    Nov 26 2010

    Hi,
    Its look it will help to me. But i want to do pcsync in android through USB with obex. If you have any stuff please help to me.

    Thanks
    Laxman Dodda

  7. Nov 26 2010

    Starting with 2.1 Android supports obex, but that’s all I know about that, haven’t worked with it at all.

  8. laxman dodda
    Dec 7 2010

    Hi,
    Can you help to me. How to establish a connection between pc (pcsuite) and target (mobile) in windows environment. Through program. It will be good help. Above is good to me to understand. Please mail a sample program to me.

    Regards
    Laxman Dodda

  9. Andrea
    Jan 11 2011

    thanks for that post. Do you think is possibile to connect via USB an android device with another device that is not a pc with your code?
    thanks in advance,
    Andrea.

  10. Jan 11 2011

    Well, the way it is here I’m using adb to enable communication so you need a computer running adb and able to execute the commands for it. I can’t see how this could be used with another device and there are probably better ways to solve that specific problem.

    Thanks.

  11. Andrea
    Jan 12 2011

    thanks for your answer. do you have any suggestion? any keyword for a google search?
    thanks again

  12. li
    Feb 13 2011

    i wrote the code like yours ,but there is error,permission deny.
    Runtime.getRuntime().exec(“adb forward tcp:38300 tcp:38300″);

    why? should xml add some permission?

  13. Feb 13 2011

    li, you might have things confused. The adb runs on the host machine, not on the smartphone.

  14. Manoj
    May 5 2011

    Hi Anothem,

    I got the below exception which I couldnt resolve it…

    05-07 20:55:05.079: WARN/System.err(5298): java.io.IOException: Error running exec(). Command: [E:\gingerBread\android-sdk-windows\tools\adb.exe, forward, tcp:5037, tcp:38300] Working Directory: null Environment: null
    05-07 20:55:05.079: WARN/System.err(5298): at java.lang.ProcessManager.exec(ProcessManager.java:226)
    05-07 20:55:05.079: WARN/System.err(5298): at java.lang.Runtime.exec(Runtime.java:196)
    05-07 20:55:05.079: WARN/System.err(5298): at java.lang.Runtime.exec(Runtime.java:285)
    05-07 20:55:05.079: WARN/System.err(5298): at java.lang.Runtime.exec(Runtime.java:218)
    05-07 20:55:05.079: WARN/System.err(5298): at com.adb.test.ADBTest.execAdb(ADBTest.java:28)
    05-07 20:55:05.079: WARN/System.err(5298): at com.adb.test.ADBTest.access$0(ADBTest.java:25)
    05-07 20:55:05.079: WARN/System.err(5298): at com.adb.test.ADBTest$1.run(ADBTest.java:18)
    05-07 20:55:05.079: WARN/System.err(5298): at java.lang.Thread.run(Thread.java:1096)
    05-07 20:55:05.079: WARN/System.err(5298): Caused by: java.io.IOException: Permission denied
    05-07 20:55:05.079: WARN/System.err(5298): at java.lang.ProcessManager.exec(Native Method)
    05-07 20:55:05.079: WARN/System.err(5298): at java.lang.ProcessManager.exec(ProcessManager.java:224)
    05-07 20:55:05.079: WARN/System.err(5298): … 7 more

    Please suggest me some solution for it..

    Thanks,
    Manoj.

  15. May 5 2011

    Sounds like you have some problems running exec. Try and see if you can run other programs using that command. Also, there shouldn’t be any commas in the command, it would appear from your error that you have that.

    GL!

  16. Manoj
    May 6 2011

    Hi Anothem,

    thanks for your reply.

    I am trying to write and adroid app which takes the logs…Something like…
    in an activity…
    I want to run the \”adb logcat\” and want to show it on the textbox. this is what I am trying…any suggestions?

  17. Nicholas
    Jun 13 2011

    Thanks Anothem,

    Just what I was looking for… :)

  18. Jun 14 2011

    Thanks Nicholas, glad to help.

  19. Aug 8 2011

    Hello Anothem,

    Would it be possible to establish the usb connection and then run telnet commands back to the pc from the phone? Say if you had a telnet daemon running on specified port on the PC?

  20. Aug 9 2011

    Hi Scott,

    I haven’t tried it, but I don’t see any reason why it couldn’t be done.

    –a.

  21. Sep 6 2011

    Hi Anothem,

    Thanks for your solution.

  22. Seba
    Nov 1 2011

    Great example, it helped me understand several pieces together

  23. Chetan Nanda
    Dec 22 2011

    Great, work for me also.
    We must create server port on Android device reason for this is, we have to use ‘adb forward … ‘ command.

    After using this command window can’not bind to same port which is needed for any server.

  24. dj
    Feb 8 2012

    hi anothem,
    can we implement a simple server program in C on android phone cross-compiled for ARM platform in your example? client program is also a C program running on windows PC.
    can we do client server communication now after port forwarding through ADB?

  25. Feb 9 2012

    Hi dj,

    I can’t say for certain what the answer to your question is, because I haven’t done any work with native apps on Android. From what I know of ADB you should be able to leverage it from native apps as well, but that’s something you’ll have to look into.

    I’m curious about it, so I’ll do some research into it when I get a chance and I’ll let you know if I find out anything.

    Alex

  26. dj
    Feb 11 2012

    Hi Alex,
    Thanks a lot for your reply.:)i will also try along this line and get back here if i succeed..As far as i tried till now its a failure..i dono what im missing in running the server c code in android OS.

  27. Mahi
    Mar 2 2012

    Hi dj,

    I trying to implement same kind of sever client program in c for android,I hope by this time you might have good command over this topic! Can you share your code in this blog? this would be really great helpful for me move future.

  28. sasa
    Apr 13 2012

    hi anothem,

    nice post. finnaly i found example code to connect android USB to pc. but i’m still confused. i have to try and i get some bug. can you give me your source code? please.
    thanks before

  29. Apr 13 2012

    sasa, check out this post: http://www.anothem.net/archives/2011/11/22/with-our-powers-combined-sample-code/
    There’s an external link there to a sample project using these concepts.

  30. sasa
    Apr 17 2012

    can this source code to using send character to windows hyperterminal?

  31. Apr 17 2012

    sasa, I’m not familiar with the hyperterminal. But all this code is showing is how to set up a simple socket connection. You can leverage this to implement other communication protocols if you need to.

  32. dj
    Apr 23 2012

    Hi Mahi,
    sorry dint see ur post..normal windows based client C code and server C code in linux worked for me in this regard.
    i got the server code from this site
    http://www.tidytutorials.com/2010/06/linux-c-socket-example-with-client.html
    and cross compiled it for ARM processor.i think this should help

  33. nshah
    Apr 24 2012

    Great post and information. Worked for me.
    Thanks a Lot!!

  34. Naresh
    Jun 26 2012

    Thank you very much Alex.

  35. Bazil
    Sep 3 2012

    Hi, I have found your post very helpful. I need to know the following: I want to build an app that will run on PC and will show the android sensors’ readings on the PC. Is it possible?

    Thanks

  36. Sep 3 2012

    Thanks Bazil!

    It can definitely be done if you have both an Android app (or service maybe?) and a PC app running at the same time, with a connection similar to what I was doing.

    Not sure if there’s anyway to leverage adb for this and do what you want without running an app at the same time. I believe not though.

  37. Ashwini
    Sep 12 2012

    Very good explaination I have ever seen. Got a clear picture of how port forwarding works ! Thanks a lot !!

  38. john Smith
    Oct 29 2012

    Great sample. Thank you!

    You need to add the required permission on the manifest to be able to run your sample.

    <manifest xmlns:android="http://sc

  39. john Smith
    Oct 29 2012
  40. Shammu Shaa
    Dec 23 2013

    Hello Sir,
    I am new for android. i trying for data transfer between computer and mobile phone via USB cable.
    Communication can be done two way:
    1) The first way is Socket,Protocol so like
    2) The Second way is Using USB functions
    ie, can be take example for in android USB HOST and USB Accessory Methods and in JAVA can also have JAVA HOST methods.
    Please sir,If you will have this code means send me sir,otherwise give some ideas and techniques of code..
    thank you sir…

  41. Rohit
    Jan 7 2014

    Hi Anothem,

    I am a B.Tech student. I am working on my “Major Project”. I have to connect java app on PC with android app on Mobile. Your app seems to be very helpful. But, I have some doubts regarding adb usage. If I use the same method as you explained here, will my java app on PC run on others PCs too. Because adb has to be there on PC for this method to work. am I right ?

    Please point me in a right way so that I can proceed with my project…

    Thanks in advance…

  42. Jan 7 2014

    Hi Rohit — Yes, the PC you’re running this on must have adb installed, of course, but I don’t see that as a deal breaker.

    I would just mention that as a requirement and allow my java application to be configured by the user with the path to the android sdk installation. As a matter of fact, that’s what I did for my senior project when I used this and is similar to what commercial software will do for things like this (e.g. your IDE probably did the same).

    Whether you can do the same is something I can’t advise you on, it obviously depends on your project requirements and what your professor advises, but it seems reasonable to me.

    Hope that helps! Good luck with your project!
    Alex

  43. RY
    Mar 5 2014

    I am new to Android and java programming. Can anyone guide me to resolve the last three compile errors as below?

    Connected cannot be resolved to a type. (what is “Connected.class”?)

    The method onClick(View) of type Connection must override or implement a supertype method

    The method setOnClickListener(View.OnClickListener) in the type View is not applicable for the arguments (Connection)

  44. AndroidPower
    Mar 13 2014

    Thank you very much, Alex!

    You posted this almost 3 and a half year ago. And your stuff is still helping someone like me to control a service from a pc for automation of just everything.

    And it still works. After 1.5 hours I can connect from windows shell with telnet to my service running at an android device, and send messages there.

    We will use this in an automated environment, where an android smartphone is permanently connected with a windows pc. We already use MonkeyRuner for automation, but we also need to control background services in parallel.

    Thanks again

Trackbacks & Pingbacks

  1. Communicating over the USB cable | Seconds & pixels
  2. Best way to connect a Microchip card to Android Tablet

Share your thoughts, post a comment.

(required)
(required)

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments

Current day month ye@r *