Fast Keyevent Simulation (Android Shell) - android

Using adb shell input text <String> or adb shell input keyevent <KEYCODE_NAME> works perfectly fine in sending text to the android device, but my issue is speed.
Using something like input keyevent KEYCODE_A KEYCODE_A KEYCODE_SPACE KEYCODE_A KEYCODE_ENTER; will type the text quickly, but separating it into 2 commands will result in a (1 sec) delay between the 2 commands (Much Slower).
Sample Shell Code:
Method 1 (Much faster):
input keyevent KEYCODE_A KEYCODE_A KEYCODE_ENTER KEYCODE_A KEYCODE_A KEYCODE_ENTER;
Method 2:
input keyevent KEYCODE_A KEYCODE_A KEYCODE_ENTER;
input keyevent KEYCODE_A KEYCODE_A KEYCODE_ENTER;
I would like to type a large text as fast as possible, but having a shell script with input keyevent followed by a large combination of KEYCODE_A for instance, will not be executed. (Large Shell Commands are aborted)
What would be the best way to send large text without having long delays?
Would sendevent be faster in sending large text?
Note:
The weakness of input text <String> is that it also has a limit to it's size and it can't perform special keyevents inside of it (Like the Back Button or Enter/New Line ).
Thanks in Advance.

I realise you are after Android Shell, but I think you have exhausted the options available to you there.
I know of one way that is faster than what you have tried, using Instrumentation:
final Instrumentation mInst = new Instrumentation();
mInst.sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, keycode));
mInst.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, keycode));

Related

Clear Edit Text - adb

How to clear focused Edit text using shell command.
I tried
adb shell input keyevent KEYCODE_CLEAR // Not worked
adb shell input keyevent KEYCODE_DEL // Delete only one char
adb shell input keyevent KEYCODE_FORWARD_DEL // Not worked
With this I am only able to delete upto One character only, Is there any way I can delete/clear the focused Edit text.
This works for me:
function clear_input() {
adb shell input keyevent KEYCODE_MOVE_END
adb shell input keyevent --longpress $(printf 'KEYCODE_DEL %.0s' {1..250})
}
Then:
clear_input
You can use this way:
adb shell input keyevent --longpress 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67
67 is the keycode of KEYCODE_DEL
The only way that I have found so far is to get the proper coordinates to use input swipe x y x y duration to simulate a long press. This will then highlight all the text in the EditText field. You can then send the keys you want to replace what was there.
I just wish that adb shell input keyevent KEYCODE_CLEAR would clear all the text in the field. That would make things so much easier, if someone can find a better way that would be great.
If you use uiautomator(https://github.com/xiaocong/uiautomator), you could do this by:
tap the EditText widget to get focus, then
use device(focused=True).clear_text() to clear the view, or by device(focused=True).set_text("new text") to set a new text.

How to make monkeyrunner simulate a drag following a custom path on the android screen?

The MonkeyDevice.drag currently can takes only 2 sets of co-ordinates which means I can move from (x1,y1) to (x2,y2). Is there a way I could make the monkey runner simulate a drag from (x1,y1) to (x3,y3) and then to (x2,y2) without breaking the same drag function?
Monkeyrunner is kind of deprecated.
You can use uiautomator instead. More details can be found here:
http://developer.android.com/tools/testing/testing_ui.html
This tool has a method for what you seek, a custom swipe using an array of points (x, y coordinates). More on that here:
http://developer.android.com/tools/help/uiautomator/UiDevice.html#swipe(android.graphics.Point[], int)
I would use Get/Send Event.
Get an event, e.g. touch screen:
issue command: adb shell getevent | grep event2 > CaptureEvent.txt
do the touchscreen activity
stop the recording with CTRL+C
Convert the event:
e.g.: /dev/input/event1 3 47 0
Send an event:
issue commands, e.g.: adb shell sendevent /dev/input/event1 3 47 0

Android - how to paste File.txt content into adb Shell

I am writing a small code to search for a number in whatsapp and send a text message.
I am able to send text message if I type in the script itself, but I wanted to paste the message from a file.
Is there any way to copy the content from a file instead os using the adb shell input text command.
My code below.
adb shell input keyevent 82
adb shell am force-stop com.whatsapp
adb shell am start -n com.whatsapp/.Main
adb shell input text "9800000000"
adb shell input keyevent 66
adb shell input text 'This%sis%sa%stest%smessage'
adb shell input keyevent 66
adb shell input text 'I%sam%schecking%slots%sof%sthings'
adb shell input keyevent 61
adb shell input keyevent 61
adb shell input keyevent 66
adb shell am force-stop com.whatsapp
Thanks,
Deepak
You don't say which scripting language you are using.
You can do it from a Native binary (written in C/C++).
1. Open the file for reading.
2. LOOP
3. Read a line into a string.
4. convert all special characters to escape strings
5. Use the command system to send the text:
system("input "text Hello%sWorld");
6. LOOP
I wrote such a binary called inputer. pasting into it works quite well, but
each line is fork/exec'd so big files can get out of order, you need to test for each line completing or send as one huge call.
Yes, you actually can do this. It's kind of kludgy looking when you inspect the clipboard, but it works just fine.
First off, you can inspect the current clipboard contents with service call clipboard 1 from an adb shell (or, without shelling in first, adb shell service call clipboard 1). It may start out initially blank after a reboot, for example:
service call clipboard 1
Result: Parcel(
0x00000000: 00000000 00000001 00000000 00000000 '................'
0x00000010: 00000000 00000000 '........ ')
#
You can put text into the clipboard using service call clipboard 2, which basically takes 3 parameters - two ints and the string you want to put on the clipboard:
# service call clipboard 2 i32 1 i32 0 s16 "Hi there"
Result: Parcel(00000000 '....')
To be honest, I'm not sure what the first two parameters are. One answer on Stack Overflow has suggested the first int is "number of items in the parcel" (one in this case) and that the second is the length of the string. However, I've used 0 for the second parameter and it works fine, and I can't find any documentation that matches up with this particular function...so take that for what it's worth.
In any case, it's basically creating a Parcel object with 3 fields, then passing it into the clipboard. The clipboard then unpacks the Parcel and sets the string value passed in as the clipboard's contents. You can see this when you go to retrieve the value afterwards:
# service call clipboard 1
Result: Parcel(
0x00000000: 00000000 00000001 00000000 00000008 '................'
0x00000010: 00690048 00740020 00650068 00650072 'H.i. .t.h.e.r.e.'
0x00000020: 00000000 00000000 '........ ')
#
Similarly, if you long-press on a text entry field and hit "Paste" after doing this, you will get the text that was set via the call service clipboard 2 line above (and it will look completely normal).
(The above examples come from my HTC EVO, running CyanogenMod 7)
Reference : https://android.stackexchange.com/questions/19710/is-it-possible-to-write-to-a-devices-clipboard-using-adb

adb: tap and input text

I'm trying to use "input tap" and "input text" via ADB:
input tap 400 730
input tap 60 410
input tap 150 490
input tap 120 300
input tap 120 420
input tap 130 180
input tap 130 180
input text name_of_the_apn
Tapping works fine, but the execution of the scripts gives back an error when it tries to input the text (see below). However, when I try to send the text outside of the script, it works fine. I already tried adding sleep between tapping and the text - with no effect.
Any hints? Thanks!
/mnt/.lfs: Function not implemented
/data/ste-debug/stedump: Operation not permitted
[1] Killed input text name_of_the_apn
I know it's nearly 7 years now, but I have to escape any spaces in the text when I use type from the commnand line (as opposed to being in the shell):
adb shell input text "Hi\ there\ this\ is\ dog"
and also be weary if it's a variable in bash
TEXT="Hi\ there\ this\ is\ dog"
adb shell input text "$TEXT" #make sure it's in quotes
I also think that maybe you had a variable on your terminal name_of_vpn but you were in the adb shell at the time, and the variable was not present, or you are not accessing that with $
It could also be that this has been fixed now.

How to lock Android screen via ADB?

Is there a way to lock the Android screen via the ADB?
I find ways to lock the display in an apk, but I want to lock the screen from the PC via ADB, to simulate a display timeout, without having to wait for the timeout.
Is it possible to do this?
Thanks,
Diane
Cool, I just found KEYCODE_POWER which is 26.
so it works by sending:
adb shell input keyevent 26
which locks the screen if the screen is unlocked. If the screen is already locked, it wakes up the device.
My guess is that the only way to ensure that the screen is locked (off), is to unlock (we use keyevent 82 (menu), then lock it with the power button keyevent. Does anyone have any idea if this is true?
Michael R. Hines gave the what is arguably the easiest solution. However, the following line is not useful in later versions of Android.
adb shell input keyevent 82 # unlock
I've updated the shell script using coordinates for the individual device I want to wake (Tablet). My tablet does not support orientation changes for lockscreen events, so the values always work as the lockscreen is always in landscape. Should you require orientation change detection, a simple if/then/else would suffice in picking the correct coordinates to use for the orientation.
#!/bin/bash
if [ "$(adb shell dumpsys power | grep mScreenOn= | grep -oE '(true|false)')" == false ] ; then
echo "Screen is off. Turning on."
adb shell input keyevent 26 # wakeup
adb shell input touchscreen swipe 930 380 1080 380 # unlock
echo "OK, should be on now."
else
echo "Screen is already on."
echo "Turning off."
adb shell input keyevent 26 # sleep
fi
Here's the whole thing in one single bash script which checks if the screen is actually on or not and then wakes up and unlocks the screen in one shot:
if [ "$(adb shell dumpsys power | grep mScreenOn= | grep -oE '(true|false)')" == false ] ; then
echo "Screen is off. Turning on."
adb shell input keyevent 26 # wakeup
adb shell input keyevent 82 # unlock
echo "OK, should be on now."
else
echo "Screen is already on."
fi
You've already found a solution, but I'll put this code here for reference anyway.
What you could do is to inject event to "press" the power button twice. If you don't know the status of the device (display on/off), check whether the screen is currently on or off and press the power button accordingly.
Here's a simple monkeyrunner script:
import re
from java.util import *
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
device = MonkeyRunner.waitForConnection() # connect to a device
device.shell("input keyevent KEYCODE_POWER") # turn screen off (or on?)
res = device.shell("dumpsys power") # fetch power state
m = re.search(r'.*mPowerState=([0-9]+).*', res) # parse the string
if m and int(m.group(1)) == 0: # screen is off
device.shell("input keyevent KEYCODE_POWER") # turn the screen on
In addition to the answers before, here's what I do to lock / unlock my screen using adb:
adb shell input keyevent 26 will lock the screen.
So, if you execute that command again, while the screen is turned off / locked, it will be turned on / unlocked.
adb shell input keyevent 26 will also unlock the screen (if the screen is locked).
Furthermore, I have also tested all commands, such as adb shell input keyevent number, and found out that adb shell input keyevent 3 also unlock the device.
I had also found out (by testing) that key 3 is the home button. So , if you have a physical home button (not the soft home button on the screen), you can also use this to unlock your device.
For those using earlier versions of android (4.2+ at least), dumpsys power has a different output.
Instead of using mPowerState= as the answer given by #Jakub Czaplicki, I used mScreenOn=.
p = Runtime.getRuntime().exec("su", null, null);
OutputStream o = p.getOutputStream();
o.write(("dumpsys power").getBytes("ASCII"));
o.flush();
o.close();
p.waitFor();
boolean screenState;
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((res = in.readLine()) != null) dump += res;
screenState = dump.charAt( dump.indexOf("mScreenOn=") + 10 ) == 't';
screenState is true (screen on), or false (screen off).
You can use following command to trigger display ON.
adb shell input keyevent POWER
I tried and am using in my project, Hope it will work for you.
And here is the ruby code I used:
def ScreenCheck()
system("adb shell dumpsys power > c:/interact.log")
File.open("C:\\interact.log").each do |line|
if line[/mScreenOn/]
if line.strip == "mScreenOn=true"
p "Screen is On, Starting execution.."
else
p "Screen is Off, starting screen.."
system("adb shell input keyevent = POWER")
p "Starting execution.."
end
end
end
end
Here is a script to turn on/off the screen for every connected device including any pre-lollipop devices. I use this on my Jenkins server right before running any connected Android tests to make sure the devices are ready to go. Hope someone finds this useful!
#!/bin/sh
# Returns the power state of the screen 1 = on, 0 = off
getDisplayState() {
state=$(adb -s $1 shell dumpsys power | grep mScreenOn= | grep -oE '(true|false)')
# If we didn't get anything it might be a pre-lollipop device
if [ "$state" = "" ]; then
state=$(adb -s $1 shell dumpsys power | grep 'Display Power' | grep -oE '(ON|OFF)')
fi
if [ "$state" = "ON" ] || [ "$state" = "true" ]; then
return 1;
else
return 0;
fi
}
echo "Turning on screen on all connected devices..."
for device in `adb devices | grep device$ | cut -f1`
do
echo -n "Found device: $device ... "
getDisplayState $device
state=$?
# If the display is off, turn it on
if [ $state -eq 0 ]; then
echo "display was off, turning on"
adb -s $device shell input keyevent 26
else
echo "display was on"
fi
done

Categories

Resources