安卓串口通信!可移植!

安卓串口通信!可移植!

demo地址
安卓串口实在太难调了
去网上参考了好多demo,才完成了串口调试的小app
而且亲自试了一下移植,是可以成功的
大体思路如下:
1.导入.so文件
什么是.so文件:
.so文件是Unix的动态连接库,本身是二进制文件,是由C/C++编译而来的。
Android调用.so文件的过程也就是所谓的JNI了。在Android中想要调用C/C++中的API的话,也就是调用.so文件了。
需要调用的so文件
2.下面的两个类封装了查找设备端口以及打开/关闭串口的方法,都是谷歌官方代码,其中:
SerialPort类的作用为,JNI的调用,用来加载.so文件,获取串口输入输出流,通过操作IO流,达到能够利用串口接收数据和发送数据的目的
SerialPortFinder这个类是用来获取串口物理地址的,其实一般是用不到这个类的,因为硬件设备上串口的物理地址,在硬件上都是有具体标识的,你直接使用就可以了,我这里安卓pad的串口物理地址是:“dev/ttyMT3”
在这里插入图片描述
这里也附上串口物理地址获取代码:
获取串口物理地址:

//获取所有串口名字
//String[]devices=newSerialPortFinder().getDevices();
////获取所用串口地址
//String[]devicesPath=newSerialPortFinder().getDevicesPaths();
for(Stringpath:devicesPath){
Log.e("tag",path);
}
for(Stringdevice:devices){
Log.e("tag",device);
}

jni文件夹下有它们需要用到的c文件源码
在这里插入图片描述
3.对串口收到的数据进行类型转换的类
在这里插入图片描述
4.串口操作类:
在这里插入图片描述
其中SerialPortBuilder是设置串口初始化各项参数的类
SerialPortService是设置串口收发数据逻辑的类
效果如下:
在这里插入图片描述
电脑端:
在这里插入图片描述
将串口部分移植到其他工程的步骤如下:
1.在需要移植的项目上如下操作:将serialportLibrary项目作为库引入此项目
在这里插入图片描述
2.文件管理中找到此工程下的serialportLibrary文件夹的位置,点击finish(此处因为我以经引入了所以提示module已经存在)
在这里插入图片描述
3.设定引入的包:
Build gradle文件dependicies中加入:
在这里插入图片描述
4.在对应的显示activity里面加入以下代码:
引入包:

import com.serialportlibrary.service.impl.SerialPortBuilder;
import com.serialportlibrary.service.impl.SerialPortService;

activity内部变量声明:

public static boolean sendFlag ;
SerialPort myPort=new SerialPort();

onCreate()方法中加入:

myPort.startPort();
myPort.sendMessage();
myPort.receiveMessage();

或者自己写按钮来启动,我是这样写的:

@Override
    public void onClick(View v) {
        if(v==open){
            myPort.startPort();
            myPort.receiveMesage();
        }
        if (v==send){
            sendFlag=true;
            String str=sendtext.getText().toString();
            myPort.sendMessage(str);
        }
        if(v==close){
            sendFlag=false;
            myPort.closePort();
        }
    }

Activity 内部类:

class SerialPort {
        private byte[] mBuffer;
        private Handler handler;
        SerialPortService serialPortService;
        //开启串口
        public  void startPort(){
            serialPortService = new SerialPortBuilder()
                    .setTimeOut(100L)
                    .setBaudrate(115200)
                    .setDevicePath("dev/ttyMT3")
                    .createService();

            serialPortService.isOutputLog(true);}
            public void sendMessage(final String receiveString){
                //发数据的线程
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                            if (sendFlag){
                                byte[] sendData = receiveString.getBytes();
                            serialPortService.sendData(sendData);
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();
            }
            public void receiveMesage(){

                handler = new Handler(); //创建主线程的handler  用于接收数据时更新UI
                serialPortService.setOnDataReceiveListener(new SerialPortService.OnDataReceiveListener() {
                    @Override
                    public void onDataReceive(byte[] buffer, int size) {
                        Log.d("tag", "进入数据监听事件 "+new String(buffer));
                        mBuffer = buffer;
                        handler.post(runnable);//利用handler将数据传递到主线程

                    }
                    //开线程更新UI
                    Runnable runnable = new Runnable() {
                        @Override
                        public void run() {
                        //串口数据里面实际上存的是二进制数据
                            //String mString=ByteStringUtil.byteArrayToHexStr(mBuffer);
                            String myString=new String(mBuffer);
                            //String myStrings=ByteStringUtil.convertbyteToASCII(mBuffer);
                            byte[] myByte=new byte[]{0x6,'2'};
                            //如果byte[]里面是十六进制数,则会转化成十进制,如果是字符则会转成十进制的ASCII码的值,其实都是二进制保存的
                            Log.e("tag", Arrays.toString(myByte)+myByte.length);
                            Log.e("tag", Arrays.toString(mBuffer)+mBuffer.length);//遍历打印:[35, 52, 69],打印的是10进制数据
                            //也就是如果按照这个值转成字符串的话,会对应着转成这个值的ascii码对应的字符
                            receivetext.setText("size:"+ (mBuffer.length-1)+"\n"+"数据监听:"+ myString);
                        }
                    };
                });
            }
            public void closePort(){
            serialPortService.close();

            }

    }

移植的时候可能会出现以下错误:
在这里插入图片描述
网上的解释如下:(实际上是android 7.0 加载system.loadLibrary崩溃事件解决–.so文件缺失——实际上是因为so文件冲突)
由于引入的库中有多个平台的.so文件,而和本地自己的工程编译进去的平台个数和种类不一样,根据jni的规则,平台文件夹下的so文件,必须是一一对应的,不能少,简单粗暴的办法是,删除掉不需要平台的so、或者补全其他平台的so文件。
解决方法:查看自己的工程所依赖的平台然后对应的引入的库里面的libs里只留下一个:(比如可以只留下armeabi-v7a)
在这里插入图片描述
在这里插入图片描述

©️2020 CSDN 皮肤主题: 游动-白 设计师: 上身试试 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值