快速开发和使用Android串口

这篇具有很好参考价值的文章主要介绍了快速开发和使用Android串口。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、什么是串口

        串口叫做串行接口,也称串行通信接口,也可以叫做COM口,按电气标准及协议来分包括RS-232-C、RS-422、RS485、USB等。串行接口是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信,从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。

二、串口通讯方式

  • 单工模式:只支持数据在一个方向上传输;在同一时间只有一方能接收或发送信息,不能实现双向通信。一般用在只向一个方向传输数据的场合,比如跟打印机通讯。
  • 半双工模式:如果只有一条通讯线,那么它既可以发送数据也可以接收数据,但不能同时进行发送和接收。如果使用两条通讯线,数据可以在两个方向传输,但是在同一时间只可以有一方接受或发送信息,实际上是一种切换方向的单工通讯。比如RS485-2W通讯就是采用这种模式。
  • 全双工模式:数据可以同时往两个方向传输,相当于两个单工通讯的结合,它要求发送设备和接收设备都有独立的发送和接收能力,在同一时间可以同时进行发送和接收数据,实现双向通信,数据传输效率比较高。比如RS-232通讯就是采用这种模式。

串口通讯是一个字符一个字符地传输,每个字符一位一位地传输,总是以“起始位”开始,以“停止位”结束,字符之间没有固定的时间间隔要求。
实际传输时每一位的信号宽度与波特率有关,波特率越高,宽度越小,在进行传输之前,双方一定要使用同一个波特率。 

三、Android串口开发

        通过使用serialport库,直接上代码 :

第一步导包:

// 在项目根目录的build.gradle文件中添加:
allprojects {
    repositories {
        ...
        mavenCentral()
    }
}
// 在项目Module下的build.gradle文件中添加:
dependencies {
    implementation 'io.github.xmaihh:serialport:2.1.1'
}

第二步代码:


import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;

import com.alibaba.fastjson.JSONObject;

import java.io.IOException;
import java.io.InputStream;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import tp.xmaihh.serialport.SerialHelper;
import tp.xmaihh.serialport.bean.ComBean;
import tp.xmaihh.serialport.stick.AbsStickPackageHelper;
import tp.xmaihh.serialport.utils.ByteUtil;

public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {

    @BindView(R.id.rg_type)
    RadioGroup mRgType;
    @BindView(R.id.et_read_content)
    EditText mEtReadContent;
    @BindView(R.id.et_send_content)
    EditText mEtSendContent;

    private SerialHelper serialHelper;
    private boolean isHexType = false;
    private String text = "";

    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            ComBean comBean = (ComBean) msg.obj;
            String time = comBean.sRecTime;
            String rxText;
            rxText = new String(comBean.bRec);
            if (isHexType) {
                //转成十六进制数据
                rxText = ByteUtil.ByteArrToHex(comBean.bRec);
            }
            text += "Rx-> " + time + ": " + rxText + "\r" + "\n";
            mEtReadContent.setText(text);
            return false;
        }
    });

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ButterKnife.bind(this);

        mRgType.setOnCheckedChangeListener(this);

        initSerialConfig();
    }

    private void initSerialConfig() {
        //初始化SerialHelper对象,设定串口名称和波特率(此处为接收扫码数据)
        serialHelper = new SerialHelper("/dev/ttyACM0", 9600) {
            @Override
            protected void onDataReceived(ComBean paramComBean) {
                Message message = mHandler.obtainMessage();
                message.obj = paramComBean;
                Log.e("TAG", "onDataReceived: " + JSONObject.toJSONString(message.obj));
                mHandler.sendMessage(message);
            }
        };

        /*
         * 默认的BaseStickPackageHelper将接收的数据扩展成64位,一般用不到这么多位
         * 我这里重新设定一个自适应数据位数的
         */

        serialHelper.setStickPackageHelper(new AbsStickPackageHelper() {
            @Override
            public byte[] execute(InputStream is) {
                try {
                    int available = is.available();
                    if (available > 0) {
                        byte[] buffer = new byte[available];
                        int size = is.read(buffer);
                        if (size > 0) {
                            return buffer;
                        }
                    } else {
                        SystemClock.sleep(50);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
    }

    @OnClick({R.id.bt_open, R.id.bt_close, R.id.bt_send, R.id.bt_clear_content})
    public void onButtonClicked(View view){
        switch (view.getId()) {
            case R.id.bt_open:
                if (serialHelper.isOpen()) {
                    Toast.makeText(this, Const.SPORT_NAME + "串口已经打开", Toast.LENGTH_SHORT).show();
                    return;
                }
                try {
                    serialHelper.open();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Toast.makeText(this, Const.SPORT_NAME + "串口打开成功", Toast.LENGTH_SHORT).show();
                break;

            case R.id.bt_close:
                if (serialHelper.isOpen()) {
                    serialHelper.close();
                    Toast.makeText(this, Const.SPORT_NAME + "串口已经关闭", Toast.LENGTH_SHORT).show();
                }
                break;

            case R.id.bt_clear_content:
                text = "";
                mEtReadContent.setText(text);
                break;

            case R.id.bt_send:
                if (!serialHelper.isOpen()) {
                    Toast.makeText(this, Const.SPORT_NAME + "串口没打开 发送失败", Toast.LENGTH_SHORT).show();
                    return;
                }
                String sendContent = mEtSendContent.getText().toString();
                if (isHexType) {
                    serialHelper.sendHex(sendContent);
                } else {
                    serialHelper.sendTxt(sendContent);
                }
                break;
        }
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch (checkedId) {
            case R.id.rb_txt:
                isHexType = false;
                mEtSendContent.setText(Const.TXT_TYPE_SEND);
                break;

            case R.id.rb_hex:
                isHexType = true;
                mEtSendContent.setText(Const.HEX_TYPE_SEND);
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        serialHelper.close();
        serialHelper = null;
    }
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!--串口操作部分-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@id/ll_read_data"
        android:layout_marginBottom="@dimen/dp_10"
        android:orientation="horizontal">

        <Button
            android:id="@+id/bt_open"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/open_serial"
            android:layout_marginStart="@dimen/dp_10"
            android:layout_gravity="center_vertical"/>

        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:textSize="@dimen/edit_text_size"
            android:text="@string/data_type"
            android:layout_marginStart="@dimen/dp_10"
            android:layout_gravity="center_vertical"/>

        <RadioGroup
            android:id="@+id/rg_type"
            android:layout_width="0dp"
            android:layout_weight="2"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginStart="@dimen/dp_10"
            android:orientation="horizontal">


            <RadioButton
                android:id="@+id/rb_txt"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text="@string/data_type_txt"/>

            <RadioButton
                android:id="@+id/rb_hex"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/dp_10"
                android:text="@string/data_type_hex"/>

        </RadioGroup>

        <Button
            android:id="@+id/bt_close"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/close_serial"
            android:layout_marginStart="@dimen/dp_10"
            android:layout_marginEnd="@dimen/dp_10"
            android:layout_gravity="center_vertical"/>

    </LinearLayout>

    <!--数据接收部分-->
    <LinearLayout
        android:id="@+id/ll_read_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:orientation="horizontal">


        <!--数据接收显示-->
        <EditText
            android:id="@+id/et_read_content"
            android:layout_width="0dp"
            android:layout_height="200dp"
            android:layout_marginStart="@dimen/dp_10"
            android:layout_weight="6"
            android:background="@drawable/edit_bg"
            android:cursorVisible="false"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:gravity="top"
            android:padding="@dimen/dp_5"
            android:textSize="@dimen/edit_text_size" />

        <Button
            android:id="@+id/bt_clear_content"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/clear_all_data"
            android:layout_marginStart="@dimen/dp_10"
            android:layout_marginEnd="@dimen/dp_10"
            android:layout_gravity="center_vertical"/>


    </LinearLayout>

    <View
        android:id="@+id/view_line"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_2"
        android:layout_marginTop="@dimen/dp_10"
        android:layout_marginStart="@dimen/dp_10"
        android:layout_marginEnd="@dimen/dp_10"
        android:background="@color/colorAccent"
        app:layout_constraintTop_toBottomOf="@id/ll_read_data"/>

    <!--数据发送部分-->
    <LinearLayout
        android:id="@+id/ll_send_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/view_line"
        android:layout_marginTop="@dimen/dp_10"
        android:orientation="horizontal">


        <!--数据接收显示-->
        <EditText
            android:id="@+id/et_send_content"
            android:layout_width="0dp"
            android:layout_height="200dp"
            android:layout_marginStart="@dimen/dp_10"
            android:layout_weight="6"
            android:singleLine="false"
            android:background="@drawable/edit_bg"
            android:gravity="top"
            android:padding="@dimen/dp_5"
            android:inputType="text"
            android:textSize="@dimen/edit_text_size"
            android:text="@string/txt_data"/>

        <Button
            android:id="@+id/bt_send"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/send_data"
            android:layout_marginStart="@dimen/dp_10"
            android:layout_marginEnd="@dimen/dp_10"
            android:layout_gravity="center_vertical"/>


    </LinearLayout>

</android.support.constraint.ConstraintLayout>

 第三步说明:

        上面代码,在创建serialHelper之时,就已经传入了一个onDataReceived()方法,用来监听串口数据接收,但是如要打开串口才能开启监听。

SerialHelper创建完成,打开串口

serialHelper.open();

如果需要设置其他的属性,比如设置奇偶检验,需要在执行open()之前设定。

serialHelper.setPort(String sPort);      //设置串口
serialHelper.setBaudRate(int iBaud);     //设置波特率
serialHelper.setStopBits(int stopBits);  //设置停止位
serialHelper.setDataBits(int dataBits);  //设置数据位
serialHelper.setParity(int parity);      //设置校验位
serialHelper.setFlowCon(int flowcon);    //设置流控

发送数据

serialHelper.send(byte[] bOutArray); // 发送byte[]
serialHelper.sendHex(String sHex);  // 发送Hex
serialHelper.sendTxt(String sTxt);  // 发送ASCII

关闭串口

serialHelper.close(); 

效果图 

android 串口,android

 四、参考文章

Android串口使用2之使用Google官方库android-serialport-api_android-serialport-api使用_Steven Jon的博客-CSDN博客

mirrors / xmaihh / Android-Serialport · GitCode 文章来源地址https://www.toymoban.com/news/detail-637529.html

到了这里,关于快速开发和使用Android串口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 安卓Android开发快速入门

    配合天哥视频食用更佳:【天哥】Android开发视频教程最新版 Android Studio开发 LinearLayout(线性布局) 可嵌套 最常用属性 id 起标记布局的作用 layout_width [wrap_content根据内容选择大小、match_parent匹配父级、具体数值(单位-dp)] layout_height layout_weight 权重,按照权重比例分配父级

    2023年04月16日
    浏览(41)
  • Android Studio的笔记--SerialPort串口通讯学习和使用

    摘要:本篇介绍android中SerialPort串口通讯学习和使用。主要用到android-serialport-api。 几个工程参考学习使用 Google开源的Android串口通信Demo android-serialport-api 源码下载 cepr/android-serialport-api SerialPort获取串口输入输出流 SerialPortFinder获取硬件地址 可以推荐看android串口通信——andr

    2024年02月06日
    浏览(63)
  • ARabbit:一个快速开发Android App的框架

    5.主要版本修订日志 6.引用的第三方库 7.SDK引用的开源框架 8.使用ARabbit的项目 欢迎加入Android开发交流QQ群: 1.简介 ============================================================== 提供App开发的接口,使开发者只关心App的业务实现,不用再关心具体功能实现,比如网络请求、图片加载、对话

    2024年04月25日
    浏览(32)
  • Android问题笔记四十三:JNI 开发如何快速定位崩溃问题

    Unity3D特效百例 案例项目实战源码 Android-Unity实战问题汇总 游戏脚本-辅助自动化 Android控件全解手册 再战Android系列 Scratch编程案例 软考全系列 Unity3D学习专栏 蓝桥系列 ChatGPT和AIGC 专注于 Android/Unity 和各种游戏开发技巧,以及 各种资源分享 (网站、工具、素材、源码、游戏等

    2024年02月05日
    浏览(50)
  • 基于阿里云物联网平台的Android物联网软件框架(快速开发)

    提示:该工程是连接阿里云物联网平台的模板代码,将MQTT连接、JSON数据的订阅发布等操作封装,并且能够迅速将获取到的数据显示到手机界面上。使用了Servier进行网络连接的逻辑操作,并且使用自定义控件,绑定对用标识符的数据对象,实现了数据自动实时更新等操作,并

    2024年02月06日
    浏览(52)
  • 【北京迅为】《iTOP-3588开发板快速测试手册》第二章 Android12系统功能测试

    RK3588是一款低功耗、高性能的处理器,适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用,RK3588支持8K视频编解码,内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP,内置NPU,支持INT4/INT8/INT16/FP16混合运算能力

    2024年02月21日
    浏览(53)
  • 不会代码(实操能力弱一点)的我如何快速开发出一个Android/Web/IOS/小程序

    像做PPT一样的可视化编程语言你想拥有吗,可以自己尝试一下。 像PPT一样的编程语言 抽象出超过200+前端和后台原子组件,每个组件都具备“不可拆分”特性,并表达独立具有特征的属性;同时每个组件都具备“属性”“触发条件”“功能(函数)”。 逻辑编辑框架:(专利

    2024年02月09日
    浏览(91)
  • 使用GoEasy快速实现Android原生app中的websocket消息推送

    摘要: GoEasy带来了一项令开发者振奋的消息:全面支持Android原生平台!现在,您可以在Android应用中使用最酷炫的实时通信功能,借助GoEasy轻松实现消息的发送和接收。本文将带您领略GoEasy最新版本的威力,为您的应用增添一抹鲜活的互动色彩。 嗨,开发者朋友们!是时候展

    2024年02月12日
    浏览(44)
  • (二) 盘古UI,全网独创,较为全面的自定义Android UI框架,绝对帮助你快速开发!(盘古导航栏-PanguNavBar)

    (二) 盘古UI,较为全面的自定义UI框架,帮助你绝对的快速开发!(长期维护中) demo地址,点击查看github 1, 样例展示图 2, 介绍 个性化导航栏,标题栏,可以灵活设置和配置各种属性和事件! 下面直接上属性列表: attr 属性 对应的方法 method 介绍 introduction pangu_title_mid setMidTitle(String title)

    2024年04月14日
    浏览(47)
  • (一) 盘古UI,全网独创,较为全面的自定义Android UI框架,绝对帮助你快速开发!(盘古输入框-PanguInputView)

    (一) 盘古UI,较为全面的自定义UI框架,帮助你绝对的快速开发!(长期维护中) demo地址,点击查看github 1, 样例展示图 2, 介绍 支持你所需要的常用的属性样式和功能! 下面直接上属性列表: attr 属性 对应的方法 method 介绍 introduction pgiv_title setTitle(String title) 标题 pgiv_title_color setTitleC

    2024年04月14日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包