Running a UiAutomator test via android app - android

I have some test built, and my testing department can't figure out how to use the terminal. Uiautomator test are .jar files so must be ran via terminal. So for convenience, I want to make an app for them with the tests in a list to choose from to execute. Is this possible? My research leads me to believe that the devices will need to be rooted. If that is the case I will not be able to do it. So is there a workaround to this? This is what I have tried:
Runtime rt = Runtime.getRuntime();
try {
Process process = rt.exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("uiautomator runtest test.jar -c ui.test.getData\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
This code will produce this :
java.io.IOException: Error running exec(). Command: [su] Working Directory: null Environment: null
Please help me with a way to get this to work. Thanks!

Do you have suggestions of something I could do to make it easy for my testing team to run a test of mine?
Create a desktop app that runs the test.
Or, just put a nice batch file/shell script in front of it. Perhaps one that launches the test and displays a photo of a cute kitten in the tester's Web browser.
(testers love cute kittens)
Or, set up a continuous integration server, so testers are not manually running the tests at all -- the tests are run automatically, and the testers are simply examining the results. I presume that somebody has a recipe for Hudson/Jenkins/whatever that can run an uiautomator test. And there may be a separate recipe for integrating photos of cute kittens into the test result reports, though it is possible that you'll be stuck writing your own for that.

Related

Complete terminal control on android

I have been trying to run a few Linux commands on my android phone with
Process process = Runtime.getRuntime().exec(COMMAND);
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
And noticed that I can only run specific commands and get the proper output even if the device is rooted with SuperSU (I have also tested it with a device without SuperSU on it).
For example, if I run ls and try to put it on a screen (through a TextView) as follows:
public void onBtnClick(View view) {
try {
EditText commandLine = findViewById(R.id.commandText);
Process process = Runtime.getRuntime().exec(commandLine.getText().toString());
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
((TextView) findViewById(R.id.mainTextView)).setText(((TextView) findViewById(R.id.mainTextView)).getText() + "\n" + in.readLine());
commandLine.setText("");
} catch (IOException e) {
e.printStackTrace();
}
}
the output is acct which makes sense.
But on the other hand, if lets say I run pwd it gives me the following error:
W/System.err: java.io.IOException: Error running exec(). Command:
[pwd] Working Directory: null Environment: null
I did some research online and stumbled upon Termux that can have complete control over the phone through a terminal which is exactly what I'm looking to make (for my own learning and testing purposes).
And although it's just an emulator it can do exactly what I want but the only problem is that it requires I input the commands through the terminal.
What I'm here for is to sort of replicate what Termux does for myself so that I could run Linux commands properly from the Java code of the application, not requiring the user to actually input commands.
Can anyone help me with where to start and the basics of running those commands properly on my device?
Termux states that it doesn't work as a traditional Linux bash does since it sets its own virtual-ish environment when first setting up in its data directory in /data/data/com.termux/files/usr see here and here
Also, according to the official android docs, the exec(command) method,
Executes the specified string command in a separate process.
This is a convenience method. An invocation of the form exec(command)
behaves in exactly the same way as the invocation exec(command, null,
null).
So if it's a separate process, when executing a command, it will run it inside that process' directory (Each process in Linux gets its directory and is assigned an PID which os uses). So what the ls command gives you is simply whatever's inside that process' directory. You should be somewhere like /proc/31415/ and there's only a acct file (cgroup in regular Linux).
What you should be doing is running the command inside a directory by declaring it when invoking getRuntime().exec() see the link above to find the right one you'll need. I'd suggest using the override which handles all the parameters.
You'll need something like this:
String[] cmd = {"mkdir", "testDir"};
File env = new File(getFilesDir().getAbsolutePath());
Runtime.getRuntime().exec(cmd, null, env);
Also, it doesn't hurt to take a look at Termux's installer code (exec(). It'll give you a good overlook to setting up your environment as well as working with basic commands.
Also, I think you've done it already but double check to make sure that you're requesting WRITE_EXTERNAL_STORAGE permission for your application.

AT Command: USSD

I am trying to make USSD call to send AT command. When I execute code, I get following error:
"Error running exec(). Command: [AT+CUSD=1,"*222#",15] Working Directory: null Environment: null"
My code is:
String args="AT+CUSD=1,\"*222#\",15";
try {
java.lang.Process process=Runtime.getRuntime().exec(args);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
Log.e("zoraf",bufferedReader.toString());
} catch (IOException e) {
e.printStackTrace();
}
What can be done to solve this issue ?
It seams that you lack some basic understanding of what AT commands are and how they operate. AT commands are not something that you pass to a shell or the operating system like Runtime.getRuntime().exec(args) implies. AT commands are text command that you send to a modem over a serial interface (e.g. USB, Bluetooth, RS-232 or a virtual one).
The absolutely best place for you to start is to read all of chapter 5 of the V.250 specification. It is an extremely important document that will guaranteed teach you much more about AT commands than you currently know.

How to run root commands from Android application?

I want to write an application which roots the device on which it is installed, I mean by installing this app you will be able to root your device without a computer, just like the app in the following link,
http://www.kingoapp.com/root-tutorials/how-to-root-android-without-computer.htm
I've searched a lot on how to do that using Java code for Android devices, but there was no clear solution to me. Based on my research, I think we need the following steps:
1- Being able to use shell commands in Android using Runtime.getRuntime().exec();
2- Executing a command that gains root privileges (I think su, but this needs a rooted device to be executed).
3- Initiate a root command that will root the device.
I couldn't find a code explanation on how to do the steps above. I want to understand this process first, the commands that can be used in it, then I want to try to implement it by myself. Since there are many apps on the store that offer this feature, then implementing it must be feasible.
Could anyone please explain to me how to implement this process?
Also, is there a possibility to write a code for the opposite process, which is unrooting the device?
Any help is appreciated.
Thanks.
To run root commands, you have to use the following format:
public void RunAsRoot(String[] cmds){
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd+"\n");
}
os.writeBytes("exit\n");
os.flush();
}
where you pass in an array of strings, each string being a command that needs to be executed. For example:
String[] cmds = {"sysrw", "rm /data/local/bootanimation.zip", "sysro"};

Is it possible to run "pm create-user Name" command programmatically?

I am able to create the multiple user profile on Jellybean using "pm create-user Name" terminal command on Emulator, but I want to know is there any way so I can run the same command programmatically. I don’t want to open the terminal.
When the Multiple User feature was first found in 4.1, I wrote an app to do just this. I've open sourced it here. You can find the code for running that command programmatically in TerminalUtils, but I'll put it in the answer as well.
public static void createUser(String name)
{
Process p;
try {
p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("pm create-user \"" + name + "\"\n");
os.writeBytes("exit\n");
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
TerminalUtils also contains methods to remove and rename users.
Yes you can by :
Using Stericson RootTools :
RootTools provides rooted developers a standardized set of tools for
use in the development of rooted applications. In the end, we will
accomplish this by providing developers with robust, easy-to-use
libraries that will drastically improve development times as well as
promote code reuse. This project is open to any proven developer that
feels they have something to contribute. By pitching in together we
can streamline our own processes, improve the effectiveness of our
apps, learn new techniques, and provide a better experience for our
users.
Using Android Runtime :
Allows Java applications to interface with the environment in which
they are running. Applications can not create an instance of this
class, but they can get a singleton instance by invoking getRuntime().

Android Terminal and Log Dumping

I am trying to send terminal commands programmaticly from an android activity. At the moment I'm using something like the following:
Process process = null;
DataOutputStream os = null;
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes("./data/program1\n");
os.writeBytes("./data/program2\n");
os.writeBytes("exit\n");
os.flush();
However, my program1 is failing to run successfully and I believe it is due to inadequate user permissions. Now for my question:
Does anyone know how I can dump the terminal to a file and save it on the phone or sdcard? The program is tying into the terminal to feed it commands, I want to know a way to open a connection the otherway and access the (what is normally visual on a terminal screen) output.
See the sources for the Terminal application, as that is bidirectional.
Sadly, running shell commands or launching native processes is not an officially supported part of android, so no future stability is guaranteed.

Categories

Resources