Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait until a command in su finishes

Tags:

android

I am running a su process in Android which itself runs the screencap utility (/system/bin/screencap) every time the user shakes their phone.

I want to wait for each screencap to finish before I allow the user to take another screencap by shaking the phone. However, using process.waitFor() doesn't work for me because I don't want to close the su process and reopen it for each screencap (because it would prompt the SuperUser app's toast, which interferes with screencaps)

So far I have:

in service's onCreate():

p = Runtime.getRuntime().exec("su");
os = p.getOutputStream();

in the shake listener handler:

if (isReady) {
  isReady = false;
  String cmd = "/system/bin/screencap -p " + nextScreenshotFullPath + "\n";
  os.write(cmd.getBytes("ASCII"));
  os.flush();

  [INSERT MAGIC HERE]
  isReady = true;

  Bitmap bm = BitmapFactory.decodeFile(nextScreenshotFullPath);
  // Do something with bm
}

Where [INSERT MAGIC HERE] is what I'm looking for - the piece of code that would wait until screencap finishes.

like image 401
Daniel Avatar asked Oct 21 '22 12:10

Daniel


1 Answers

I found a way! I echo a single character (say, 0) using the shell command echo -n 0 (-n to prevent a newline) and then reading it back. The shell won't print the character until after the screencap command is finished and the InputStream#read() method will block until it can read that character... or in code speak:

in service's onCreate():

p = Runtime.getRuntime().exec("su");
os = p.getOutputStream();
is = p.getInputStream(); // ADDED THIS LINE //

in the shake listener handler:

if (isReady) {
  isReady = false;
  String cmd = "/system/bin/screencap -p " + nextScreenshotFullPath + "\n";
  os.write(cmd.getBytes("ASCII"));
  os.flush();

  // ADDED LINES BELOW //
  cmd = "echo -n 0\n";
  os.write(cmd.getBytes("ASCII"));
  os.flush();
  is.read();
  // ADDED LINES ABOVE //

  isReady = true;

  Bitmap bm = BitmapFactory.decodeFile(nextScreenshotFullPath);
  // Do something with bm
}
like image 90
Daniel Avatar answered Nov 15 '22 07:11

Daniel