android - 如何在 Android 中读写字符设备(如 /dev/ttyS0)
问题描述
我对Java和Android知之甚少。我想做的是在应该与串行线路对话的Android应用程序中打开/dev/ttyS0,但我迷路了。
我的设备已植根,从命令行我可以“回显 ...>/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 文件的 r/w 权限,并禁用其echo选项。如果这些权限+选项已经正确,或者存在其他设置它们的方法,则不需要 sudo() 命令。
注意:我相信 sudo() 命令意味着设备必须是root的。
推荐阅读
- oracle - Oracle DB 中 ENUM 列的 Liquibase 'addCheckConstraint' 允许任何字符
- python - 用正则表达式捕捉第一场比赛 - PYTHON
- sql - 带有一个额外的自定义条件列的 Oracle 查询
- mysql - MySQL左连接中的语法问题
- python-3.x - None appereance in a if statment
- python - 在 selenium 中使用“webdriver.Chrome()”时出错
- python - 将文本字符串转换为数据框 - 逗号分隔
- c# - 如何使用 ML.Net 执行具有许多特征的二元分类
- lua - 如果条件不满足,则在 Lua 上中断 while 循环
- angular - 如何将 ngbCarousel 箭头从图像中移开