最近在做自动售货机的程序,需要用到串口,经过几天的时间终于搞明白了,先来个效果图,下面是我发送的数据和接收数据的图片,下面直接上代码:
新建一个类:SerialPortFinder,添加如下代码:
public class SerialPortFinder {
public class Driver {
public Driver(String name, String root) {
mDriverName = name;
mDeviceRoot = root;
}
private String mDriverName;
private String mDeviceRoot;
Vector<File> mDevices = null;
public Vector<File> getDevices() {
if (mDevices == null) {
mDevices = new Vector<File>();
File dev = new File("/dev");
File[] files = dev.listFiles();
int i;
for (i=0; i<files.length; i++) {
if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) {
Log.d(TAG, "Found new device: " + files[i]);
mDevices.add(files[i]);
}
}
}
return mDevices;
}
public String getName() {
return mDriverName;
}
}
private static final String TAG = "SerialPort";
private Vector<Driver> mDrivers = null;
Vector<Driver> getDrivers() throws IOException {
if (mDrivers == null) {
mDrivers = new Vector<Driver>();
LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers"));
String l;
while((l = r.readLine()) != null) {
// Issue 3:
// Since driver name may contain spaces, we do not extract driver name with split()
String drivername = l.substring(0, 0x15).trim();
String[] w = l.split(" +");
if ((w.length >= 5) && (w[w.length-1].equals("serial"))) {
Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length-4]);
mDrivers.add(new Driver(drivername, w[w.length-4]));
}
}
r.close();
}
return mDrivers;
}
public String[] getAllDevices() {
Vector<String> devices = new Vector<String>();
// Parse each driver
Iterator<Driver> itdriv;
try {
itdriv = getDrivers().iterator();
while(itdriv.hasNext()) {
Driver driver = itdriv.next();
Iterator<File> itdev = driver.getDevices().iterator();
while(itdev.hasNext()) {
String device = itdev.next().getName();
String value = String.format("%s (%s)", device, driver.getName());
devices.add(value);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return devices.toArray(new String[devices.size()]);
}
public String[] getAllDevicesPath() {
Vector<String> devices = new Vector<String>();
// Parse each driver
Iterator<Driver> itdriv;
try {
itdriv = getDrivers().iterator();
while(itdriv.hasNext()) {
Driver driver = itdriv.next();
Iterator<File> itdev = driver.getDevices().iterator();
while(itdev.hasNext()) {
String device = itdev.next().getAbsolutePath();
devices.add(device);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return devices.toArray(new String[devices.size()]);
}
新建SerialPort类,这个类主要用来加载SO文件,通过JNI的方式打开关闭串口
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/bin/su");
String cmd = "chmod 666 " + 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) {
Log.e(TAG, "native open returns 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 {
System.loadLibrary("serial_port");
}
}
发送和接收串口的Activity
public class ComAActivity extends Activity {
EditText editTextRecDisp;
Button ButtonSendCOMA;
SerialControl ComA;//串口
DispQueueThread DispQueue;//刷新显示线程
SerialPortFinder mSerialPortFinder;//串口设备搜索
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
ComA = new SerialControl();
DispQueue = new DispQueueThread();
DispQueue.start();
setControls();
//开启串口
ComA.setPort("/dev/ttyS2");
ComA.setBaudRate("115200");
OpenComPort(ComA);
}
@Override
public void onDestroy() {
CloseComPort(ComA);
super.onDestroy();
}
@Override
public void onBackPressed() {
AseoZdpAseo.initPush(this);
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addCategory(Intent.CATEGORY_HOME);
AseoZdpAseo.initFinalTimer(this);
startActivity(intent);
}
//----------------------------------------------------
private void setControls() {
editTextRecDisp = (EditText) findViewById(R.id.editTextRecDisp);
ButtonSendCOMA = (Button) findViewById(R.id.ButtonSendCOMA);
ButtonSendCOMA.setOnClickListener(new ButtonClickEvent());
mSerialPortFinder = new SerialPortFinder();
String[] entryValues = mSerialPortFinder.getAllDevicesPath();
List<String> allDevices = new ArrayList<String>();
for (int i = 0; i < entryValues.length; i++) {
allDevices.add(entryValues[i]);
}
}
//----------------------------------------------------清除按钮、发送按钮
class ButtonClickEvent implements View.OnClickListener {
public void onClick(View v) {
if (v == ButtonSendCOMA) {
sendPortData(ComA, "01023101000035");
}
}
}
//----------------------------------------------------串口控制类
private class SerialControl extends SerialHelper {
public SerialControl() {
}
@Override
protected void onDataReceived(final ComBean ComRecData) {
DispQueue.AddQueue(ComRecData);//线程定时刷新显示(推荐)
}
}
//----------------------------------------------------刷新显示线程
private class DispQueueThread extends Thread {
private Queue<ComBean> QueueList = new LinkedList<ComBean>();
@Override
public void run() {
super.run();
while (!isInterrupted()) {
final ComBean ComData;
while ((ComData = QueueList.poll()) != null) {
runOnUiThread(new Runnable() {
public void run() {
DispRecData(ComData);
}
});
try {
Thread.sleep(100);//显示性能高的话,可以把此数值调小。
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
}
public synchronized void AddQueue(ComBean ComData) {
QueueList.add(ComData);
}
}
//----------------------------------------------------显示接收数据
private void DispRecData(ComBean ComRecData) {
StringBuilder sMsg = new StringBuilder();
sMsg.append(ComRecData.sRecTime);
sMsg.append("[");
sMsg.append(ComRecData.sComPort);
sMsg.append("]");
sMsg.append("[Hex] ");
sMsg.append(MyFunc.ByteArrToHex(ComRecData.bRec));
sMsg.append("\r\n");
/**
* 接收串口的数据返回值,并且做相应的处理
*/
editTextRecDisp.append(sMsg);
String[] temp = MyFunc.StrToStrArray(MyFunc.ByteArrToHex(ComRecData.bRec));
if (temp.equals("FF 01 01 01 02 01 04 ")) {
Toast.makeText(ComAActivity.this, "您连接了主板", Toast.LENGTH_SHORT).show();
}
}
//----------------------------------------------------串口发送
private void sendPortData(SerialHelper ComPort, String sOut) {
if (ComPort != null && ComPort.isOpen()) {
ComPort.sendHex(sOut);
}
}
//----------------------------------------------------关闭串口
private void CloseComPort(SerialHelper ComPort) {
if (ComPort != null) {
ComPort.stopSend();
ComPort.close();
}
}
//----------------------------------------------------打开串口
private void OpenComPort(SerialHelper ComPort) {
try {
ComPort.open();
} catch (SecurityException e) {
ShowMessage("打开串口失败:没有串口读/写权限!");
} catch (IOException e) {
ShowMessage("打开串口失败:未知错误!");
} catch (InvalidParameterException e) {
ShowMessage("打开串口失败:参数错误!");
}
}
//------------------------------------------显示消息
private void ShowMessage(String sMsg) {
Toast.makeText(this, sMsg, Toast.LENGTH_SHORT).show();
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/LinearLayoutRecDisp"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<EditText
android:id="@+id/editTextRecDisp"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:clickable="false"
android:editable="false"
android:gravity="top"
android:longClickable="false"
android:textSize="14sp" />
</LinearLayout>
<Button
android:id="@+id/ButtonSendCOMA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送" />
</LinearLayout>
综合以上就可以实现串口间的通讯;程序考进去以后有问题可直接留言给我,我会为大家解答
整个Demo下载地址:http://download.csdn.net/download/chen_xiaobao/9929474