尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Android 串口通信之间的发送数据与接收数据(详解)
大家好我是陈志宝一名天津全栈软件开发工程师。本篇记录开发时遇到的问题以及解决方案。最近在做自动售货机的程序需要用到串口经过几天的时间终于搞明白了先来个效果图下面是我发送的数据和接收数据的图片下面直接上代码新建一个类SerialPortFinder添加如下代码public class SerialPortFinder { public class Driver { public Driver(String name, String root) { mDriverName name; mDeviceRoot root; } private String mDriverName; private String mDeviceRoot; VectorFile mDevices null; public VectorFile getDevices() { if (mDevices null) { mDevices new VectorFile(); File dev new File(/dev); File[] files dev.listFiles(); int i; for (i0; ifiles.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 VectorDriver mDrivers null; VectorDriver getDrivers() throws IOException { if (mDrivers null) { mDrivers new VectorDriver(); 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() { VectorString devices new VectorString(); // Parse each driver IteratorDriver itdriv; try { itdriv getDrivers().iterator(); while(itdriv.hasNext()) { Driver driver itdriv.next(); IteratorFile 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() { VectorString devices new VectorString(); // Parse each driver IteratorDriver itdriv; try { itdriv getDrivers().iterator(); while(itdriv.hasNext()) { Driver driver itdriv.next(); IteratorFile 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); } }发送和接收串口的Activitypublic 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(); ListString allDevices new ArrayListString(); 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 QueueComBean QueueList new LinkedListComBean(); 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 version1.0 encodingutf-8? LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthfill_parent android:layout_heightfill_parent android:orientationvertical LinearLayout android:idid/LinearLayoutRecDisp android:layout_widthmatch_parent android:layout_heightfill_parent android:layout_weight1 EditText android:idid/editTextRecDisp android:layout_widthfill_parent android:layout_heightmatch_parent android:layout_weight1 android:clickablefalse android:editablefalse android:gravitytop android:longClickablefalse android:textSize14sp / /LinearLayout Button android:idid/ButtonSendCOMA android:layout_widthwrap_content android:layout_heightwrap_content android:text发送 / /LinearLayout综合以上就可以实现串口间的通讯程序考进去以后有问题可直接留言给我我会为大家解答作者陈志宝 | 志尊宝整个Demo下载地址http://download.csdn.net/download/chen_xiaobao/9929474
RELATED

相关推荐

无人机控制器不止是遥控器:飞控、协议、链路全解析

无人机控制器不止是遥控器:飞控、协议、链路全解析

简介:面向无人机飞行控制场景的C工程源码包,适合飞控开发学习者与嵌入式软件工程师,帮助理解多旋翼/小型无人机在姿态控制、任务调度与无线通信方面的软件实现。包内为可编译的模块化飞控项目,按src、tasks、config、monitor、wir…

📅 2026/10/21 6:13:35
大模型API接入实战:从流式输出到企业级应用落地

大模型API接入实战:从流式输出到企业级应用落地

2026 年上半年智谱营收达到 9.54 亿元,同比增长 399.7%,亏损进一步收窄到 20.71 亿元,这个数据在 AI 圈子里引发了不少讨论。很多人第一反应是“大模型公司终于开始赚钱了”,但作为技术开发者,我更关心的是&#xff1a…

📅 2026/10/22 12:11:34
PX4与Gazebo SITL仿真:从环境搭建到多机编队实战指南

PX4与Gazebo SITL仿真:从环境搭建到多机编队实战指南

简介:本资源是一套面向无人机控制与多智能体协同研究者的PX4四旋翼软件在环(SITL)仿真完整实践方案,聚焦自动驾驶/无人机前沿技术领域,适用于高校科研、研究生课题及ROS机器人开发工程师。资源涵盖PX4飞控栈集成、Gaze…

📅 2026/10/26 11:56:37
MORE NEWS

更多资讯

📰

WOA优化VMD参数K与α:包络熵适应度及Matlab实战避坑

简介:面向计算机、电子信息工程、数学等专业学生及信号处理初学者,这份PDF资料围绕Matlab环境下的WOA-VMD展开,重点解决VMD中模态数K与惩罚因子alpha难以人工选取的问题。内容以鲸鱼优化算法自动寻优为主线,结合边际谱、频率图、收…

📰

AIGC落地实战:从重复工作流中识别高价值切口

1. 这不是概念炒作,而是正在发生的生产力迁移 “AIGC:一个值得探索的新蓝海?”——这个标题里藏着两个关键信号:一个是“ AIGC ”,它早已不是实验室里的名词,而是每天在设计师的图层面板里生成草稿、在运…

📰

CSP-J初赛选择题训练2021:分块刷题与错题复盘

很多人第一次认真做CSPJ初赛选择题训练2021的时候,都会经历一个很别扭的阶段:十套卷子刷完,正确率纹丝不动,错的地方还是那几处——补码的边界、二叉树的叶子数、快排的最坏情况、代码段里循环变量到底跑了几轮。对完答案&#xf…

📰

HBase与Neo4j集成架构:大规模图数据处理实战

1. HBase与Neo4j集成方案概述 在大规模图数据处理领域,HBase和Neo4j的结合堪称"天作之合"。我曾在某社交网络分析项目中采用这种架构,成功处理了超过10亿节点和50亿边的图数据。HBase负责存储原始数据和高吞吐量的读写操作,而Neo4j…

📰

金蝶云星空V7.3生产模块:基础数据与系统参数的协同控制逻辑

简介:本资源是金蝶云星空V7.3制造领域生产管理模块的官方培训课件,面向制造业企业ERP实施顾问、生产计划员、车间管理人员及金蝶系统运维人员,聚焦解决生产订单全周期管控、物料齐套分析、领退补料协同、在制过程追溯等核心业务痛点。课件为单…

📰

轻资产合伙人模式技术架构与管理系统设计

1. 轻资产合伙人模式的核心逻辑 在传统雇佣关系中,企业需要承担人力成本、设备投入和管理开销。而轻资产合伙人模式彻底重构了这一关系链——让参与者主动投入资源,同时共享收益。这种模式之所以能成立,关键在于平台方提供了三种核心价值&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬