从程序中连续读取输出并在其他地方显示该数据

时间:2018-03-16 21:09:07

标签: java android runtime bufferedreader outputstream

我试图从一个输出数据的程序中读取,然后在我的GUI上连续显示该数据。具体来说,我已经将旋转编码器作为输入设备连接到我的Raspberry Pi 3,它运行在Android OS(4.4 - KitKat)上。当我与旋转编码器进行物理交互时,当我从终端中的/ dev / input / eventX中的“getevent”工具中读取时,我看到旋转编码器正在移动时弹出数据。

我正在尝试读取数据,因为它被输出并几乎立即读取数据并实时显示在我的GUI上(或者延迟非常小)。

所以我试图做的事情如下:

1)在我的GetEventRecorder类中,我编写以打开getevent工具,然后从中读取输出。我使用scheduleAtFixedRate重复此过程(延迟很小)。此工具保持打开状态,直到我关闭它。我相信我需要关闭工具才能从中读取输出。所以我关闭它的目的是在之后再打开它。我认为这可能会导致我在下面描述的部分问题。

2)在我的MainActivity()中,我有一个textView,我定期更新(小延迟),它接收来自第1部分的读取数据。我在RunThread中执行此操作。

问题:只有在工具关闭后,我才会看到屏幕上显示的数据。但是,我似乎没有看到数据,直到它关闭(我认为这是正常的)。但是,此后我似乎无法读取任何新输入,只有工具关闭前的输入。但我想继续阅读数据,似乎无法做到这一点。请在下面找到我的代码。由于这是我的第一篇文章,请提出任何问题,以便我可以帮助进一步澄清我的情况等。

MainActivity:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

TextView textElement;
private String myOutput;
private GetEventRecorder getEventRecorder;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textElement = (TextView) findViewById(R.id.firstTextView);
    getEventRecorder = new GetEventRecorder();

    init_all();
    runThread();
}

public void init_all() {
    getEventRecorder.start();
}

private void runThread() {
    new Thread() {
        public void run() {
            while (true) {
                try {
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            myOutput= getEventRecorder.logGetEventData();
                            textElement.append(myOutput);
                        }
                    });
                    Thread.sleep(1000);
                    }
                    catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();
}
}

GetEventRecorder:

import java.io.OutputStream;
import java.util.Timer;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.TimerTask;

public class GetEventRecorder {

private GetEventRecorder mRecorder = null;
Timer timer;
String err = "initial";

// active su session
private Process mProcess;
// Byte Writer
private DataOutputStream outputStream;
private BufferedReader br;
private StringBuilder text = new StringBuilder();
private int i = 0;

{
    try {
        mProcess = Runtime.getRuntime().exec("su");

        outputStream = new DataOutputStream(mProcess.getOutputStream());
        String comm1 = "getevent -c 2 /dev/input/event1";
        String newLine = "\n";

        outputStream.writeBytes(comm1);
        outputStream.writeBytes(newLine);

    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void start() {
    try {

        timer = new Timer();
        timer.scheduleAtFixedRate(new GetEventRecorder.RecorderTask(), 0, 
1000);
    } catch (Exception e) {

    }
}

public void stop() {
    if (mRecorder != null) {
        mRecorder.stop();
        mRecorder = null;
        timer.cancel();
    }
}

private class RecorderTask extends TimerTask {


    @Override
    public void run() {
        try {
            String close = "^C";

            outputStream.writeBytes(close);
            outputStream.flush();

            br = new BufferedReader(new InputStreamReader(mProcess.getInputStream()));

            String line;

            if (br != null) {
                if (br.ready()) {
                    while ((line = br.readLine()) != null) {
                        text.append(line);
                        text.append("\n");
                    }
                }
            }
        } catch (Exception e) {
            err = "error_1";
        }
    }
}

public String logGetEventData() {
    if (text != null) {
        String retour = text.toString();
        return retour;
    } else {
        return "err_log";
    }
}
}

1 个答案:

答案 0 :(得分:0)

我对你的术语感到困惑,因为你提到"打开getevent文件"。我相信getevent是Android上的工具(程序)。请参阅https://android.googlesource.com/platform/system/core.git/+/android-4.2.2_r1/toolbox/getevent.chttps://source.android.com/devices/input/getevent

根据您的代码,看起来您正在创建一个超级用户shell作为子进程,通过向子进程发送命令来运行getevent(将继续创建子进程),然后循环发送^ C到子进程。

  • 您将-c 2传递给getevent,这意味着它会读取两个值并退出。

  • ^C到shell进程会终止进程。因此,您并未真正关闭此处的文件。

  • 您正在产生的shell不是交互式的,因此可能无法启用作业控制功能。所以^C可能无论如何都不起作用。 (不是100%肯定这个。)

  • 您无法在任何地方重新运行getevent,因此如果因任何原因(例如之前的列表)停止输出,您将无法再看到任何内容。< / p>

因此,要实现您想要的方式,您需要重新生成getevent。这就是您现在在静态初始化块中拥有的代码。

正如进一步的评论一样,这对你正在做的事情来说似乎有些过分。您真的想直接从事件设备中读取。您似乎使用此方法解决的唯一问题可能是设备文件的权限。