(2022上新)安卓串口,一篇就够了

 ————————————————重要通知——————————————

Hello,本人的博客文章已更新至个人网站(www.jonexu.cn)

文章中有问题可以到网站联系博主,后续新的文章也将更新在个人网站

——————————————————————————————————

如果不想自己写,可直接用串口成品库

一、Google官方demo

注意目录里的文件,主要分为图中三块android_serialport_api、libs、jni

参考完google的项目,开始写到我们项目里。

二、先安装下载NDK、CMake 

三、上手自己的项目

全程是Project视图下在操作 

1、先在你的项目main下java目录中新建package命名为android_serialport_api(必须必这个名字),并把google项目中android_serialport_api目录下的SerialPort.java、SerialPortFinder.java复制过来

2、将Google中libs和jni复制移动到你的项目main目录下,我这边复制过来后,将libs重命名jniLibs了,这样就不需要在sourceSet里配置dir

3、在app目录下创建一个CMakeLists.txt文件,内容如下

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

#设置生成的so动态库最后输出的路径
#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/..jniLibs/${CMAKE_ANDROID_ARCH_ABI})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/jniLibs/${ANDROID_ABI})

add_library( # 生成的.so文件的名字!!
        serial_port

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        src/main/jni/SerialPort.c)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
        serial_port

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

4、在build.gradle中android节点中增加如下配置

android {
    // ...默认配置省略
    defaultConfig{
        //...默认配置省略
        ndk {
          //abiFilters "armeabi", "armeabi-v7a", "x86"
          abiFilters "arm64-v8a", "armeabi-v7a"
        }
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    externalNativeBuild {
//        ndkBuild { // 使用这个就会生成ndkBuild目录,此为ndk形式
//            path 'src/main/jni/Android.mk'    //这个是Android.mk文件的路径
//        }
        cmake {
            path "CMakeLists.txt"    //这个是Android.mk文件的路径
        }
    }
    sourceSets {
        main {
            jni.srcDirs = []
//            jniLibs.srcDirs = ['libs']因为命名为jniLibs所以不需要额外引入
        }
    }
}
      
   

"arm64-v8a"//是目前最新的64位cpu支持

"armeabi-v7a"//是目前主流cpu支持

所以我只引入了这两种。

官方没有给到arm64-v8a的.so文件,所以自己基于jni里的c文件通过cmake来生成。(主要是.c和.h文件起作用)

5、修改build.gradle后,同步,然后点击工具栏Build—Make Project,成功之后有如图目录型号文件,移动到你缺失的jniLibs里就好了。

 6、使用,接收数据        

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    String[] arr = new SerialPortFinder().getAllDevices();
    //获取当前这个设备所有串口地址

    SerialPort mSerialPort = new SerialPort(
       new File("/dev/ttyS2"),//这个通过上面的arr中得知,设备有多个口,要监听哪一个
       9600,0);
    final InputStream inputStream = mSerialPort.getInputStream();
//  this.mOutputStream = mSerialPort.getOutputStream();//这个可以用来写入
    this.mInputStream = mSerialPort.getInputStream();
    this.mReadThread = new ReadThread();
    this.mReadThread.start();
}

private class ReadThread extends Thread {
        @Override
        public void run() {
            super.run();
            while (!isInterrupted()) {
                try {
                    if (mInputStream == null) {
                        return;
                    }
                    int available = mInputStream.available();
                    if (available > 0) {
                        byte[] buffer = new byte[available];
                        int size = mInputStream.read(buffer);
                        if (size > 0) {
                            Log.e(TAG, "收到数据: "+new String(buffer, "UTF-8"));
                        }
                    } else {
                        SystemClock.sleep(50);
                    }
                } catch (Throwable e) {
                    Log.e("接收错误", e.getMessage());
                    return;
                }
            }
        }
}

附:

1、查看mac已连接的串口

ls /dev | grep tty.usb

2、获取模拟器中所有串口, 通过adb命令可以查看模拟器中所有串口名称

adb shell
cd proc/tty
cat drivers

错误

1、如果报错找不到serial_port.so那么两个问题,

1) build.gradle中没有配置sourceSets,

2) 或者说jniLibs中armeabi等.so文件不全,可以到这个项目里下载更多型号的

2、Install Failed Insufficient Storage

真机的话,那就是想办法腾出手机的内存空间了,

模拟器,1)打开模拟器管理,然后右键当前的模拟器,选择Wipe Data

或 2)右键模拟器Edit, 然后 选择 Show Advanced Settings,修改Memory and Storage

3、No implementation found for java.io.FileDescriptor

SerialPort.java文件没有放到main——java——android_serialport_api目录下,同名

4、java.io.IOException: Cannot run program "/system/bin/su": error=13, Permission denied

没有root权限,AVD模拟器的话,使用命令行cd到你安卓的sdk目录下,MAC如下,参考博客

 cd /Users/jonexu/Library/Android/sdk/tools 
 adb root  
//得到restarting adbd as root
 adb shell setenforce 0

 

真机的话得刷机了,按道理你调试串口得有专业的工业板,一般都是root的

5、libserial_port.so text relocations

报错的原因就是没有安卓6.0以上的可读.so文件,需要增加arm64-v8a目录并添加对应.so文件看第1点提到的项目里,可以下载到。

6、Unknown host CPU architecture: arm64

Mac OS里M1芯片中NDK暂不识别arm64、临时解决方案:修改你安卓sdk目录下的ndk中的ndk-build文件

#!/bin/sh
#DIR="$(cd "$(dirname "$0")" && pwd)"
#$DIR/build/ndk-build "$@"
# 新脚本"
DIR="$(cd "$(dirname "$0")" && pwd)"
arch -x86_64 /bin/bash $DIR/build/ndk-build "$@"

7、Execution failed for task ':app:mergeDebugNativeLibs'.如图错误 

Build的时候会遇到这个报错,需要在build.gradle中android节点下增加

android {
    //...其他配置省略
    //主要加入如下配置,defaultConfig.ndk.abiFilters有几种型号就加几种!
    packagingOptions {
        pickFirst 'lib/armeabi-v7a/libserial_port.so'
        pickFirst 'lib/arm64-v8a/libserial_port.so'
    }
}

原文类似问题及解决方案 

End

推荐关于Android型号arm64-v8a等介绍

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值