首先说下思路,本文采用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不支持消息队列。

直接上代码:

java上层封装代码

 package android.wf;
public final class MotionEvent { public MotionEvent(){
int fd = initEvent();
System.out.println("fd = %d\n");
} public final float getX() {
return getXX();
} public final float getY() {
return getYY();
} public final float getWidth() {
return getH();
} public final float getHight() {
return getW();
} static
{
System.loadLibrary("MotionEvent");
} private static native float getW();
private static native float getH();
private static native int initEvent();
private static native float getXX();
private static native float getYY(); }

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

 /* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class android_wf_MotionEvent */ #ifndef _Included_android_wf_MotionEvent
#define _Included_android_wf_MotionEvent
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: android_wf_MotionEvent
* Method: initEvent
* Signature: ()F
*/
JNIEXPORT jint JNICALL Java_android_wf_MotionEvent_initEvent
(JNIEnv *, jclass); /*
* Class: android_wf_MotionEvent
* Method: getXX
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getXX
(JNIEnv *, jclass); /*
* Class: android_wf_MotionEvent
* Method: getYY
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getYY
(JNIEnv *, jclass);
JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getW
(JNIEnv *, jclass);
JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getH
(JNIEnv *, jclass );
#ifdef __cplusplus
}
#endif
#endif

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

 #include <linux/input.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <jni.h>
#include "android_wf_MotionEvent.h"
#include<android/log.h> //LCD和触摸框转换比例
float xScale = 1920.0/;
float yScale = 1080.0/; int fd ; // dev的文件描述符
int fds[]; //管道 jfloat x;
jfloat y;
jfloat pressure;
jfloat touchMajor;
jfloat touchMinor; static int getTouchEventNum() //判断触摸框事件是哪一个event
{
char name[]; /* RATS: Use ok, but could be better */
char buf[] = { , }; /* RATS: Use ok */
int fd = ;
int i;
for (i = ; i < ; i++)
{
sprintf(name, "/dev/input/event%d", i);
if ((fd = open(name, O_RDONLY, )) >= )
{
ioctl(fd, EVIOCGNAME(sizeof(buf)), buf);
if(strstr(buf, "MTOUC Touch"))
{
close(fd);
return i;
}
//printf("%s\n", name);
//printf("name: %s\n", buf);
close(fd);
}
}
return -;
} static void* readInput(void *data)
{
struct input_event inputEvent;
while()
{
read(fd, &inputEvent, sizeof(struct input_event));
// 向管道中写数据
write(fds[], &inputEvent, sizeof(struct input_event));
}
return NULL;
} static void* dispatchInput(void *data)
{
struct input_event inputEvent;
int flag = ;
while()
{
//从管道中读取数据
read(fds[], &inputEvent, sizeof(struct input_event)); if(inputEvent.type == EV_ABS && inputEvent.code == ABS_X ){
float fv = inputEvent.value * 1.0;
x = fv * xScale;
continue;
}
if(inputEvent.type == EV_ABS && inputEvent.code == ABS_Y ){
float fv = inputEvent.value * 1.0;
y = fv * yScale;
continue;
}
if(inputEvent.type == EV_KEY && inputEvent.code == BTN_TOUCH ){
pressure = inputEvent.value;
if( == pressure && flag)
{
flag = ;
}
else if( == pressure)
{
flag = ;
}
continue;
}
//增加flag的判断作用是touchMajor和toushMinor事件在pressure事件之前的比较准确
if(inputEvent.type == EV_ABS && inputEvent.code == ABS_MT_TOUCH_MAJOR && flag ){
float fv = inputEvent.value * 1.0;
touchMajor = fv ;
continue;
}
if(inputEvent.type == EV_ABS && inputEvent.code == ABS_MT_TOUCH_MINOR && flag ){
float fv = inputEvent.value * 1.0;
touchMinor = fv;
continue;
}
}
return NULL;
} JNIEXPORT jint JNICALL Java_android_wf_MotionEvent_initEvent(JNIEnv *env, jclass clazz)
{
int num = getTouchEventNum();
if( num == -)
{
printf("No Touch Event\n");
return -;
}
char name[];
sprintf(name, "/dev/input/event%d", num);
fd = open(name, O_RDWR);
if(fd < )
{
//LOGI("Open dev Error");
return fd;
} //创建无名管道
if(- == pipe(fds))
{
printf("pipe\n");
exit(-);
} pthread_t readId, disPatchId;
pthread_create(&readId, NULL, readInput, NULL);
sleep();
pthread_create(&disPatchId, NULL, dispatchInput, NULL); return fd;
} JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getXX(JNIEnv *env, jclass clazz)
{
return x;
} JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getYY(JNIEnv *env, jclass clazz)
{
return y;
} JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getW(JNIEnv *env, jclass clazz)
{
return touchMajor;
} JNIEXPORT jfloat JNICALL Java_android_wf_MotionEvent_getH(JNIEnv *env, jclass clazz)
{
return touchMinor;
}

最后在来个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)

最新文章

  1. java二叉树的实现和遍历
  2. CDN(内容分发网络)技术原理
  3. Linux环境下实现管道通信-问题
  4. VS编程中找不到Microsoft.Office.Core、Microsoft.Office.Interop.Word和VBIDE
  5. C#全屏随机位置显示图片的小程序
  6. 转:6款Java转C#的最佳工
  7. Swift数据类型之整型和浮点型-备
  8. Oracle10g安装中遇到的错误及解决办法
  9. 【原创】纯OO:从设计到编码写一个FlappyBird (四)
  10. 记一次sql优化——left join不走索引问题
  11. nginx做80端口转发
  12. SQL Server的实例恢复解析
  13. git 完全讲解 无废话,包含在myeclipse中使用,包括解决冲突
  14. 软件安全概念:认证 &amp; 授权
  15. [日常工作] 并行计算引发Microsoft.jscript.ni.dll的内存溢出问题的分析解决. .net framework 的版本说明
  16. case when then用法
  17. python参数传递方式
  18. oggMonitor是什么
  19. java -D 参数功能解析
  20. JavaEE-学习目录

热门文章

  1. Centos6 yum安装openldap+phpldapadmin+TLS+双主配置
  2. CCF——Z字形扫描问题
  3. C#+JQuery+.Ashx+百度Echarts实现全国省市地图和饼状图动态数据图形报表的统计
  4. SQL语句分组排序,多表关联排序
  5. 个人项目框架搭建 -- Autofac简单使用记录
  6. 转载:《TypeScript 中文入门教程》 13、类型兼容性
  7. 第 31 章 项目实战-PC 端固定布局[5]
  8. [javaSE] 注解-自定义注解
  9. karma的基础应用之与fis结合
  10. Dev Winform 简洁界面模板制作