Wednesday, March 21, 2012

Selecting the adb device

How many times have your received an error message like this


error: more than one device and emulator


when you run the adb command ?


I guess many, if like me, you normally use several devices an emulators. When this happens, you should obtain the serial number using


$ adb devices


then cut & paste the desired serial number into the command line and run the desired command again. Imagine how much time is wasted if this occurs tens or even hundreds of times during your day.


Hopefully, Linux and Mac OSX (or perhaps Cygwin if you are using Windows) give you the power to change what you don't like, so the following scripts will transparently allow you to select a device from the list when there's more than one a it wasn't specified in the command line.


android-select-device
This script, which is called android-select-device, is the responsibly of prompting the user for the selection of the device.


#! /bin/bash
# selects an android device

PROGNAME=$(basename $0)
UNAME=$(uname)
DEVICE_OPT=
for opt in "$@"
do
   case "$opt" in
      -d|-e|-s)
         DEVICE_OPT=$opt
         ;;
   esac
done
[ -n "$DEVICE_OPT" ] && exit 0
DEV=$(adb devices 2>&1 | tail -n +2 | sed '/^$/d')
if [ -z "$DEV" ]
then
   echo "$PROGNAME: ERROR: There's no connected devices." >&2
   exit 1
fi
N=$(echo "$DEV" | wc -l | sed 's/ //g')

case $N in
1)
   # only one device detected
   D=$DEV
   ;;

*)
   # more than one device detected
   OLDIFS=$IFS
   IFS="
"
   PS3="Select the device to use, <Q> to quit: "
   select D in $DEV
   do
      [ "$REPLY" = 'q' -o "$REPLY" = 'Q' ] && exit 2
      [ -n "$D" ] && break
   done

   IFS=$OLDIFS
   ;;
esac

if [ -z "$D" ]
then
   echo "$PROGNAME: ERROR: target device coulnd't be determined" >&2
   exit 1
fi

# this didn't work on Darwin
# echo "-s ${D%% *}"
echo "-s $(echo ${D} | sed 's/ .*$//')"

my-adb
This is the other component of our solution. This script, which we are calling my-adb will be the adb replacement which ultimately invokes the real adb.

#! /bin/bash
# This command can be used as an alias for adb and it will prompt for the
# device selection if needed
#   alias adb=my-adb

set +x
PROGNAME=$(basename $0)
ADB=$(which adb)
if [ -z "$ADB" ]
then
   echo "$PROGNAME: ERROR: cannot found adb"
   exit 1
fi

set -e
if [ $# == 0 ]
then
   # no arguments
   exec $ADB
elif [ "$1" == 'devices' ]
then
   # adb devices should not accept -s, -e or -d
   exec $ADB devices
else
   # because of the set -e, if selecting the device fails it exits
   S=$(android-select-device "$@")
   exec $ADB $S "$@"
fi


final step
The final step is to put this solution in place. To achieve this we need a way of replacing a normal adb command with the modified version. The alias shell's internal command is the best way of getting this done (you can add it to ~/.bash_aliases):


$ alias adb=my-adb


providing that the scripts are in your PATH and execute permission was granted.
So now, every time you type adb without specifying the target device, android-select-device will prompt you for the selection:



$ adb shell
1) 02783201431feeee device           3) emulator-5554
2) 3832380FA5F30000 device           4) emulator-5556
Select the device to use, <Q> to quit: 1
$

Hope this saves you some time.

10 comments:

Unknown said...

I wanted to be change my windows adb command.
Will it work for Windows PC ?
How to modify in the Windows PC?

Diego Torres Milano said...

Have you tried http://www.cygwin.com/ ?
It may help. I should have implemented this script in python to avoid this Windows compatibility problem.

DouO said...

that's helpful , thank you!

Joseh672 said...

how can I make these scripts work in windows 7


Thanks

Diego Torres Milano said...

@Joseh672,
It should work on cygwin.
You can give it a try and post any problem you may encounter.

Unknown said...

Very useful! Thank you very much.

Yurii said...

Could you please give a few instruction in direction to using this awesome script in Mingw?
I've created these two files, and tried to put at home folder, then in adb folder with extentions .sh and .cmd and still getting
"sh.exe": my-adb command not found.
Thank you in advance.

Diego Torres Milano said...

@ Юрий,

I assume you are executing bash or shell and you are at the command prompt.
Try:

$ /path/to/my-adb

or

$ ./my-adb

if it's already in your current working directory.

sathish said...
This comment has been removed by the author.
Diego Torres Milano said...

Use:

vc = ViewClient(device, '0123456789ABCDEF')