How to select all text in a text field in monkeyrunner? - android

Actually I want to delete all text in a text field, and I am using a loop calling device.press('KEYCODE_DEL') to achieve this.
But there are two disadvantages:
Not efficient enough, especially when I don't know how many
characters in the text field so I need set a large enough loop
Need to move the cursor to the end before deleting
So I am trying to accomplish this by two steps:
select all text
press delete button
I found an similar question here which is not solved yet.
And there is an answer for how to select all text, but I think it has the same issues as my loop delete way.
I did several tests, and found a way close to it:
device.press('KEYCODE_MENU', 'MonkeyDevice.DOWN', '')
device.press('KEYCODE_A')
device.press('KEYCODE_MENU', 'MonkeyDevice.UP', '')
I thought these three steps accomplish a MENU+A operation. But it did not work every time. I executed this code for 20 times(in a loop) and found it only took effect for about 5-8 times.
Besides, I found these three steps will move the cursor to the first place most of the time.
Did anyone know why is this operation not reliable? Or any other suggestions to select all text?
Appreciate for any suggestions!

AndroidViewClient's EditText has a method for that:
def setText(self, text):
"""
This function makes sure that any previously entered text is deleted before
setting the value of the field.
"""
if self.text() == text:
return
self.touch()
guardrail = 0
maxSize = len(self.text()) + 1
while maxSize > guardrail:
guardrail += 1
self.device.press('KEYCODE_DEL', adbclient.DOWN_AND_UP)
self.device.press('KEYCODE_FORWARD_DEL', adbclient.DOWN_AND_UP)
self.type(text, alreadyTouched=True)

Using AndroidViewClient its pretty easy. Try this code-
editText= vc.findViewByIdOrRaise(EDITTEXT ID in quotes)
(x,y) = editText.getXY()
editText.device.drag((x,y), (x,y), 2000, 1)
vc.dump()
device.press('KEYCODE_DEL')

Related

Selecting an element on Appium / Android with Python that has same Class and Same Index of another element on UIAutomatorViewer

I am testing an app and on most of the screens I see that there are elements that have the same class "android.widget.TextView" with same index number "0". All other properties also same, only exceptions are the "text" and "bound".
I have "Skip", "Next" and "Skip Next 3" as texts on the screen which has the same attribute other than the text and bounds Attribute. I need to know how I can point appium to click on the desired item .. say I want to click on "Next", how can I do this. I am using Python for the scripting.
You can search for all matching web elements with the same class name, which will return you a list of the matching elements. Then you loop over the found elements and you compare their text, e.g :
for element in webdriver.find_elements_by_class_name('android.widget.TextView'):
if element.text == "Next":
element.click()
Doing as Chuk Ultima said will work, but if you have lots of TextView it may take a while.
You can use:
((AndroidDriver<MobileElement>)driver).findElementByAndroidUIAutomator("new UiSelector().text(\"Next\")");
See more usages in http://www.automationtestinghub.com/uiselector-android/
Well, In my case I finally solved the problem using traversing through nodes like I created xpath to get the Text (time value) from a particular location like this:
Time = self.driver.find_element_by_xpath('//android.widget.LinearLayout[#index=2]/android.view.ViewGroup[#index=0]/android.view.ViewGroup[#index=0]/android.view.ViewGroup[#index=0]/android.view.ViewGroup[#index=3]/android.view.ViewGroup[#index=0]/android.widget.TextView[#index=0]').get_attribute('text')
I understand this is a tedious process, but for the time being this is the solution for me.

Why does my looping instruction to input values for a character array of 6 elements stop after 3 inputs?

I'm new to C and programming in general. I'm stuck wondering why this thing is happening. Basically, I wrote this simple program to input a 6 character array from the user, and to print the same out. I'm using CPPDroid on my Android phone to compile and execute the code;
#include"stdio.h"
int main()
{
char c[6];
for(int i=0;i<=5;i++)
{
scanf("%c",&c[i]);
}
for(int j=0;j<=5;j++)
{
printf("%c",c[j]);
}
return 0;
}
For some reason, the first loop simply exits out before the rest of the elements are filled. I'd get an output like this (I entered a,b,s as the first 3 elements):
a
b
s
a
b
s
It just simply only takes 3 elements rather than 6, and prints them back. What's going on?
My apologies if this is a well known issue. I'm not familiar with terms used in programming much, so it's not easy for me to search for questions.
All the answers and comments mentioned it right. I will just add one more thing. Earlier the \n were also taken as input by the scanf. As a result
your loop ended and still the characters you desired were not read.
why the solution scanf("%c ",..) works?
Now, the trailing one is telling scanf() to skip any trailing
whitespace after the character input. It therefore keeps reading input
until it sees something that is not whitespace or the end of the
stream.
Also as pointed out, the leading white space would also let you achieve the same thing with the added benefit of having a smooth interactive input.
To give you an idea of what I mean I would give an excample:
int n,m;
scanf("%d ",&n);
printf("n is %d\n",n);
printf("Give 2nd number\n");
scanf("%d ",&m);
printf("m is %d\n",m);
So now you start giving input.
1
Enter
Now you expect so see the output n is 1. But it seems like it stopped.
You again type 2Enter
Now you see the output: n is 1. Then you see the output
n is 1
6<enter>
Give 2nd number
m is 2
That's what I meant when asked to avoid the trailing whitespace.
When you type in:
a
b
s
The Enter keystroke is counted as its own character (the newline character, '\n'), so you end up storing the following in c: ['a', '\n', 'b', '\n', 's', '\n'].
If you want to consume the newline, you can include it in the scanf() call; something like this:
scanf("\n%c",&c[i]);

Calculator app approach

as getting into android i decided to replace the default calculator with mine. A simple calculator with the 4 operational signs. I've been giving to all buttons the right behaviour, storing every number in a 'num' ArrayList(String) and signs in a 'sign' ArrayList(String).
What i wanted to do, was to then combine numbers and signs into a string, parse it into a float and getting a result. I thought this was one of the easy/simple ways to deal with it, since when you set a float like this:
float f = 6*4-5/2+3
it gives you the right result. but it clearly does not when starting from a String, like this:
String s = "6*4-5/2+3"
Float f = Float.valueOf(s)
Is there a way to getting a result from my 2 ArrayList(String)? In the negative case, what would be a doable approach (in the sense im not an experienced programmer)I?
I Think this approach is incorrect.
I would do the following:
You would have a Textview or Edittext as the calculator "screen" on top.
then you would have all your number and operation signs buttons.
Now, every number you press, it will append to the last one on the screen, using .append()
once you tap on an operator sign - two things will happen:
1) the number in the textView will be stored as a Float (using Float.valueOf(yourTextView); in a varibale, say firstNum.
2) you will save the operator you clicked in a second variable, say String calcOper.
Now, you enter your second number, and then you would press the Equals sign.
What will happen then is simply use a Switch of If expression.
If calcOper is "-" - then do firstNum- Current number shown on screen.
If calcOper is "+" - then do firstNum+ Current number shown on screen.
At last don't forget to set the text on the TextView the result.
Good luck!

Android: InputConnection - how to get composingtext correctly

I do backspace in textfield, and i need to set as composingText word or it part, that has left before cursor position. I must do that thing each time when i press backspace. So my step must be:
get size of last word (or part of it);
make it as composing text.
I try do it like this:
ic.setSelection(startWordPosition, word.length());
ic.setComposingText(word, 1);
All works good, while i don't test backspace in string like "a.a". It select all 3 characters, but when set, replace only part after dot.
Then i try make it like this:
ic.deleteSurroundingText(word.length(),0);
ic.setComposingText(word, 1);
But it not work correctly and delete sometimes text before my word(maybe because it currently compose).
Just find one more way that looks like right:
ic.finishComposingText();
ic.deleteSurroundingText(word.length(),0);
ic.setComposingText(word, 1);
ic.setSelection(fullInputedString.length(),fullInputedString.length());
Is it correct?
How should it be in right way?
target sdk=8
Thanks!
UPD:
I found next solution for
ic.finishComposingText();
ic.deleteSurroundingText(wordForInsert.length(), 0);
ic.setComposingText(wordForInsert, 1);
And for latest android version i use appropriate method:
ic.setComposingRegion();
But this solution provide issue in standatrd android browser for 4.0v Android and latest.

IndexOutOfBoundsException in Edit Text for android

i have an edit text in my activity.i am entering numbers in it manually but
int mystart = destinationNumber.getSelectionStart();
int myend = destinationNumber.getSelectionEnd();
numberText.getText().replace(Math.min(mystart, myend), Math.max(mystart, myend),
"1", 0, 1);
its entering fine according to the cursor position.
i have a delete button in my acitivity which deletes single character according to cursor postion.
numberText.getText().delete(myend - 1, mystart);
But this logic is not working properly when i select whole text and call delete method it gives me IndexOutOfBoundsException OR i select 4-5 digits and call this delete.
I want the same functionality as android contact dialpad number enter field.Can someone help me figure out what is the correct logic to delete single digit from edittext and multiple selected digits as well.
Thanks
delete receives the start as first parameter and end as second, not the other way around.
Probably the error its taht mystart or myend(probably this) are bigger or smoller than numberText.lenght().
Try to put a Log.d("","" ) with the lenght of the text, mystart and myend and check if you need a myend -1 or something like that.

Categories

Resources