0

I am using my Android app to launch a native binary. I would like to display the output of that binary in a small window in my application. How would I go about either displaying the output in a TextView or showing the terminal in a small window (preferred)?

Thanks.

jbrew
  • 145
  • 2
  • 13
  • Welcome to StackOverflow. What exactly is the problem - you're not sure how to capture the output into a variable, or you're not sure how to display said variable in a window? Note that calls for ready to use, complete solutions normally go unheeded here at SO. For that, Rent-A-Coder exists. – Seva Alekseyev Oct 01 '12 at 14:27
  • I'm not looking for a full code solution, I'm looking for a suggested path or an Android SDK package/method that allows you to display the command line execution of my binary. – jbrew Oct 01 '12 at 15:22
  • It's not a single method, it's a fairly involved piece. The cleanest way of doing this would probably involve dropping to the NDK level. Without that, you can probably use an intermediate file and shell-level input redirection. I'll sketch out the latter for you. – Seva Alekseyev Oct 01 '12 at 15:27
  • How is _"showing the terminal in a small window"_ different from a small TextView? – Alex Cohn Oct 01 '12 at 18:49

2 Answers2

1

The gist of the article that Alex linked to is that Runtime.exec() returns a Process object, which lets you get the process' standard output (and stderr, too) as Java streams via Process.getOutputStream()/getErrorStream(). Get them, read them in a thread (they do properly block - you don't want to block the UI thread), pass the data back to the UI thread. Much, much better. I rescind my previous answer.

The article also recommends wrapping the stream in a BufferedReader so that you can do readLine.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
0

Here's one scheme. NDK is not necessary for this one.

You create a temporary file in your app's data dir. You run the binary, specifying the same file as an output direction in the command line using Runtime.exec(). The command line you'll have to specify would invoke not the binary itself, but sh, and one of the command line parameters would be a redirection: >myfile.txt.

You then start a worker thread that reads the same file. You'll need to carefully implement new data detection - as this is a file, not a pipe, the reading operation will simply terminate once the end of file is reached; it won't block until new data appears.

Then you pass the data from the worker thread using Activity.runOnUiThread() or Handler.post() to the main thread, where it's used to update TextView's content.

A cleaner way would involve creating a pipe pair with mkfifo() and redirecting output in place using dup2() from a pipe handle to the file handle value 1 (stdout). That's how they normally do it in the C/Linux world. There's probably an Android example out there, I've never done that.

Oh, and before you do all that, make sure the binary does not have a more palatable interface. More often than not, Linux binaries are based on a static/dynamic library where all the yummy functionality is, one that can be linked with and called directly.

EDIT: Especially if it's logcat. There are other ways to read a log in Android.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • Thanks, I like the suggestion of using a file as an interface to both levels. In this case libpcap and libpthread are being utilized, but there is a lot of other functionality that I need in the binary that doesn't exist in a library. – jbrew Oct 01 '12 at 17:04
  • If the answer solves your problem, please accept it. I still think that the `mkfifo()/dup2()` avenue is worth pursuing, but the code will get considerably hairier. Up to you. – Seva Alekseyev Oct 01 '12 at 17:22
  • You don't need temporary files, and don't have to worry about pipes, and have no reason to dig into NDK. Java provides a clean and rich mechanism for capturing output from child processes, see for example http://stackoverflow.com/questions/882772/capturing-stdout-when-calling-runtime-exec – Alex Cohn Oct 01 '12 at 20:55
  • @Alex Cohn: why don't you write an answer of your own, rather than comment on mine? SO was kind of meant for this sort of thing... – Seva Alekseyev Oct 01 '12 at 21:27
  • I did not post an answer, first of all, because I did not understand the question, re: terminal vs. TextView. Also, it would require lots of typing, and I was far from my keyboard (and still am). But I thought that the correction was necessary, and even urgent, and I think you did a great job adding a separate answer about it. – Alex Cohn Oct 02 '12 at 05:36