Android 操作串口 (android serial port api)
來(lái)源:程序員人生 發(fā)布時(shí)間:2014-12-10 08:25:28 閱讀次數(shù):5547次
頭幾天公司有通過(guò)搭載Android系統(tǒng)的開(kāi)發(fā)板來(lái)使用打卡機(jī)統(tǒng)計(jì)數(shù)據(jù)的需求,對(duì)攻城獅來(lái)講就需要在Android平臺(tái)上讀寫(xiě)打卡機(jī)的串口,在網(wǎng)上搜索1些東西以后發(fā)現(xiàn)了在google code 上的android serial port api可以用,墻了以后拿到源碼發(fā)現(xiàn)還有demo,不錯(cuò)不錯(cuò),我這個(gè)帖子就通過(guò)serial port api的源碼簡(jiǎn)單得實(shí)現(xiàn)1個(gè)讀寫(xiě)串口,這個(gè)固然是在native寫(xiě)的,如果還有哪些童鞋不清楚android上使用jni和native的話(huà)可以跳轉(zhuǎn)到我的上篇帖子 點(diǎn)我點(diǎn)我
在Android工程中建立1個(gè)工具類(lèi),該類(lèi)的作用就是通過(guò)調(diào)用Jni中聲明的Native方法openSerialPort,來(lái)打開(kāi)參數(shù)中path的串口,該串口的具體參數(shù)為:baudrate比特率,databits數(shù)據(jù)位,stopbits停止位,和parity奇偶校驗(yàn).如果打開(kāi)成功的話(huà)該方法會(huì)返回path串口的文件描寫(xiě)實(shí)例,這樣就能夠獲得到能讀寫(xiě)該串口的IO流,串口對(duì)我們來(lái)講就能夠當(dāng)做1個(gè)文件(在linux系統(tǒng)上確切是1個(gè)裝備文件).成功就按按著不同的命令或數(shù)據(jù)協(xié)議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實(shí)現(xiàn)中,就是拿著配置下來(lái)的參數(shù)來(lái)打開(kāi)串口,配置串口.成功了就返回1個(gè)java的文件描寫(xiě),失敗返回空.
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 == ⑴) {
/* 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 == ⑴)
{
/* 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;
}
生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)