Below is code I've written that is supposed to take a list of all devices connected, extract their serial numbers, and than spit them out to the terminal. When I run this script I get error: unknown host service which spawns out of my Return Serial function
ReturnSerial () {
adb -s $usb shell getprop | grep ro.serial | awk '{print $2}'
}
for usb in $(adb devices -l | awk '/ device usb:/{print $2}'); do ReturnSerial ; done
I don't understand what this error means. I have many other functions that I run in the same fashion that do not get caught.
Also worth noting, the devices I work with do not spit out their serial number on a simple adb devices command, thus why I need to use their usb locator and extract the serial number from their properties.
Related
I need a bit of assistance. I have a Huawei g6-l11 (with Android 4.3) from which I am trying to extract the IMEI via ADB. I know that this device is ancient, but this is one of my tasks. So far I had tried everything I could find on the internet, like:
1) adb shell getprop | grep "<IMEI>"
2) adb shell service call iphonesubinfo N | grep "<IMEI>" - Where N is a number between 1 and 50
3) adb shell settings get secure android_id
4) adb shell content query --uri content://settings/secure | grep "<IMEI>"
5) adb shell content query --uri content://settings/system | grep "<IMEI>"
6) adb shell content query --uri content://settings/global | grep "<IMEI>"
7) adb shell dumpsys | grep "<IMEI>"
So I had made an Android app and run this piece of code on the smartphone:
val tm = this.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
Log.d("Emy_","The IMEI is ${tm.deviceId}")
That worked fine but it is an Android app when I need to do the same thing but only via ADB.
Also, I had found a fastboot command that would help me (like: fastboot oem get-psid). But the problem is that I need to reboot the phone into fast boot mode. Which is taking too long.
My questions are:
1) why is it different for Huawei models with the OS version below Marshmallow to extract the IMEI?
2) how could I replicate the function call done by the Java code to be done with the ADB in the terminal? Or in other words, what other commands would you recommend to me to try to extract the IMEI?
You could display it on screen:
adb am start -a android.intent.action.CALL -d tel:*%2306%23
If you just searching to know the IMEI, You can try this code : *#06#
Or you can try this : adb shell
service call iphonesubinfo 1 | toybox cut -d "'" -f2 | toybox grep -Eo '[0-9]' | toybox xargs | toybox sed 's/\ //g'
hop that help you !
How can I check adb device is connected in batch files?
I wrote "adb devices" in the batch file, but I want it as a condition so the app working smoothly and automatically
So if the user is not connected his device print no device and exit the app,
Otherwise resume the app.
Pipe the output to find and analyse the errorlevel:
adb devices -l | find "device product:" >nul
if errorlevel 1 (
echo No connected devices
) else (
echo Found!
..............
)
For user in bash or similar shell environment, try
$ adb get-state 1>/dev/null 2>&1 && echo 'device attached' || echo 'no device attached'
This is the easiest and is most accurate since it'll only find "device" and not other words containing the string such as "devices":
adb devices | findstr "\<device\>"
Take note that findstr works on Windows but not in Unix terminals. So the equivilent would be to use find and grep together. John explains this well in this page Using find and grep to Mimic findstr Command
Is there a way of running adb commands on all connected devices? To uninstall an app from all connected devices with "adb uninstall com.example.android".
The commands I am interested in is mainly install and uninstall.
I was thinking about writing a bash script for this, but I feel like someone should have done it already :)
Create a bash file and name it e.g. adb+:
#!/bin/bash
adb devices | while read -r line
do
if [ ! "$line" = "" ] && [ "$(echo "$line" | awk '{print $2}')" = "device" ]
then
device=$(echo "$line" | awk '{print $1}')
echo "$device" "$#" ...
adb -s "$device" "$#"
fi
done
Usage: ./adb+ <command>
Building on #Oli's answer, this will also let the command(s) run in parallel, using xargs. Just add this to your .bashrc file:
function adball()
{
adb devices | egrep '\t(device|emulator)' | cut -f 1 | xargs -t -J% -n1 -P5 \
adb -s % "$#"
}
and apply it by opening a new shell terminal, . ~/.bashrc, or source ~/.bashrc.
If you only want to run on devices (or only on emulators), you can change the (device|emulator) grep by removing the one you don't want. This command as written above will run on all attached devices and emulators.
the -J% argument specifies that you want xargs to replace the first occurrence of % in the utility with the value from the left side of the pipe (stdin).
NOTE: this is for BSD (Darwin / Mac OS X) xargs. For GNU/Linux xargs, the option is -I%.
-t will cause xargs to print the command it is about to run immediately before running it.
-n1 means xargs should only use at most 1 argument in each invocation of the command (as opposed to some utilities which can take multiple arguments, like rm for example).
-P5 allows up to 5 parallel processes to run simultaneously. If you want instead to run the commands sequentially, simply remove the entire -P5 argument. This also allows you to have two variations of the command (adball and adbseq, for example) -- one that runs in parallel, the other sequentially.
To prove that it is parallel, you can run a shell command that includes a sleep in it, for example:
$ adball shell "getprop ro.serialno ; date ; sleep 1 ; date ; getprop ro.serialno"
You can use this to run any adb command you want (yes, even adball logcat will work! but it might look a little strange because both logs will be streaming to your console in parallel, so you won't be able to distinguish which device a given log line is coming from).
The benefit of this approach over #dtmilano's & approach is that xargs will continue to block the shell as long as at least one of the parallel processes is still running: that means you can break out of both commands by simply using ^C, just like you're used to doing. With dtmilano's approach, if you were to run adb+ logcat, then both logcat processes would be backgrounded, and so you would have to manually kill the logcat process yourself using ps and kill or pkill. Using xargs makes it look and feel just like a regular blocking command line, and if you only have one device, then it will work exactly like adb.
This is an improved version of the script from 強大な. The original version was not matching some devices.
DEVICES=`adb devices | grep -v devices | grep device | cut -f 1`
for device in $DEVICES; do
echo "$device $# ..."
adb -s $device $#
done
To add in the ~/.bashrc or ~/.zshrc:
alias adb-all="adb devices | awk 'NR>1{print \$1}' | parallel -rkj0 --tagstring 'on {}: ' adb -s {}"
Examples:
$ adb-all shell date
$ adb-all shell getprop net.hostname
$ adb-all sideload /path/to/rom.zip
$ adb-all install /path/filename.apk
$ adb-all push /usr/local/bin/frida-server-arm64 /data/local/tmp/frida-server
Explanation: awk extracts the device id/host (first column: print $1) of every lines except the first one (NR>1) to remove the "List of devices attached" header line), then gnu parallel runs adb -s <HOSTNAME> <whatever-is-passed-to-the-alias> on whatever non-empty line (-r) in the order specified (-k, to avoid random order / fastest response order) and prepend each line with on <DEVICE>:\t for clarity, all in parallel (-j0, possible to set another number to define how many adb should be ran in parallel instead of unlimited).
:)
This is the highest result on Google, so for all Windows users coming here let me add this solution by User zingh (slightly modified to accept arbitrary commands, rather than "only" install
Batch file (adball.bat):
FOR /F "skip=1" %%x IN ('adb devices') DO start adb -s %%x %*
Call as:
adball uninstall com.mypackage
(%* takes all input parameters, my line above makes it so that all commands are passed to adb as they are, so that you can type multiple words, flags etc.)
Note: you can even use this directly from the Android Studio "run all" popup, if you install the Powershell-plugin. You can add adball to your path, then double-tap ctrl and run
powershell adball uninstall com.mypackage
adb wrapper supports selecting multiple targets for adb commands and parallel execution.
From its README:
# Installation
./install.sh ~/apps/android-sdk-linux
# Execute adb commands on all connected devices.
adb set-target all
# Execute adb commands on given devices.
adb set-target emulator-5554 C59KGT14263422
# Use GNU parallel for parallel install.
adb set-parallel true
(Disclaimer: I have written half of it)
$ adb --help
-s SERIAL use device with given serial (overrides $ANDROID_SERIAL)
$ adb devices
List of devices attached
emulator-5554 device
7f1c864e device
$ adb shell -s 7f1c864e
error: more than one device and emulator
Use the -s option BEFORE the command to specify the device, for example:
adb -s 7f1c864e shell
For multiple Emulator, use the process's IP and port as the id, like:
adb -s 192.168.232.2:5555 <command>
See How to get the Android Emulator's IP address?
But if there is only a single Emulator, try:
adb -e <command>
See also http://developer.android.com/tools/help/adb.html#directingcommands
adb -d shell (or adb -e shell).
This command will help you in most of the cases, if you are too lazy to type the full ID.
From http://developer.android.com/tools/help/adb.html#commandsummary:
-d - Direct an adb command to the only attached USB device. Returns an error when more than one USB device is attached.
-e - Direct an adb command to the only running emulator. Returns an error when more than one emulator is running.
Another alternative would be to set environment variable ANDROID_SERIAL to the relevant serial, here assuming you are using Windows:
set ANDROID_SERIAL=7f1c864e
echo %ANDROID_SERIAL%
"7f1c864e"
Then you can use adb.exe shell without any issues.
To install an apk on one of your emulators:
First get the list of devices:
-> adb devices
List of devices attached
25sdfsfb3801745eg device
emulator-0954 device
Then install the apk on your emulator with the -s flag:
-> adb -s "25sdfsfb3801745eg" install "C:\Users\joel.joel\Downloads\release.apk"
Performing Streamed Install
Success
Ps.: the order here matters, so -s <id> has to come before install command, otherwise it won't work.
Hope this helps someone!
I found this question after seeing the 'more than one device' error, with 2 offline phones showing:
C:\Program Files (x86)\Android\android-sdk\android-tools>adb devices
List of devices attached
SH436WM01785 offline
SH436WM01785 offline
SH436WM01785 sideload
If you only have one device connected, run the following commands to get rid of the offline connections:
adb kill-server
adb devices
The best way to run shell on any particular device is to use:
adb -s << emulator UDID >> shell
For Example:
adb -s emulator-5554 shell
As per https://developer.android.com/studio/command-line/adb#directingcommands
What worked for my testing:
UBUNTU BASH TERMINAL:
$ adb devices
List of devices attached
646269f0 device
8a928c2 device
$ export ANDROID_SERIAL=646269f0
$ echo $ANDROID_SERIAL
646269f0
$ adb reboot bootloader
WINDOWS COMMAND PROMPT:
$ adb devices
List of devices attached
646269f0 device
8a928c2 device
$ set ANDROID_SERIAL=646269f0
$ echo $ANDROID_SERIAL$
646269f0
$ adb reboot bootloader
This enables you to use normal commands and scripts as if there was only the ANDROID_SERIAL device attached.
Alternatively, you can mention the device serial every time.
$ adb -s 646269f0 shell
This gist will do most of the work for you showing a menu when there are multiple devices connected:
$ adb $(android-select-device) shell
1) 02783201431feeee device 3) emulator-5554
2) 3832380FA5F30000 device 4) emulator-5556
Select the device to use, <Q> to quit:
To avoid typing you can just create an alias that included the device selection as explained here.
User #janot has already mentioned this above, but this took me some time to filter the best solution.
There are two Broad use cases:
1) 2 hardware are connected, first is emulator and other is a Device.
Solution : adb -e shell....whatever-command for emulator and adb -d shell....whatever-command for device.
2) n number of devices are connected (all emulators or Phones/Tablets) via USB/ADB-WiFi:
Solution:
Step1) run adb devices THis will give you list of devices currently connected (via USB or ADBoverWiFI)
Step2) now run adb -s <device-id/IP-address> shell....whatever-command
no matter how many devices you have.
Example to clear app data on a device connected on wifi ADB I would execute:
adb -s 172.16.34.89:5555 shell pm clear com.package-id
to clear app data connected on my usb connected device I would execute:
adb -s 5210d21be2a5643d shell pm clear com.package-id
For Windows, here's a quick 1 liner example of how to install a file..on multiple devices
FOR /F "skip=1" %x IN ('adb devices') DO start adb -s %x install -r myandroidapp.apk
If you plan on including this in a batch file, replace %x with %%x, as below
FOR /F "skip=1" %%x IN ('adb devices') DO start adb -s %%x install -r myandroidapp.apk
Create a Bash (tools.sh) to select a serial from devices (or emulator):
clear;
echo "====================================================================================================";
echo " ADB DEVICES";
echo "====================================================================================================";
echo "";
adb_devices=( $(adb devices | grep -v devices | grep device | cut -f 1)#$(adb devices | grep -v devices | grep device | cut -f 2) );
if [ $((${#adb_devices[#]})) -eq "1" ] && [ "${adb_devices[0]}" == "#" ]
then
echo "No device found";
echo "";
echo "====================================================================================================";
device=""
// Call Main Menu function fxMenu;
else
read -p "$(
f=0
for dev in "${adb_devices[#]}"; do
nm="$(echo ${dev} | cut -f1 -d#)";
tp="$(echo ${dev} | cut -f2 -d#)";
echo " $((++f)). ${nm} [${tp}]";
done
echo "";
echo " 0. Quit"
echo "";
echo "====================================================================================================";
echo "";
echo ' Please select a device: '
)" selection
error="You think it's over just because I am dead. It's not over. The games have just begun.";
// Call Validation Numbers fxValidationNumberMenu ${#adb_devices[#]} ${selection} "${error}"
case "${selection}" in
0)
// Call Main Menu function fxMenu;
*)
device="$(echo ${adb_devices[$((selection-1))]} | cut -f1 -d#)";
// Call Main Menu function fxMenu;
esac
fi
Then in another option can use adb -s (global option -s use device with given serial number that overrides $ANDROID_SERIAL):
adb -s ${device} <command>
I tested this code on MacOS terminal, but I think it can be used on windows across Git Bash Terminal.
Also remember configure environmental variables and Android SDK paths on .bash_profile file:
export ANDROID_HOME="/usr/local/opt/android-sdk/"
export PATH="$ANDROID_HOME/platform-tools:$PATH"
export PATH="$ANDROID_HOME/tools:$PATH"
Running adb commands on all connected devices
Create a bash (adb+)
adb devices | while read line
do
if [ ! "$line" = "" ] && [ `echo $line | awk '{print $2}'` = "device" ]
then
device=`echo $line | awk '{print $1}'`
echo "$device $# ..."
adb -s $device $#
fi
done
use it with
adb+ //+ command
you can use this to connect your specific device :
* adb devices
--------------
List of devices attached
9f91cc67 offline
emulator-5558 device
example i want to connect to the first device "9f91cc67"
* adb -s 9f91cc67 tcpip 8080
---------------------------
restarting in TCP mode port: 8080
then
* adb -s 9f91cc67 connect 192.168.1.44:8080
----------------------------------------
connected to 192.168.1.44:8080
maybe this help someone
Here's a shell script I made for myself:
#! /bin/sh
for device in `adb devices | awk '{print $1}'`; do
if [ ! "$device" = "" ] && [ ! "$device" = "List" ]
then
echo " "
echo "adb -s $device $#"
echo "------------------------------------------------------"
adb -s $device $#
fi
done
For the sake of convenience, one can create run configurations, which set the ANDROID_SERIAL:
Where the adb_wifi.bat may look alike (only positional argument %1% and "$1" may differ):
adb tcpip 5555
adb connect %1%:5555
The advance is, that adb will pick up the current ANDROID_SERIAL.
In shell script also ANDROID_SERIAL=xyz adb shell should work.
This statement is not necessarily wrong:
-s SERIAL use device with given serial (overrides $ANDROID_SERIAL)
But one can as well just change the ANDROID_SERIAL right before running the adb command.
One can even set eg. ANDROID_SERIAL=192.168.2.60:5555 to define the destination IP for adb.
This also permits to run adb shell, with the command being passed as "script parameters".
If I call the command "adb.exe devices" I get a list of devices with a unique ID for each. These IDs are perfect for programming but not very human readable. Is there any way I can link one of these IDs to a (not necessarily unique) description of the phone? For example, if I have a device with an ID 1234567890abcdef is there any way I can figure that in real life it is a Motorola Droid X?
In Android there is a Model number entry in settings that shows phone name.
There is a way to quickly see this via command line:
adb shell cat /system/build.prop | grep "product"
This is what's shown for Samsung Galaxy S 4G:
ro.product.model=SGH-T959V
ro.product.brand=TMOUS
ro.product.name=SGH-T959V
ro.product.device=SGH-T959V
ro.product.board=SGH-T959V
ro.product.cpu.abi=armeabi-v7a
ro.product.cpu.abi2=armeabi
ro.product.manufacturer=Samsung
ro.product.locale.language=en
ro.product.locale.region=US
# ro.build.product is obsolete; use ro.product.device
ro.build.product=SGH-T959V
On a HTC Desire, the output looks like this:
ro.product.model=HTC Desire
ro.product.brand=htc_wwe
ro.product.name=htc_bravo
ro.product.device=bravo
ro.product.board=bravo
ro.product.cpu.abi=armeabi-v7a
ro.product.cpu.abi2=armeabi
ro.product.manufacturer=HTC
ro.product.locale.language=hdpi
ro.product.locale.region=
You can refine your query to show only one line:
adb shell cat /system/build.prop | grep "ro.product.device"
or
adb shell cat /system/build.prop | grep "ro.product.model"
With newer devices, you can run
adb devices -l
This will list some devices in a more human readable form
Example:
04d9a601ce516d53 device usb:1A134500 product:occam model:Nexus_4 device:mako
015d4b3406280a07 device usb:1A134700 product:nakasi model:Nexus_7 device:grouper
01466E620900F005 device usb:1A134600 product:mysid model:Galaxy_Nexus device:toro
Yes, adb shell cat /system/build.prop is wonderful, but also as #Matt said, it sometimes differs because of different manufacture.
IMHO, the most reliable approach is the built-in command: adb shell getprop
======================================================================
Here is a comparison for an exception (Genymotion emulator):
By adb shell cat /system/build.prop you'll get
ro.product.brand=generic
ro.product.name=vbox86p
ro.product.device=vbox86p
ro.product.board=
ro.product.cpu.abi=x86
ro.product.manufacturer=Genymotion
ro.product.locale.language=en
ro.product.locale.region=US
So there is no model value :(
By adb shell getprop you'll get
[ro.product.manufacturer]: [Genymotion]
[ro.product.model]: [Nexus422ForAutomation]
[ro.product.name]: [vbox86p]
Here you get the model name: Nexus422ForAutomation :)
Unfortunately, there is no reliable way to do this since each manufacturer tweaks their build properties
If you type "adb help" into the command line you can see a list of the adb commands and a description for each.
I'm using this script (on MacOS):
#!/bin/bash
devices=`adb devices | grep "device" | grep -v "List of" | cut -d " " -f 1`
for device in $devices
do
manufacturer=`adb -s $device shell getprop ro.product.manufacturer | sed -e 's/[[:space:]]*\$//'`
model=`adb -s $device shell getprop ro.product.model | sed -e 's/[[:space:]]*\$//'`
echo "$device: $manufacturer $model"
done
It produces e.g. the following output:
T076000UWX: motorola XT1053
C4F12070E5A068E: samsung GT-P7510
4df1ff977b919f91: samsung GT-N7100
4258393032523638324D: Sony Ericsson LT18i