【问题标题】:How to read-write character devices (like /dev/ttyS0) in Android如何在 Android 中读写字符设备(如 /dev/ttyS0)
【发布时间】:2019-07-06 06:51:50
【问题描述】:

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

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

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

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

谁能指出正确的方向谢谢?

【问题讨论】:

    标签: android tty


    【解决方案1】:

    经过多次尝试,并在 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 文件的 r/w 权限,并禁用其 echo 选项。如果这些权限+选项已经正确,或者存在其他设置它们的方法,则不需要 sudo() 命令。

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

    【讨论】:

      【解决方案2】:

      Java 中的所有文件访问都是通过输入和输出流完成的。如果要打开文件,只需为其创建 FileOutputStream 或 FileInputStream。这些是无缓冲的流。如果您想写入原始字节,可以将其包装在 ByteArrayOutputStream 或 ByteArrayInputStream 中。

      要进行字符模式,您可以使用 Writer。带有 ascii 字符集的 OutputStreamWriter 可以包装 FileOutputStream。那应该为您进行字符转换。只是不要使用 FileWriter——虽然它看起来很合适,但它没有选择字符集的选项,默认值不是 ascii。要读入,请使用 InputStreamReader。

      【讨论】:

      • TY 用于回复,但我需要一个代码框架......事情很复杂,因为我需要实现一个对话框:写,等待回复,然后再写等等。对话框仅是 ASCII(带有 CR/LF 结尾)。
      • 我成功了,有兴趣可以看我的帖子。
      • @linuxfansaysReinstateMonica 我已经使用了你的代码,但是,执行 sudo 命令的两行错误,找不到 sudo 方法。
      • @linuxfansaysReinstateMonica 还有一件事是android设备必须root才能与windows pc进行串口通信?如果是,那么我们是否有任何支持文件。
      • @ChetanJoshi:使用 sudo 命令以某种方式暗示设备必须植根。如果有办法为文件 ttyS0 设置合适的权限和选项,则可能不需要超级用户权限(因此,sudo)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-23
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      相关资源
      最近更新 更多