Use Appium to make a telephone call on Android device - android

I would appreciate some help with some test automation on Android devices. We use Appium and RemoteWebDriver code to access the Android emulator, open up our application, tap and move around the application UI, and this all seems to work well.
However, as part of my testing, I would like to use Appium to initiate a telephone call on the device, keep the call open for a minute or so, and then hang up. Is there away to do this through the RemoteWebDriver object?
If not, what is the recommended way to make calls on the emulator? I have seen some discussion of using direct telnet calls to the emulator, but hope there is a better way!

You may set these desired capabilities :
capabilities.setCapability("androidPackage", "com.android.dialer");
capabilities.setCapability("appActivity", "DialtactsActivity");
and use this snippet to make call via Appium :
remoteWebDriver.findElement(By.id("com.android.dialer:id/search_view")).sendKeys("NAME_OF_PERSON");
remoteWebDriver.findElements(By.id("com.android.dialer:id/dialer_search_item_view")).get(0).click();
This would make call to the first search item
try {
Thread.sleep(60000); //
} catch (InterruptedException e) {
e.printStackTrace();
}
remoteWebDriver.findElement(By.id("com.android.dialer:id/endButton")).click();
This would disconnect the call after 60 seconds.

You can use a start a phone call using ADB:
public static int makePhoneCall(AppiumDriver driver, Srting deviceId, String phoneNum, int callDuration) throws IOException, InterruptedException {
callDuration *= 1000;
cmd = "adb -s " + deviceId + " shell am start -a android.intent.action.CALL -d tel:" + phoneNum; //open a Dialer and placing a call right away
Process exec = Runtime.getRuntime().exec(cmd); //starting a call and..
Thread.sleep(callDuration);//..waiting for callDuration seconds before hangup
driver.sendKeyEvent(6);// hang up phonecall
return exec.exitValue();
}

It turns out that this is possible, though perhaps a little more painfully than I expected. I had to do two things: specify the correct app to open, and work out the xpath references to the buttons on the dial pad. The activity is com.android.contacts.activities.DialtactsActivity and the xpaths to some of the buttons are:
Number text field: /linear/linear/editText
Number 1 button: /linear/table/row[1]/imageButton[1]
Number 5 button: /linear/table/row[2]/imageButton[2]
Dial button: /linear/frame/imageButton
If anyone has a better way to do this, I'd be very pleased to see it! Martin

press home button
driver.sendKeyEvent(3);
Press call button.
dr.sendKeyEvent(5);
locate dial pad
driver.findElementById("com.android.dialer:id/dialpad_button").click();
type number by send key or by sendKeyEvents.
driver.findElement(By.className("android.widget.EditText")).sendKeys(phoneNumber);
Press call button
driver.findElementById("com.android.dialer:id/dial_button").click();
put some wait and press End call button.
dr.findElementById("com.android.dialer:id/endButton").click();

Related

I am trying to make an application that will make phone calls one after another from the list of number

I am developing an application for my friend who is in sales, this application will make phone calls one after another, as soon as one phone call gets disconnected, it will automatically make call to another number from the list. This list can be read from and xml data source or json or mongodb or even from excel sheet.
This could be an ios app that reads data from an end point and stores them and can initiate the call at any point and it wont stop until all the calls are made.
Next call will be made only after the first call has been finished.
I am thinking about using node based web app using google voice to trigger the chain.
I've no experience with ios / android apis but Im willing to work on that if it's a viable thing on that platform.
Note: what we're trying to avoid is whole process of
looking up the phone number.
touch hangup and then click for another phone number.
It should self trigger the next call as soon as current call gets disconnected.
Also we're trying to avoid any paid services like twillo.
Thanks in advance :)
for IOS, you could use CTCallCenter
self.callCenter = [[CTCallCenter alloc] init];
self.callCenter.callEventHandler = ^(CTCall *call){
if ([call.callState isEqualToString: CTCallStateConnected])
{
//NSLog(#"call stopped");
}
else if ([call.callState isEqualToString: CTCallStateDialing])
{
}
else if ([call.callState isEqualToString: CTCallStateDisconnected])
{
//NSLog(#"call played");
}
else if ([call.callState isEqualToString: CTCallStateIncoming])
{
}
};
Download phone list, loop inside phone list, make a call, listening for CTCallCenter and appdelegate's Event, detect user have finish last call, our app active again, then make the next call.
Or you can try in Demo here !

Send uiautomator command over Command Line and get a return value

I'm working with the android uiautomtor and I want to confirm Pop-Up-Windows like Bluetooth Requests. The Pop-Up appears when I want to turn on the bluetooth visibility. Then I have to confirm it by pressing the button with the text "YES". I call the method of the uiautomator by using the command line from a PC and it works as well!
I use this Code:
UiObject obj;
boolean success;
obj = new UiObject(new UiSelector().text("YES"));
success = obj.click();
This code is working in a test automation for testing the UI of an android device. So the programm, which calls the method, runs for long time and i want to know if the button was clicked correctly or not. The click()-Method returns true if the ID of the UI-Object was found. I need the return value for analyze the tests.
So here is my question:
Is it possible to return/send the boolean value of the click()-Method from the uiautomator testcase class to the command line?
If you would only want to see the value of "success", you could use:
system.out.println("success = " + success);
It's not clear to me if you want to further use this value in some other parts of your program.

Android - how to stop continuous terminal action (ping) programmaticaly?

I am working on a simple app but don't know how to stop continuous action in terminal such as PING programmatically.
I just want to know the command, then I'll add it to runtime.getruntime.exec...
I know there's a CTRL+C shortcut in pc but how do I execute this on Android?
Sorry for not adding examples, I'm writing from my phone.
Another way:
Process proc = Runtime.getRuntime().exec("ping 127.0.0.1");
proc.destroy();
As you execute your command, you get the relating process. You can use it to stop your ping, too.
You can't directly send CTRL + C, but take a look at Process.sendSignal() (Android Developers)
First, get the process ID of the ping-process.
Then you can easily send a Process.sendSignal(yourPid, Process.SIGNAL_QUIT);
After debugging for a long time I found out how to solve the problem
"Kill results without the ping statistics being returned".
Get pid of ping process.
Ex:
Progress proc = runtime.exec("ping 192.168.1.1");
where proc will be something like Process[pid=2343], so you need to extract 2343.
Then when you are reading the ping output, you can use
"Runtime.getRuntime().exec("kill -INT " + 2243);" to kill the process.
InputStreamReader reader = new InputStreamReader(proc.getInputStream());
BufferedReader buffer = new BufferedReader(reader);
String line;
while ((line = buffer.readLine()) != null) {
echo.append(line).append("\n");
if (UserStopPing) {
Runtime.getRuntime().exec("kill -INT " + temp);
}
proc.waitFor();
This program will stop ping and you will get the statistic also [variable echo].
You can try this.
There is a CTRL option on your screen. Press that and then enter c.
This might help you.
Just in case people are still looking for a solution to this -- On an Android the equivalent of CTRL+C is "Volume down button" + C on your keyboard. This should stop the ping.

Android executing SU commands in background?

I'm writing an android app that sets the max frequency, governor etc.. when the screen turns off. To do it i have a service running that receives screen on/off broadcast intents. When the screen off event fires, I read from the shared preferences and set whatever is set by the user with this function
public static void writeFile(String file, String content) {
try {
Process suProcess = Runtime.getRuntime().exec("su");
DataOutputStream out = new DataOutputStream(suProcess.getOutputStream());
out.writeBytes("echo '" + content + "' > '" + file + "'");
out.flush();
out.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
Then when the screen turns back on, i revert the system to its previous state by rewriting the files. Everything is working nicely, working as intended.
The problem is i'm noticing some lag when turning the screen on/off. Also when i turn the screen on, i see the toast message from SuperUser "App was granted su access", and it pops up once for every command. Is there a way to hide that toast message? I haven't found any way to hide a toast message from another activity. I know they can be disabled in the superuser app, but that's not ideal. I read you can write your own superuser binary but that sounds alot more complicated than simple java programming... also sounds like it could lead to security problems.
Basically i'm asking what's the best way to do this, so that it's as non-invasive to the user as possible?
I haven't used su, but I think if you don't close the stream every time it should only display toast once.

Android Java code to mimic a 2 Keystroke sequence (to perform a device screenshot)

I have been trying to get a bitmap screenshot of a SurfaceView for days but the more I look into it, there doesn't seem to be a solution at present for Android OS 2.3.4 based OSs my device from HTC.
So on to Plan B, where I just found out another blog: "On my HTC Evo 3d, all I have to do is hold the power button for 1-2 sec and then hit the home button and it takes a screen shot. No app required." Turns out this works perfectly on my tablet.
I also know from digging around there are these intents: android.intent.action.SCREEN_OFF & android.intent.category.HOME
(So I tried a bunch of code experiments to try to mimic the 2-key combo in code to get a screenshot in this brute force manor. Unfortunately without success).
So my ? -- Does anyone have any insights into a method to invoke this 'screenshot sequence' for my HTC device from java code? (Presume I need to fool the OS into thinking I am holding down the power key AND tap the Home key, simultaneously)...
More: Here is a snip of the code I am attempting:
Button click for test... ...
Thread t = new Thread() {
public void run() {
Instrumentation inst = new Instrumentation();
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_POWER);
Instrumentation inst2 = new Instrumentation();
inst2.sendKeyDownUpSync(KeyEvent.KEYCODE_HOME);
} // run
}; // thread t
Doesnt work as the inst.sendKeyDownUpSync is wrong as I need a sendKeyDown (& hold) behavior or its equivel
Many thanks for any advise. If I do get this working, I will post the solution here. Cheers GH
PS; I presume there is some custom intent under the hood doing this? Is there a system log somewhere to trey to peek at the call tree to find out what it is ?
EDIT (MORE)... 9/24/11
More. Still not working but I am heading down this path & think it is closer...
// Attempt to SIMULATE A Long press (DOWN) + HOME to tell the HTC to invoke the 'Screenshot' command (WARNING: HTC Tablet specific behavior!)
Thread tt = new Thread() {
public void run() {
final KeyEvent dapowerkey = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POWER);
Handler onesecondhandler = new Handler();
onesecondhandler.postDelayed(new Runnable() {
public void run() {
// fpr about 1 second send power down keystrokes (DOWN ONLY)
while (true) { dispatchKeyEvent(dapowerkey); }
} // we are done running on the timer past time point
}, 750); // 3/4 second key press
// send the HOME keystroke
Instrumentation inst1 = new Instrumentation();
inst1.sendKeyDownUpSync(KeyEvent.KEYCODE_HOME);
} // outer thread run tp mpt block the GUI
}; // outer thread t
tt.start();
...
Also thought if I can send the right intent directly to the proper place on the device that I might be able to kick off a screen capture function directly (which is what I really want. Through some log examinations (when you Long-Power + Home click on HTC) a program called 'com.htc.mysketcher' (FlashActivity) is being called...
Again, if I figure this out then I will post to the group... Cheers GH

Categories

Resources