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;
}


  



  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
要集成下载Android-SerialPort-API库,可以按照以下步骤进行: 1. 首先下载Android-SerialPort-API库的源代码,可以从Github上获取。 2. 将下载的源代码解压缩后,将其中的serial_port_api.c和serial_port_api.h文件复制到你的Android项目的jni目录下。 3. 在jni目录下创建一个Android.mk文件,文件内容如下: ``` LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := serial_port_api LOCAL_SRC_FILES := serial_port_api.c include $(BUILD_SHARED_LIBRARY) ``` 4. 在jni目录下创建一个Application.mk文件,文件内容如下: ``` APP_MODULES := serial_port_api APP_OPTIM := release APP_ABI := armeabi armeabi-v7a x86 ``` 5. 在AndroidManifest.xml文件中添加以下权限: ``` <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.SET_DEBUG_APP"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-feature android:name="android.hardware.usb.host"/> ``` 6. 将serial_port_api库文件导入到你的项目中,可以通过以下方式: - 将库文件打包成.jar文件,并通过Build Path->Add External Archives添加到你的项目中。 - 将库文件复制到libs目录下,并通过Build Path->Add Libraries添加到你的项目中。 7. 在你的Android代码中调用serial_port_api库的相关函数,以实现串口通信。 注意:集成Android-SerialPort-API库需要NDK支持,所以请确保你已经安装了NDK。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值