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.
Related
I'm using the code above to simulate a 'swipe' using sendevent:
sendevent /dev/input/event0 3 53 300 ;First position X
sendevent /dev/input/event0 3 54 600 ;First position Y
sendevent /dev/input/event0 3 48 5
sendevent /dev/input/event0 3 58 50
sendevent /dev/input/event0 0 2 0
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 3 53 300 ;Second position X
sendevent /dev/input/event0 3 54 400 ;Second position Y
sendevent /dev/input/event0 0 2 0
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 0 2 0
sendevent /dev/input/event0 0 0 0
However, it does swipe instantly without any delay.
I'm trying to figure how to specify the duration of the swipe, like you can do using adb shell input:
input [touchscreen|touchpad|touchnavigation] swipe <x1> <y1> <x2> <y2> [duration(ms)]
shell input swipe 300 400 300 200 2000
This produces a swipe with a duration of 2 seconds.
I have tried to add a
sleep 2 before the ;Second position but it does result in a pause before the swipe instead of a swipe with 2 seconds of duration.
With duration I mean, the time slowly swapping from position 1 to position 2.
The problem with this is that sending events through sendevent takes some time. I made a python script (You can take whatever you need from there) that interpolates points between the given ones. It also waits some time between points.
This is the lineal interpolation code:
def lerp(p1:tuple, p2:tuple, points:int) -> list:
output = []
header = [_p2 - _p1 for _p1, _p2 in zip(p1, p2)]
for p in range(points + 1):
percent = p / points
output.append((p1[0] + percent * header[0], p1[1] + percent * header[1]))
return output
The time problem appears when using multiples points. Using a path with 10 interpolated points with no time between them already takes 1.29 seconds and a 100 points one, 11.45.
If you compare the sendevent and input commands' source code you can clearly understand their goals; the former covers basic command line's input events whereas the latter covers more flexible and complex input scenarios.
To get an insight on how the swipe duration has been implemented (on input command) you can focus directly on the sendSwipe method: it sends multiple basic input events, leveraging the InputManager, in a timespan defined by the duration parameter
final long endTime = down + duration;
The function injectMotionEvent used by sendSwipe doesn't have any concept of "duration".
That said, I think the command you're looking for, as of today, doesn't exist and I believe you can still rely on console prompt like
input swipe 300 400 300 200 2000
that can be invoked after using
adb shell
One cannot set the duration on the low level, but one can record analog input and then play it back. This permits for more flexible and complex scenarios ...because the events are countless.
Run adb shell to open a shell.
Where ...
getevent --help shows all available options.
getevent -p shows all recordable devices.
getevent -lp /dev/input/event1 shows BTN_TOUCH event data format.
getevent /dev/input/event1 logs input events for device focaltech_ts.
getevent -l /dev/input/event1 is human-readable (useless for automation).
To record:
cd sdcard/Download
getevent /dev/input/event1 >> ./swipe.log
download swipe.log with the Android device explorer.
Where 0003 means coordinate, and 0x35 is the X-axis and 0x36 is the Y-axis:
0003 0035 000001a8
0003 0036 000005cb
This log can the be played back by a shell script loop, with sendevent.
sendevent --help shows the expected parameters: DEVICE TYPE CODE VALUE.
cat ./swipe.log | while read line
do
adb shell sendevent /dev/input/event1 $line
done
When delaying the execution with sleep, the lines with 0000 0000 00000000 might suit best.
Alike this one can also automate GPIO buttons, which maybe be quite specific on certain devices. UiObject2.swipe() might also just generate linear-interpolation coordinates and play them back. It generally does not matter, if they're generated or recorded - the only difference is that the one movement is perfectly straight and the other one obviously isn't.
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));
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
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.
I am trying to get the (x, y) coordinate of the touch through the pointer location option in Developer Options and I use these coordinates to tap on the screen using sendevent. Here is my script that does the sendevent.
tap.sh
sendevent /dev/input/event0 3 57 2421
sendevent /dev/input/event0 3 58 232
sendevent /dev/input/event0 3 53 $1
sendevent /dev/input/event0 3 54 $2
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 3 57 4294967295
sendevent /dev/input/event0 0 0 0
I call the script from adb shell sh tap.sh <x> <y> but it is not tapping on the right coordinate. Instead it is tapping at a different location.
Also when I tap on the screen and check the result in getevent adb shell getevent. I find that the coordinates that is shown on the pointer location and the getevent are different.
Why are they different and how do I solve this issue?
PS: The devices I tried are Nexus 7, Nexus 10.
The X and Y co-ordinates obtained from the getevent and the ones obtained from the pointer location in developer options are not the same. They are mapped using a formula.
displayX = (x - minX) * displayWidth / (maxX - minX + 1)
displayY = (y - minY) * displayHeight / (maxY - minY + 1)
Source: Touch Devices
Turn on developer options and enable Pointer Location and you can see the x and y coordinates on top of the screen when you tap on the screen use those coordinates to send tap events.
Are you aware that getevent (in my experience, this possibly varies between devices) shows base 16 values?
(side note: getevent -l is often easier to read as it prints a string representation of the event types)
i.e. if getevent -l says
/dev/input/event1: EV_ABS ABS_MT_POSITION_X 000001cb
/dev/input/event1: EV_ABS ABS_MT_POSITION_Y 00000376
the position of the touch is (459, 886) actually
however it appears that sendevent is not following suit in requiring hex values if your code works at all, as your (such as) 53 and 54 work where I would have used
0035 and 0036.
Edit:
Having tried the original code on a Nexus 5 (correct device file substituted in), I have found that no touch event is generated (nor when the hexadecimal equivalent is substituted, for experimental rigor), nor from reusing values captured (and converted) from getevent. Previously, I have had better experience converting the events with a Python script based on the C one here, and writing the output directly to the device file.
Edit 2:
This question here suggests that the initial code should work.