Android sendKeys() performance

Hello.
I use appium for android automation and i have some performance issue with sendKeys() method.
For example, input of text performs 3-5 sec. I have tried to type text in filed in another way - using sendKeyEvent() method for all symbols in input text, but this approach is slow also.
Can anybody suggest some relatively quick way to type text with Appium in Android?
Thank you in advance.

I have found alternative approach for text input.
You can use adb shell for this purpose.
For example,
adb shell input text abcdefg, where “abcdefg” is input text.
Thanks.

Hi Can you please let me know how in java code we can call ‘adb shell input text abcdefg’ command? I am also facing lots os problem because of element.sendKeys() being slow.

Before executing of command you should perform focus on input field (click on it, for example).
Then, you could execute next java code:

String [] args = {"cmd", "start", "adb", "-s", your_device_uid, "shell", "input", "text", your_text};
Runtime runtime = Runtime.getRuntime();
runtime.exec(args);

Thanks for the reply.

I tried below code because I am using android emulator. Using “0000000000000” as device uid.

WebElement element=driver.findElement(By.id(“com.calculator:id/EditText01”));
element.click();
String [] args = {“cmd”, “start”, “adb”, “-s”, “0000000000000”, “shell”, “input”, “text”, “2”};
Runtime runtime = Runtime.getRuntime();
runtime.exec(args);

getting below exception -

java.io.IOException: Cannot run program “cmd”: error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1047)
at java.lang.Runtime.exec(Runtime.java:617)
at java.lang.Runtime.exec(Runtime.java:485)
at com.saucelabs.appium.AndroidTest.apiDemo(AndroidTest.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.(UNIXProcess.java:184)
at java.lang.ProcessImpl.start(ProcessImpl.java:130)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1028)

Do you have any idea, why I am getting this exception? or what I am doing wrong?

I have got it working. Thanks. Using emulator id i.e. emulator-5554 instead of “000000000000000” solves my problem.

So for anyone else facing the same issue -

below is what you need to do in order to get your code working.

WebElement element=driver.findElement(By.id(“com.calculator:id/EditText01”));
element.click();
Process p = Runtime.getRuntime().exec("/Users/manjyotsingh/Library/Android/sdk/platform-tools//adb -s emulator-5554 shell input text 267");

1 Like

The only issue that I am facing now is, I have to give full path of adb instead of just “abd”(as mentioned above in the command). I have set path till platform-tools in PATH variable. If I write the command in terminal like “adb -s emulator-5554 shell input text 267”, it executes the command gracefully but when I am executing it from java code I have to give full path to adb.

Any solution to that?

Hi, the above solution works for me however there are times when only part of the text is being inputted. For example:

Runtime runtime = Runtime.getRuntime();
runtime.exec("cmd start adb -s 0000000000000 shell input text “1234567891111113”);

RESULT (text shown in phone): 12345

Runtime runtime = Runtime.getRuntime();
runtime.exec("cmd start adb -s 0000000000000 shell input text “30”);

RESULT (text shown in phone): 3

This happens randomly and there are times it works. I can’t pinpoint when it will happen and why.
Can somebody please help? Any ideas?

Thanks!

I have the exact same issue. I believe it to be a problem with the send key’s speed going too fast. You can manually replicate it in numeric input fields by pressing 123 really fast. Often times you get result of 12 and missing the second keystroke. Can we have abilitiy to set speed at which keys are sent to input field? Works great as is for text, but the problem seems to be isolated to numwric fields.

Actually, i found out its not a problem with appium or adb. Its a problem with the app. Some devs are typecasting for decimal coversion from string and the lib used for it is the problem.