Android 操作串口 (android serial port api)
前几天公司有通过搭载Android系统的开发板来使用打卡机统计数据的需求,对于攻城狮来说就需要在Android平台上读写打卡机的串口,在网上搜索一些东西之后发现了在google code 上的android serial port api可以用,墙了之后拿到源码发现还有demo,不错不错,我这个帖子就通过serial port api的源码简单得实现一个读写串口,这个当然是在native写的,如果还有哪些童鞋不清楚android上使用jni和native的话可以跳转到我的上篇帖子 点我点我
在Android工程中建立一个工具类,该类的作用就是通过调用Jni中声明的Native方法openSerialPort,来打开参数中path的串口,该串口的具体参数为:baudrate比特率,databits数据位,stopbits停止位,和parity奇偶校验.如果打开成功的话该方法会返回path串口的文件描述实例,这样就可以获取到能读写该串口的IO流,串口对于我们来说就可以当成一个文件(在linux系统上确实是一个设备文件).成功就按按着不同的命令或数据协议R/W串口就OK了.
/** * @Title: SerialPortUtil.java * @Description: the util of serial port * @author Jesse * @date Nov 21, 2014 10:10:49 AM * @version V1.0 */ public class SerialPortUtil { private final String TAG = SerialPortUtil.class.getSimpleName(); private static SerialPortUtil mInstance = null; private StudioJni studioJni = StudioJni.getInstance(); private FileDescriptor mFd; private FileInputStream mFileInputStream = null; private FileOutputStream mFileOutputStream = null; private boolean isRunning = false; public static SerialPortUtil getInstance(){ if(mInstance == null){ mInstance = new SerialPortUtil(); } return mInstance; } public boolean openSerialPort(String path,int baudrate,int databits, int stopbits, char parity){ Log.i(TAG, "openSerialPort,path:" + path + " ,baudrate:" + baudrate + " ,databits:" +databits + " ,stopbits:" + stopbits + " ,parity:" + parity); if(isRunning){ Log.i(TAG, "openSerialPort,the serial port is running"); return false; } mFd = studioJni.serialPortOpen(path, baudrate,databits,stopbits,parity); if(mFd != null){ isRunning = true; mFileInputStream = new FileInputStream(mFd); mFileOutputStream = new FileOutputStream(mFd); }else{ Log.i(TAG, "openSerialPort," + "the deivce is null"); } return isRunning; } public void closeSerialPort(){ Log.i(TAG, "closeSerialPort"); studioJni.serialPortClose(); isRunning = false; } public InputStream getInputStream() { return mFileInputStream; } public OutputStream getOutputStream() { return mFileOutputStream; } }在Native实现中,就是拿着配置下来的参数来打开串口,配置串口.成功了就返回一个java的文件描述,失败返回空.
JNIEXPORT jobject JNICALL serial_port_open(JNIEnv *env,jclass thiz,jstring path, jint baudrate, jint databits,jint stopbits,jchar parity){ LOGI(CAMERA_TAG,"serial_port_open"); int fd; speed_t speed; jobject mFileDescriptor; /* Check arguments */ { speed = getBaudrate(baudrate); if (speed == -1) { /* TODO: throw an exception */ LOGI(CAMERA_TAG,"serial_port_open,Invalid baudrate"); LOGE(CAMERA_TAG,"serial_port_open,Invalid baudrate"); return NULL; } } /* Opening device */ { jboolean iscopy; const char *path_utf = env -> GetStringUTFChars(path, &iscopy); LOGI(CAMERA_TAG,"serial_port_open,Opening serial port %s with flags 0x%x", path_utf, O_RDWR); fd = open(path_utf, O_RDWR); LOGI(CAMERA_TAG,"serial_port_open,open() fd = %d", fd); env->ReleaseStringUTFChars(path, path_utf); if (fd == -1) { /* Throw an exception */ LOGI(CAMERA_TAG,"serial_port_open,Cannot open port"); LOGE(CAMERA_TAG,"serial_port_open","Cannot open port"); /* TODO: throw an exception */ return NULL; } } /* Configure device */ { struct termios cfg; LOGI(CAMERA_TAG,"serial_port_open,Configuring serial port"); if (tcgetattr(fd, &cfg)) { LOGI(CAMERA_TAG,"serial_port_open,tcgetattr() failed"); LOGE(CAMERA_TAG,"serial_port_open","tcgetattr() failed"); close(fd); /* TODO: throw an exception */ return NULL; } cfmakeraw(&cfg); cfsetispeed(&cfg, speed); cfsetospeed(&cfg, speed); if (tcsetattr(fd, TCSANOW, &cfg)) { LOGI(CAMERA_TAG,"serial_port_open","tcsetattr() failed"); LOGE(CAMERA_TAG,"serial_port_open","tcsetattr() failed"); close(fd); /* TODO: throw an exception */ return NULL; } set_Parity(fd, databits, stopbits, parity); FD = fd; } /* Create a corresponding file descriptor */ { jclass cFileDescriptor = env->FindClass("java/io/FileDescriptor"); jmethodID iFileDescriptor = env->GetMethodID(cFileDescriptor, "<init>", "()V"); jfieldID descriptorID = env->GetFieldID(cFileDescriptor, "descriptor", "I"); mFileDescriptor = env->NewObject(cFileDescriptor, iFileDescriptor); env->SetIntField(mFileDescriptor, descriptorID, (jint)fd); } return mFileDescriptor; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。