接着上一篇,上一篇写的是产品模块通过usb口连接Android平板,Android平板通过usb host协议和产品模块通信。
实际上产品模块还可以通过串口和模块进行通信,因为我们的平板和模块都连有串口线。当然模块还可以直接和pc通过串口或者usb口通信,如果pc是笔记本的话,可以通过usb转串口的线来和模块通信,usb口的话直接连接就行了。
串口通信其实比较简单,android.serialport包下,有两个类,分别是SerialPort.java 和SerialPortFinder.java。
其中,SerialPort.java,这个类主要用来加载SO文件,通过JNI的方式打开关闭串口。
/* * Copyright 2009 Cedric Priscal * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android_serialport_api; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class SerialPort { private static final String TAG = "SerialPort"; /* * Do not remove or rename the field mFd: it is used by native method close(); */ private FileDescriptor mFd; private FileInputStream mFileInputStream; private FileOutputStream mFileOutputStream; public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { /* Check access permission */ if (!device.canRead() || !device.canWrite()) { try { /* Missing read/write permission, trying to chmod the file */ Process su; su = Runtime.getRuntime().exec("/system/xbin/su"); String cmd = "chmod 777 " + device.getAbsolutePath() + "\n" + "exit\n"; su.getOutputStream().write(cmd.getBytes()); if ((su.waitFor() != 0) || !device.canRead() || !device.canWrite()) { throw new SecurityException(); } } catch (Exception e) { e.printStackTrace(); throw new SecurityException(); } } mFd = open(device.getAbsolutePath(), baudrate, flags); if (mFd == null) { throw new IOException(); } mFileInputStream = new FileInputStream(mFd); mFileOutputStream = new FileOutputStream(mFd); } // Getters and setters public InputStream getInputStream() { return mFileInputStream; } public OutputStream getOutputStream() { return mFileOutputStream; } // JNI private native static FileDescriptor open(String path, int baudrate, int flags); public native void close(); static { try { System.loadLibrary("serial_port"); } catch (UnsatisfiedLinkError ule) { System.err.println("WARNING: Could not load serial_port library!"); } } }可以看到在构造方法中调用了动态库中的方法open,然后由此open方法返回的FileDescriptor对象构造出输入输出流。此动态库Android也有提供,libserial_port.so,可以在你的工程libs下面创建一个armeabi文件夹,然后把此so文件放入这个文件夹下就可以进行调用了。
SerialPort serialPort = null; try { serialPort = new SerialPort(new File("/dev/ttyS1"),115200,0); } catch (SecurityException e) { } catch (IOException e) { } ins = serialPort.getInputStream(); ous = serialPort.getOutputStream(); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { ous.write(sendCommand); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}).start();这样就可以顺利的和串口进行通信了。
可以看到serialPort的构造参数new File("/dev/ttyS1"),直接可以把串口当做文件来读写就行了。当然前提是必须知道是哪个串口,因为在我们的平板上只有一个串口,而且硬件上已经确定这个串口就是串口1,所以我可以这么写。如果平板上有多个串口,而我不确定模块是和平板的哪个串口连接的,那我就必须先通过类SerialPortFinder.java来寻找连接的串口,找到了之后再进行如上操作。