Note: this question isn't necessary just for Android developers. It should be the same for Java developers that performed root operations on Linux too.
Background
My app allows the user the perform various root operations (an operation that can only be performed on rooted devices).
Until now, each time the app wishes to perform a root operation, I had opened a new process using the Runtime.getRuntime().exec("su") command.
I wish to improve the way the app works, by calling this command only once, and then writing to the outputStream and reading from the inputStream while doing so.
A similar app that does this is "Terminal emulator". Once you type there "su" (and grant it root permission), it will allow you go perform any root operation and read any path of the device.
The problem
It seems that only the "echo" command works, but any other command doesn't. Also, I couldn't think of a good way to separate between the root operations output.
What I've tried
First, in order to initialize the root batching operations, I did this:
process=Runtime.getRuntime().exec("su");
_inputStreamReader=new BufferedReader(new InputStreamReader(process.getInputStream()));
_out=process.getOutputStream();
final String testLine=Long.toString(System.currentTimeMillis());
_out.write(("echo "+testLine+"\n").getBytes());
_out.flush();
final String resultLine=_inputStreamReader.readLine();
if(resultLine==null)
{
_out.write("exit \n".getBytes());
_out.flush();
_out.close();
_out=null;
_inputStreamReader.close();
_inputStreamReader=null;
process.waitFor();
return false;
}
while(!resultLine.equals(testLine))
resultLine=_inputStreamReader.readLine();
return true;
the code above (is supposed to) ensures I have root and that I can continue working on the "_out" and "inputStreamReader" . the call to "echo" has 2 purposes : to have some fake operation being done, and to also become a starting point and a separator between commands.
Here the second purpose is fake, but for each operation that I make further, this is how I thought of handling the separation of various root operations.
Now, if I want to make another root operation (assuming the above works fine), this is an example of an operation I wish to perform :
_out.write(("find "+someFolderPath+"/* -type f\n").getBytes());
_out.flush();
final String line=_inputStreamReader.readLine();
Thing is, it gets stuck on the "readLine" part, even though it should return a list of all of the file/folders within the specified path.
This command works perfectly using the previous way I performed root operations, and it should work here too.
using "echo" before those lines and then using "readLine()" shows that it's still available, as I will still get the result line. However, trying to call "readLine()" again (after the above command) will still make it stuck.
I've also tried adding "su" (or "su -" or "su -c") before the "find" command, but it didn't help.
This is the old code, which works fine:
final Process p=Runtime.getRuntime().exec("su");
final InputStream inputStream=p.getInputStream();
final DataOutputStream os=new DataOutputStream(p.getOutputStream());
os.writeBytes("find "+someFolderPath+"/* -type f\n");
os.writeBytes("exit\n");
os.flush();
//read from the inputstream (using BufferedReader) as much as I wish, till it ends.
The question
How should I avoid re-creating new processes for root operations? Is this a good way to do it?
How can I fix the above code? What is wrong with it?
Also, Is there a good way to run multiple root operations using a single "su" command, yet without any kind of separator like the one I've used (so that I could differentiate when a new command output starts and the previous one ends).