android - 如何在Android中读写字符设备(如/dev/ttyS0)

标签 android tty

我对Java和Android知之甚少。我想做的是在 Android 应用程序中打开/dev/ttyS0,它应该与串行线通信,但我迷路了。

我的设备已获得 root 权限,我可以从命令行“回显 ...>/dev/ttyS0”并从中读取内容,但我在 Java 中尝试这样做时迷路了。首先,我找不到一种方法来以简单的读写模式打开文件,而无需处理缓冲区和其他复杂问题(显然,我想要无缓冲的 I/O)。

我在互联网上搜索过,但所有示例均指的是我无法使用的 USB。然后我找到了 UartDevice 类,但它是一个从...派生正确实现的类。

我尝试使用 File 类,并将 Reader 和 Writer 类附加到它,但编译器提示,坦率地说,我不确定这是要走的路。我需要一个框架代码来开始;我错过了一个简单的 TextFile 类,它具有无缓冲的 read() 和 write() 方法,可以在同一个打开的文件上同时使用!

有人能指出我正确的方向吗?

最佳答案

经过多次尝试,借助SO站点的大量信息,我终于成功完成了任务。这是代码:

public class MainActivity
        extends AppCompatActivity {

    File serport;
    private FileInputStream mSerR;
    private FileOutputStream mSerW;

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

        // let this program to access the serial port, and
        // turn off the local echo. sudo() is a routine found here on S.O.
        sudo("chmod a+rw /dev/ttyS0");
        sudo("stty -echo </dev/ttyS0");
        
        // open the file for read and write
        serport = new File("/dev/ttyS0");
        try {
            mSerR = new FileInputStream(serport);
            mSerW = new FileOutputStream(serport);
        } catch (FileNotFoundException e) {}

        // edLine is a textbox where to write a string and send to the port
        final EditText edLine = (EditText) findViewById(R.id.edLine);
        // edTerm is a multiline text box to show the dialog
        final TextView edTerm = findViewById(R.id.edTerm);
        // pressing Enter, the content of edLine is echoed and sent to the port
        edLine.setOnKeyListener(new View.OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                // If the event is a key-down event on the "enter" button
                if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
                    // Perform action on key press
                    String cmd = edLine.getText()+"\n";
                    edTerm.append(cmd);
                    byte[] obuf = cmd.getBytes();
                    try {
                        mSerW.write(obuf);
                    } catch  (IOException e)  {}
                    edLine.setText("");

                    // read the reply; some time must be granted to the server
                    // for replying
                    cmd = "";
                    int b=-1, tries=8;
                    while (tries>0) {
                        try {
                            b = mSerR.read();
                        } catch  (IOException e)  {}
                        if (b==-1) {
                            try {
                                Thread.sleep(5);
                            } catch  (InterruptedException e)  {}
                            --tries;
                        } else {
                            tries=3;    // allow more timeout (more brief)
                            if (b==10) break;
                            cmd = cmd + (char) b;
                        }
                    }
                    // append the received reply to the multiline control
                    edTerm.append(cmd+"\n");
                    return true;
                }
                return false;
            }
        });

    }
}

请注意代码中存在 sudo() 命令:它用于授予对 ttyS0 文件的读/写权限,并禁用其echo 选项。如果这些权限+选项已经正确,或者存在其他设置它们的方法,则不需要 sudo() 命令。

注意:我相信 sudo() 命令意味着设备必须 root

关于android - 如何在Android中读写字符设备(如/dev/ttyS0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56911912/

相关文章:

java - 如何使用 egit-github Java 库登录 Github?

android - 在 Dagger 2 中异步构建依赖关系图

android - FragmentGridPagerAdapter 中未显示 CardFragment - Android Wear

c++ - 如果您可以在 C++ 中将串行数据视为文件,那么 termios 的用途是什么?

linux - Framebuffer、VT、tty 之间有什么关系?

java - (RxJava) 移植的 Groovy 方法不起作用

Android 使用设备艺术生成器进行屏幕截图

python - "scripting"vim 使用更细粒度的 python

python - 如何在 Python 3 中将用户输入的文本显示为不同的字符?

ruby - 如何通过管道以编程方式使用 sudo?