android 串口jni 开发流程
来源:互联网 发布:sql中不等于怎么表示 编辑:程序博客网 时间:2024/05/28 15:26
第一步, 在eclipose里新建一个android工程,再新建一个 SerialPort.java文件
package android.serialport;public class SerialPort {//本类方法,这里略过,主要是调用jni方法以给其他类提供方法。 ......// JNI 方法 private native static FileDescriptor open(String path, int baudrate) throws IOException; private native void native_close(); private native int native_read_array(byte[] buffer, int length) throws IOException; private native int native_read_direct(ByteBuffer buffer, int length) throws IOException; private native int native_read_array_timeval(byte[] buffer, int length, int tv_sec, int tv_usec) throws IOException; private native int native_read_direct_timeval(ByteBuffer buffer, int length, int tv_sec, int tv_usec) throws IOException; private native void native_write_array(byte[] buffer, int length) throws IOException; private native void native_write_direct(ByteBuffer buffer, int length) throws IOException;static {System.loadLibrary("serial_port");}}
第二步,生成共享库头文件。进入eclipose刚才所新建工程的/bin/classes/目录下。可以看到其目录下的android/serialport/SerialPort.class文件,这个文件就是eclipose自动编译生成的classes文件。
执行: javah android.serialport.SerialPort (注意把目录符“/”换成“.”,而且没有.classes)
就会在当前目录下生成android_serialport_SerialPort.h 头文件,查看android_serialport_SerialPort.h有时会多余些错误处,如Java_android_serialport_SerialPort_native_1open函数名,明显多了一个“1”,此处不懂为什么多了个“1”。但千万不要去掉它.
第三步,将刚才生成的H文件拷贝到jni源文件目录。因为我们这里是用ubuntu下ndk编译的。所以将android_serialport_SerialPort.h改名成SerialPort.h后,实现SerialPort.c文件,SerialPort.c就是要实现刚才SerialPort.h里面的所有方法。
SerialPort.h : 用javah 命令产生的
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class android_serialport_SerialPort */#ifndef _Included_android_serialport_SerialPort#define _Included_android_serialport_SerialPort#ifdef __cplusplusextern "C" {#endif/* * Class: android_serialport_SerialPort * Method: native_open * Signature: (Ljava/lang/String;I)Ljava/io/FileDescriptor; */JNIEXPORT jobject JNICALL Java_android_serialport_SerialPort_native_1open (JNIEnv *, jclass, jstring, jint);/* * Class: android_serialport_SerialPort * Method: native_close * Signature: ()V */JNIEXPORT void JNICALL Java_android_serialport_SerialPort_native_1close (JNIEnv *, jobject);/* * Class: android_serialport_SerialPort * Method: native_read_array * Signature: ([BI)I */JNIEXPORT jint JNICALL Java_android_serialport_SerialPort_native_1read_1array (JNIEnv *, jobject, jbyteArray, jint);/* * Class: android_serialport_SerialPort * Method: native_read_direct * Signature: (Ljava/nio/ByteBuffer;I)I */JNIEXPORT jint JNICALL Java_android_serialport_SerialPort_native_1read_1direct (JNIEnv *, jobject, jobject, jint);.........#ifdef __cplusplus}#endif#endifSerialPort.c : 实现SerialPort.h中声明的函数
#include "termios.h"#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <jni.h>#include "SerialPort.h"#include "android/log.h"static const char *TAG="serial_port";#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args)#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)//static jfieldID field_context; // cannot define this , use this will anr. why??????/* * Class: android_serialport_SerialPort * Method: native_open * Signature: (Ljava/lang/String;I)Ljava/io/FileDescriptor; */JNIEXPORT jobject JNICALL Java_android_serialport_SerialPort_native_1open (JNIEnv *env, jclass thiz, jstring path, jint baudrate){ int fd; speed_t speed; jobject mFileDescriptor; /* Check arguments */ { speed = getBaudrate(baudrate); if (speed == -1) { /* TODO: throw an exception */ LOGE("Invalid baudrate"); jniThrowException(env, "java/io/IOException bad baudrate!!!!!", NULL); return NULL; } } /* Opening device */ { jboolean iscopy; const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy); LOGD("Opening serial port %s", path_utf); fd = open(path_utf, O_RDWR); LOGD("open() fd = %d", fd); // (*env)->SetIntField(env,thiz, field_context, fd); // cannot define this , use this will anr. why?????? (*env)->ReleaseStringUTFChars(env, path, path_utf); if (fd == -1) { /* Throw an exception */ LOGE("Cannot open port"); jniThrowException(env, "java/io/IOException", NULL); /* TODO: throw an exception */ return NULL; } } /* Configure device */ { struct termios cfg; LOGD("Configuring serial port"); if (tcgetattr(fd, &cfg)) { LOGE("tcgetattr() failed"); close(fd); /* TODO: throw an exception */ jniThrowException(env, "java/io/IOException", NULL); return NULL; } cfmakeraw(&cfg); cfsetispeed(&cfg, speed); cfsetospeed(&cfg, speed); if (tcsetattr(fd, TCSANOW, &cfg)) { LOGE("tcsetattr() failed"); close(fd); /* TODO: throw an exception */ jniThrowException(env, "java/io/IOException", NULL); return NULL; } } /* Create a corresponding file descriptor */ { jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "<init>", "()V"); jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd); } return mFileDescriptor;}/* * Class: cedric_serial_SerialPort * Method: close * Signature: ()V */JNIEXPORT void JNICALL Java_android_serialport_SerialPort_native_1close (JNIEnv *env, jobject thiz){ jclass SerialPortClass = (*env)->GetObjectClass(env, thiz); jclass FileDescriptorClass = (*env)->FindClass(env, "java/io/FileDescriptor"); jfieldID mFdID = (*env)->GetFieldID(env, SerialPortClass, "mFd", "Ljava/io/FileDescriptor;"); jfieldID descriptorID = (*env)->GetFieldID(env, FileDescriptorClass, "descriptor", "I"); jobject mFd = (*env)->GetObjectField(env, thiz, mFdID); jint descriptor = (*env)->GetIntField(env, mFd, descriptorID); LOGD("close(fd = %d)", descriptor); close(descriptor);}..........
第四步,编写Android.mk
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)TARGET_PLATFORM := android-3LOCAL_MODULE := serial_portLOCAL_SRC_FILES := SerialPort/SerialPort.c JNIHelp.cppLOCAL_LDLIBS := -lloginclude $(BUILD_SHARED_LIBRARY)
第五步,编译,执行ndk-build命令,将会产生serial_port.so文件
第六步,将serial_port.so文件拷贝到eclipse项目 project/libs/armeabi/下,至此OK。
- android 串口jni 开发流程
- android jni 开发流程
- Android JNI开发流程
- android jni开发流程
- Android JNI开发流程
- Android Studio 串口jni开发
- Android开发之jni串口
- Android开发之jni串口
- Android JNI学习之---JNI开发流程
- Android--JNI的开发流程
- Android JNI 开发的流程
- Android Studio开发JNI流程
- Android Studio jni开发 串口通信
- android studio下JNI开发流程
- JNI(一) - Android Studio简单开发流程
- Android Studio3.0开发JNI流程------JNI入门级
- Android Studio3.0开发JNI流程------JNI函数
- Android - JNI 串口通信
- ASP.Net MVC 给母版页视图传递数据
- webservice与spring的集成
- Android-Keyguard开发分析(持续...)
- DelegatingFilterProxy
- 在新开普写在将要离开的日子
- android 串口jni 开发流程
- 用MFC在MainFrame框架下实现具有office2007的对话框。
- 一个云端的书签 -- raindrop
- Caffe代码导读(1):Protobuf例子
- ubuntu下文件名乱码的解决办法
- 哪里可以买到真的听话药水扣:55957657
- 超级有用的git reset --hard和git revert命令
- ceph存储 ceph整体学习记录(未整理较乱)
- Scala的无参方法