[英]How to read-write character devices (like /dev/ttyS0) in Android
I have little knowledge of Java and Android. 我对Java和Android知之甚少。 What I am trying to do is to open /dev/ttyS0 in an Android App which should talk to the serial line, but I am getting lost. 我想做的是在应该与串行线路通讯的Android应用程序中打开/ dev / ttyS0,但我迷路了。
My device is rooted, and from a command line I can "echo ...>/dev/ttyS0" and also read from it, but I get lost trying to do that in Java. 我的设备已扎根,并且可以从命令行“回显...> / dev / ttyS0”并从中读取信息,但是我迷失了在Java中尝试这样做的迷路。 For start, I can not find a method to open a file in simple read-write mode, without coping with buffers and other intricacies (clearly, I want unbuffered I/O). 首先,我没有找到一种方法来以简单的读写模式打开文件,而没有应对缓冲区和其他复杂问题(显然,我想要无缓冲的I / O)。
I searched the Internet, but all examples refer to USB which is not available for me. 我搜索了Internet,但是所有示例都涉及我不可用的USB。 Then I've found the UartDevice class, but it is a class to derive a proper implementation from... 然后我找到了UartDevice类,但这是一个从中派生适当实现的类。
I tried to use the File class, and attach to it both a Reader and a Writer class, but the compiler complains and, frankly, I am not sure it is the way to go. 我尝试使用File类,并将Reader类和Writer类都附加到该类上,但是编译器抱怨,并且坦率地说,我不确定这是否可行。 I would need a skeleton code to start from; 我需要一个框架代码来开始; I miss a simple TextFile class with unbuffered read() and write() methods to be used at the same time on the same open file! 我想念一个简单的TextFile类,该类具有无缓冲的read()和write()方法,它们将在同一打开文件上同时使用!
Can someone point me in the right direction thanks? 有人可以指出我正确的方向吗?
All File access in Java is done via input and output streams. Java中的所有文件访问都是通过输入和输出流完成的。 If you want to open a file, you simply create a FileOutputStream or FileInputStream for it. 如果要打开文件,只需为其创建FileOutputStream或FileInputStream。 These are unbuffered streams. 这些是无缓冲的流。 If you then want to write raw bytes you can wrap that in a ByteArrayOutputStream or ByteArrayInputStream. 然后,如果要写入原始字节,可以将其包装在ByteArrayOutputStream或ByteArrayInputStream中。
To do character mode, you can use a Writer. 要进行字符模式,可以使用Writer。 An OutputStreamWriter with a charset of ascii can wrap the FileOutputStream. 具有ascii字符集的OutputStreamWriter可以包装FileOutputStream。 That should do the character conversion for you. 那应该为您做字符转换。 Just don't use a FileWriter- while it seems like the right fit, it has no option to select a character set, and the default is not ascii. 只是不要使用FileWriter,虽然看起来很合适,但它没有选择字符集的选项,默认值不是ascii。 For reading in, use an InputStreamReader. 要读入,请使用InputStreamReader。
After many tries, and with the help of much information from the SO site, I finally succeded in the task. 经过多次尝试,并在SO站点提供的大量信息的帮助下,我终于成功完成了任务。 Here is the code: 这是代码:
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;
}
});
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.