1.Andorid串口开发包一般使用google多年前提供的android-serialport-api,

提供自用分支https://github.com/zealzeng/android-serialport-api

2.Android设备一般需要root

保证设备串口文件如/dev/ttyS0, /dev/ttyUSB0等可读可写, 如果无权限, 则需要切到su执行chmod 666。需要注意的是有些设备su路径是/system/bin/su, 有些是/system/xbin/su. 见SerialPort.java关键代码.

public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {

   /* Check access permission */
   if (!device.canRead() || !device.canWrite()) {
      Process su = null;
      try {
         /* Missing read/write permission, trying to chmod the file */
         //su = Runtime.getRuntime().exec("/system/bin/su");
         su = Runtime.getRuntime().exec("/system/xbin/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();
      }
      finally {
         if (su != null) {
            su.destroy();
         }
      }
   }

3.如何确定串口文件和波特率?

可以先使用android串口工具例如Com Assistant等, 一般串口文件是/dev/ttyS**, /dev/ttyUSB**(com转USB),波特率一般连接的硬件可设置,一般是9600, 19200, 最好咨询供应商。

4.分支自带了armeabi, armeabi-v7a, x86的libserial_port.so, 一般够用, 想玩下C的可自行build, 建议使用新些的android studio 3.3

使用cmake比ndk make感觉方便很多, 以前c源文件找不到头文件却可编译过的bug都修复了, 追踪源码方便多了。 需要注意的是新建项目向导不再是include c++ support, 而是选择新的项目类型”Native C++” 串口 修改自动生成的CMakeList.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.

add_library( # Sets the name of the library.
        serial_port

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        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})

5.串口读写阻塞设置

SerialPort.c

fd = open(path_utf, O_RDWR | flags);
cc
Linux的open函数用于打开文件, flags一般我们传入0, 默认阻塞IO, Java的blocking IO一致。当日flags也可设置为O_NONBLOCK非阻塞, Java的NIO一致
```c
#ifndef O_NONBLOCK
#define O_NONBLOCK 00004000
#endif

一般串口的是独占的, 使用blocking IO编程会感觉简单些。

6.串口通信协议

硬件方定义通信协议, 有些是回车换行作为分隔符, 分隔符前还有奇偶校验,笔者看到一些android串口的扩展支持设置奇偶位, 数据位和停止位, 有一些疑惑。 因为默认按照一个字节一个字节流的读法, 遇到分割符才处理, 最多额外处理奇偶校验;笔者调通的硬件不多, 期待大家指教。

  switch (parity) {
            case 0: break;
            case 1: cfg.c_cflag |= PARENB; break;
            case 2: cfg.c_cflag &= ~PARODD; break;
        }
        switch (dataBits) {
            case 5: cfg.c_cflag |= CS5; break;
            case 6: cfg.c_cflag |= CS6; break;
            case 7: cfg.c_cflag |= CS7; break;
            case 8: cfg.c_cflag |= CS8; break;
        }
        switch (stopBit) {
            case 1: cfg.c_cflag &= ~CSTOPB; break;
            case 2: cfg.c_cflag |= CSTOPB; break;
}

7.串口重连

串口被拔插时应用需要支持重连,在遇到InputStream,OutputStream读取返回-1或不可能恢复的问题时, 处理串口的线程应当捕获错误, 优雅关闭当前串口资源,尝试重连,保证串口应用的健壮性。

8.Android串口消息的通知

串口通常是独占, 不能被多个android app打开, 所以很多时候android需要开一个服务, 负责监听串口消息,之后做广播到监听的app处理。

暂时用到这个度, 有问题再交流。