首先说下思路,本文采用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)

使用JNI封装底层input系统提供的event事件的更多相关文章

  1. Android 4.0 事件输入(Event Input)系统

    参考:http://blog.csdn.net/myarrow/article/details/7091061 1. TouchScreen功能在Android4.0下不工作 原来在Android2. ...

  2. Linux input系统数据上报流程【转】

    转自:https://segmentfault.com/a/1190000017255939 作为鸡生蛋系列文章,这里主要关注Linux input系统,主要为触摸事件上报流程. 读该文章最好有对li ...

  3. 选择排序法、冒泡排序法、插入排序法、系统提供的底层sort方法排序之毫秒级比较

    我的代码: package PlaneGame;/** * 选择排序法.冒泡排序法.插入排序法.系统提供的底层sort方法排序之毫秒级比较 * @author Administrator */impo ...

  4. UIView封装动画--iOS利用系统提供方法来做转场动画

    UIView封装动画--iOS利用系统提供方法来做转场动画 UIViewAnimationOptions option; if (isNext) { option=UIViewAnimationOpt ...

  5. UIView封装动画--iOS利用系统提供方法来做关键帧动画

    iOS利用系统提供方法来做关键帧动画 ios7以后才有用. /*关键帧动画 options:UIViewKeyframeAnimationOptions类型 */ [UIView animateKey ...

  6. UIView封装动画--iOS 利用系统提供方法来做弹性运动

    iOS 利用系统提供方法来做弹性运动 /*创建弹性动画 damping:阻尼,范围0-1,阻尼越接近于0,弹性效果越明显 velocity:弹性复位的速度 */ [UIView animateWith ...

  7. Linux 下Input系统应用编程实战

    作者:杨源鑫(也是我们的校园代理) 经授权转载于公众号嵌入式开发圈,有些许修改. 什么是input子系统?不管是什么操作系统,都有一个程序用于管理各种输入设备,哪些是输入设备?比如,电脑键盘.鼠标,智 ...

  8. iOS系统提供开发环境下命令行编译工具:xcodebuild

    iOS系统提供开发环境下命令行编译工具:xcodebuild[3] xcodebuild 在介绍xcodebuild之前,需要先弄清楚一些在XCode环境下的一些概念[4]: Workspace:简单 ...

  9. IP编辑控件(因为封装的是系统自带控件,所以也使用了CreateSubClass,不过为啥要封装CN_COMMAND和CN_NOTIFY不是很明白)

    最近需要用一个IP输入控件,网上找了几个,都不符合效果,有些还有一些奇怪的Bug.后来发现原来系统已经提供了IP地址编辑控件,只是系统提供的控件不能设置只读效果.网上找了下资料,封装了一下,自己迂回一 ...

随机推荐

  1. sql语句优化SQL Server

    MS   SQL   Server查询优化方法查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)          2.I/O吞吐量小,形成了 ...

  2. Linux解决乱码问题

    主要的关注点是本身文件的编码和Linux的编码是否相同, 如果不相同的话,那么修改 例如: 就OK了,如果还是有问题的话,那么就查看一下连接工具的编码是否设置的有问题. 一般情况下,主要注意这些问题, ...

  3. linux 共享内存 shmat,shmget,shmdt,shmctl

    shmget int shmget(key_t key, size_t size, int flag);//开辟一段共享内存 key_t key :标识符的规则() size_t size :共享内存 ...

  4. [moka同学摘录]SQL内联、外联的简单理解

    (源自:http://blog.csdn.net/kkk9127/article/details/1487686) --查询分析器中执行:--建表table1,table2:create table ...

  5. big-endian和little-endian

    1.故事的起源 "endian"这个词出自<格列佛游记>.小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开 ...

  6. ABP之模块

    ABP的反射 为什么先讲反射,因为ABP的模块管理基本就是对所有程序集进行遍历,再筛选出AbpModule的派生类,再按照以来关系顺序加载. ABP对反射的封装着重于程序集(Assembly)与类(T ...

  7. 推荐15款响应式的 jQuery Lightbox 插件

    利用现代 Web 技术,网络变得越来越轻巧与.模态框是突出展现内容的重要形式,能够让用户聚焦到重要的内容上去.在这个列表中,我们编制了15款响应式的 jQuery 灯箱库,这将有助于开发人员创建和设计 ...

  8. js 数组去重(7种)

    第一次写技术博客,之前总是认为写这些会很浪费时间,还不如多看几篇技术博文.但...但昨天不知道受了什么刺激,好像有什么在驱使着自己要写一样,所以才有了今天的第一篇博文.总觉得应该要坚持这样写下去.初次 ...

  9. 对CVE-2014-6271 [破壳漏洞] 的一次不太深入的跟踪

    @firtst:有些事,该你遇到的始终会遇到!2013年,Struts2远程代码执行漏洞闹的满城风雨时,当时还对此一无所知:2014年4月,HeartBleed掀起波涛汹涌时,较快对此予以关注,晚上跑 ...

  10. iOS之应用发布中的一些细节

    Bundle identifier Xcode中 Target -> General中的bundle identifier ; info.plist中的Bundle identifier; 证书 ...