Friday, February 17, 2012

Configuring USB Linux Android Connection

Almost a year ago I sat in on an Android development seminar that Dr. Ralph Bunker was teaching here at MUM, and at that time I configured My Laptop (ubuntu) to be able to connect to my Nexus one and upload some of the sample applications I made.

Now, I'm trying to setup my desktop to also be able to connect and I ran into the problem where adb keeps on not listing my Nexus One as being connected, instead it gives me:

$ ./adb devices
List of devices attached
????????????    no permissions

Lets first look into my setup, to see if anything is wrong (spoiler: I mis-configured /etc/udev/rules.d/51-android.rules).

Basic Linux Android Development Setup

The basic setup is pretty easy as outlined on the android developer pages:
http://developer.android.com/sdk/index.html Which basically says:

  1. Prepare your development computer and ensure it meets the system requirements.
  2. Install the SDK starter package from the table above. (If you're on Windows, download the installer for help with the initial setup.)
  3. Install the ADT Plugin for Eclipse (if you'll be developing in Eclipse). where the following page can come in useful as well: http://developer.android.com/sdk/eclipse-adt.html#installing
  4. Add Android platforms and other components to your SDK.
  5. Explore the contents of the Android SDK (optional).
Connecting Devices under Linux

But this doesn't actually tell us anything about connecting real devices. Luckily android developer has a page for this as well: http://developer.android.com/guide/developing/device.html
 which tells us:

To set up device detection on Ubuntu Linux:
  1. Log in as root and create this file: /etc/udev/rules.d/51-android.rules. Use this format to add each vendor to the file:
    SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", MODE="0666", GROUP="plugdev"

    In this example, the vendor ID is for HTC. The MODE assignment specifies read/write permissions, and GROUP defines which Unix group owns the device node.
    Note: The rule syntax may vary slightly depending on your environment. Consult the udev documentation for your system as needed. For an overview of rule syntax, see this guide to writing udev rules.
  2. Now execute:
    chmod a+r /etc/udev/rules.d/51-android.rules
And the pages also gives you a list of usb Vendor IDs (where 18D1 is the id for my Google Nexus)... So far so good right? -- Oh, you may also want to execute:

sudo service udev reload

Just to be sure that the new rules are loaded into the the udev subsystem, although it seems to work without it as well.

So what did I do wrong?
  1. The thing I messed up on last time was that the vendorId that you take from the list (in my case 18d1) should replace the 0bb4 part in SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", MODE="0666", GROUP="plugdev"  Not the idVendor word! It seems really obvious now, but definitely had me stumped for a moment the first time I did it.
  2. The second issue I ran into just now is that while the list shows these vendorId as hexadecimal numbers with uppercase letters (18D1 for Google), the usb device driver is case sensitive and expects lowercase letters (18d1 instead of 18D1)!
Anyway, I figured it out after reading the following advice on stack overflow: http://stackoverflow.com/a/4079361 and executing the lsusb command which showed the device id with lowercase letters in the hex number.

It works!

But this post is a bit of a mess... Might as well throw in some additional random stuff:

In the past the android developer docs used to advice:
  SUBSYSTEM=="usb", SYSFS{idVendor}=="18d1", MODE="0666"
 
The docs currently say:
  SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="plugdev"

Both seem to work just fine.

No comments:

Post a Comment