java inputevent_使用JNI封装底层input系统提供的event事件

本文介绍如何使用JNI技术封装底层触摸事件,模仿Android系统的MotionEvent类,仅封装红外触摸屏的几个基本事件,如坐标、触摸宽度等。通过创建线程和管道处理/dev/input/event中的事件,并在Java层提供公共方法访问。
摘要由CSDN通过智能技术生成

首先说下思路,本文采用jni技术封装底层触摸事件,封装成MotionEvent类一样,不过没有android系统MotionEvent强大。源码MotionEvent位置:java-->frameworks/base/core/java/android/view/MotionEvent.java     ; jni-->frameworks/base/core/jni/android_view_MotionEvent.cpp  原有的MotionEvent封装的事件之多,我所做的就是只封装红外触摸屏所产生的几个简单事件,例如坐标事件以及触摸宽度等等。

1)底层事件来源于/dev/input/event。

2)顶层事件采用java封装为类。

3)jni中使用到了线程 和 管道,最开始打算使用线程和消息队列,可是失败了,android不支持消息队列。

a1b4b565d91ef5bd22fece07975de0d9.png

直接上代码:

java上层封装代码

1 packageandroid.wf;2 public final classMotionEvent {3

4 publicMotionEvent(){5 int fd =initEvent();6 System.out.println("fd = %d\n");7 }8

9 public final floatgetX() {10 returngetXX();11 }12

13 public final floatgetY() {14 returngetYY();15 }16

17 public final floatgetWidth() {18 returngetH();19 }20

21 public final floatgetHight() {22 returngetW();23 }24

25 static

26 {27 System.loadLibrary("MotionEvent");28 }29

30 private static native floatgetW();31 private static native floatgetH();32 private static native intinitEvent();33 private static native floatgetXX();34 private static native floatgetYY();35

36 }

使用javah编译生成CPP的头文件:

1 /*DO NOT EDIT THIS FILE - it is machine generated*/

2 #include

3 /*Header for class android_wf_MotionEvent*/

4

5 #ifndef _Included_android_wf_MotionEvent6 #define _Included_android_wf_MotionEvent

7 #ifdef __cplusplus8 extern "C"{9 #endif

10 /*

11 * Class: android_wf_MotionEvent12 * Method: initEvent13 * Signature: ()F14 */

15 JNIEXPORT jint JNICALL Java_android_wf_MotionEvent_initEvent16 (JNIEnv *, jclass);17

18 /*

19 * Class: android_wf_MotionEvent20 * Method: getXX21 * Signature: ()F22 */

23 JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getXX24 (JNIEnv *, jclass);25

26 /*

27 * Class: android_wf_MotionEvent28 * Method: getYY29 * Signature: ()F30 */

31 JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getYY32 (JNIEnv *, jclass);33 JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getW34 (JNIEnv *, jclass);35 JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getH36 (JNIEnv *, jclass );37 #ifdef __cplusplus38 }39 #endif

40 #endif

接着在CPP文件中实现java的native函数:

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9 #include

10 #include

11 #include "android_wf_MotionEvent.h"

12 #include

13

14 //LCD和触摸框转换比例

15 float xScale = 1920.0/32768;16 float yScale = 1080.0/32768;17

18 int fd ; //dev的文件描述符

19 int fds[2]; //管道

20

21 jfloat x;22 jfloat y;23 jfloat pressure;24 jfloat touchMajor;25 jfloat touchMinor;26

27 static int getTouchEventNum() //判断触摸框事件是哪一个event

28 {29 char name[64]; /*RATS: Use ok, but could be better*/

30 char buf[256] = { 0, }; /*RATS: Use ok*/

31 int fd = 0;32 inti;33 for (i = 0; i < 32; i++)34 {35 sprintf(name, "/dev/input/event%d", i);36 if ((fd = open(name, O_RDONLY, 0)) >= 0)37 {38 ioctl(fd, EVIOCGNAME(sizeof(buf)), buf);39 if(strstr(buf, "MTOUC Touch"))40 {41 close(fd);42 returni;43 }44 //printf("%s\n", name);45 //printf("name: %s\n", buf);

46 close(fd);47 }48 }49 return -1;50 }51

52 static void* readInput(void *data)53 {54 structinput_event inputEvent;55 while(1)56 {57 read(fd, &inputEvent, sizeof(structinput_event));58 //向管道中写数据

59 write(fds[1], &inputEvent, sizeof(structinput_event));60 }61 returnNULL;62 }63

64 static void* dispatchInput(void *data)65 {66 structinput_event inputEvent;67 int flag = 1;68 while(1)69 {70 //从管道中读取数据

71 read(fds[0], &inputEvent, sizeof(structinput_event));72

73 if(inputEvent.type == EV_ABS && inputEvent.code ==ABS_X ){74 float fv = inputEvent.value * 1.0;75 x = fv *xScale;76 continue;77 }78 if(inputEvent.type == EV_ABS && inputEvent.code ==ABS_Y ){79 float fv = inputEvent.value * 1.0;80 y = fv *yScale;81 continue;82 }83 if(inputEvent.type == EV_KEY && inputEvent.code ==BTN_TOUCH ){84 pressure =inputEvent.value;85 if(1 == pressure &&flag)86 {87 flag = 0;88 }89 else if(0 ==pressure)90 {91 flag = 1;92 }93 continue;94 }95 //增加flag的判断作用是touchMajor和toushMinor事件在pressure事件之前的比较准确

96 if(inputEvent.type == EV_ABS && inputEvent.code == ABS_MT_TOUCH_MAJOR &&flag ){97 float fv = inputEvent.value * 1.0;98 touchMajor =fv ;99 continue;100 }101 if(inputEvent.type == EV_ABS && inputEvent.code == ABS_MT_TOUCH_MINOR &&flag ){102 float fv = inputEvent.value * 1.0;103 touchMinor =fv;104 continue;105 }106 }107 returnNULL;108 }109

110

111 JNIEXPORT jint JNICALL Java_android_wf_MotionEvent_initEvent(JNIEnv *env, jclass clazz)112 {113 int num =getTouchEventNum();114 if( num == -1)115 {116 printf("No Touch Event\n");117 return -1;118 }119 char name[64];120 sprintf(name, "/dev/input/event%d", num);121 fd =open(name, O_RDWR);122 if(fd < 0)123 {124 //LOGI("Open dev Error");

125 returnfd;126 }127

128 //创建无名管道

129 if(-1 ==pipe(fds))130 {131 printf("pipe\n");132 exit(-1);133 }134

135 pthread_t readId, disPatchId;136 pthread_create(&readId, NULL, readInput, NULL);137 sleep(1);138 pthread_create(&disPatchId, NULL, dispatchInput, NULL);139

140 returnfd;141 }142

143 JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getXX(JNIEnv *env, jclass clazz)144 {145 returnx;146 }147

148 JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getYY(JNIEnv *env, jclass clazz)149 {150 returny;151 }152

153 JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getW(JNIEnv *env, jclass clazz)154 {155 returntouchMajor;156 }157

158 JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getH(JNIEnv *env, jclass clazz)159 {160 returntouchMinor;161 }

最后在来个Android的Mk文件:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

arch := $(TARGET_ARCH)

LOCAL_C_INCLUDES := $(KERNEL_HEADERS)

LOCAL_LDLIBS += -lpthread -lrt -ldl -lm    #貌似可以不加

LOCAL_MODULE:= libMotionEvent

LOCAL_SRC_FILES += jni/MotionEvent.c

include $(BUILD_SHARED_LIBRARY)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值