Android自身不带触摸屏校验APP,我们一般都是采用tslib来完成触摸屏校验,网上的相关文章也不少,在此我记录下我的移植过程。
1.准备工作
首先我们要下载tslib的源码,以前在做QT时直接下载tslib源码,网上盛传的也很多,所以很容易下载,但是在此,我并非用的是tslib,而是tslibonandroid,到底与tslib有什么差异,我没仔细研究过,可能是太懒的缘故吧。
2.开始工作
我们现在就开始移植工作吧。首先把你的tslibonandroid文件包解压,放入external\tslibonandroid目录,这个文件夹中的tests\ts_calibrate.c具体实现触摸屏的校验,具体情形之后分析。
Android平台APP是要跑Java的,所以我们在此必须建立一个Java应用程序,实现我们在显示屏上的操作。在\development\calibrate\app_calibrate\src\com\android\calibrate添加源码,具体代码如下:
package com.android.calibrate;
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;
public class Calibrate extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/*
TextView tv = new TextView(this);
tv.setText( stringFromJNI() );
setContentView(tv);
*/
// super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
tsmainloop();
}
public native void tsmainloop();
static {
System.loadLibrary("calibrate-jni");
}
}
有了Java程序也不行,因为我们需要Java本地接口(即JNI),来实现Java与C本地库的交互,在development\calibrate\app_calibrate\ts_calibrate\jni\添加我们的JNI源码,代码如下:
#include <utils/Log.h>
#include <nativehelper/jni.h>
#include <stdio.h>
#include "http://www.cnblogs.com/../external/tslibonandroid/tests/calibratejni.h"
static void tsmainloop(JNIEnv *env, jobject object)
{
LOGE("hello jni calirate\n");
ts_main();
}
static const char *classPathName = "com/android/calibrate/Calibrate";
static JNINativeMethod methods[] = { //方法列表
{"tsmainloop", "()V", (void*)tsmainloop },
};
/*
* Register several native methods for one class.
*/
static int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods) //方法的注册
{
jclass clazz;
clazz = env->FindClass(className);
if (clazz == NULL) {
fprintf(stderr, "Native registration unable to find class '%s'", className);
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
fprintf(stderr, "RegisterNatives failed for '%s'", className);
return JNI_FALSE;
}
return JNI_TRUE;
}
/*
* Register native methods for all classes we know about.
*/
static int registerNatives(JNIEnv* env)
{
if (!registerNativeMethods(env, classPathName,
methods, sizeof(methods) / sizeof(methods[0]))) {
return JNI_FALSE;
}
return JNI_TRUE;
}
typedef union {
JNIEnv* env;
void* venv;
} UnionJNIEnvToVoid;
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
UnionJNIEnvToVoid uenv;
uenv.venv = NULL;
jint result = -1;
JNIEnv* env = NULL;
printf("JNI_OnLoad");
if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
fprintf(stderr, "GetEnv failed");
goto bail;
}
env = uenv.env;
if (!registerNatives(env)) {
fprintf(stderr, "registerNatives failed");
}
result = JNI_VERSION_1_4;
bail:
return result;
}
这部分主要实现JNI的注册及对下层提供调用接口。
3.touch校验
上面有提到ts_main(),它具体在\external\tslibonandroid\tests\ts_calibrate.c文件中,主要是实现5点校验。
#define TSLIB_TSDEVICE "/dev/input/event1"
#define DEVICE_NAME "/dev/myts" //myts设备名
#define TSLIB_CALIBFILE "/system/etc/pointercal"
#define TS_POINTERCAL "/system/etc/pointercal"
int ts_main()
{
struct tsdev *ts;
calibration cal;
int cal_fd;
char cal_buffer[256];
char *tsdevice = NULL;
char *calfile = NULL;
unsigned int i;
unsigned int ret;
signal(SIGSEGV, sig);
signal(SIGINT, sig);
signal(SIGTERM, sig);
int size;
char buffer[5] = "OK";
int fd = open("/dev/myts",O_RDWR);
if(fd == -1)
{
LOGE("...open device failed 1...");
return -1;
}
printf("fd: %d\n",fd);
write(fd,buffer,2);
close(fd);
if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL )
{
ts = ts_open(tsdevice,0);
LOGE("---tsdevice:%s getenv(TSLIB_TSDEVICE)!=NULL-----\n",tsdevice);
}
else
{
if (!(ts = ts_open("/dev/input/event1", 0)))
{
LOGE("---ts_open(/dev/input/event1)---failed\n");
ts = ts_open("/dev/touchscreen/ucb1x00", 0);
}
}
LOGE("ts configure\n");
if (!ts) {
LOGE("ts open failed\n");
ret = -1;
goto end;
}
if (ts_config(ts)) {
perror("ts_config");
LOGE("ts config failed\n");
ret = -1;
goto end;
}
if (open_framebuffer()) {
close_framebuffer();
LOGE("open_framebuffer failed\n");
ret = -1;
goto end;
}
for(i = 0; i < NR_COLORS; i++)
setcolor (i, palette [i]);
put_string_center (xres / 2, yres / 4, "TSLIB calibration utility", 1);
put_string_center (xres / 2, yres / 4 + 20, "Touch crosshair to calibrate", 2);
// printf("xres = %d, yres = %d\n", xres, yres);
// Clear the buffer
clearbuf(ts);
get_sample (ts, &cal, 0, 50, 50, "Top left");
clearbuf(ts);
get_sample (ts, &cal, 1, xres - 50, 50, "Top right");
clearbuf(ts);
get_sample (ts, &cal, 2, xres - 50, yres - 50, "Bot right");
clearbuf(ts);
get_sample (ts, &cal, 3, 50, yres - 50, "Bot left");
clearbuf(ts);
get_sample (ts, &cal, 4, xres / 2, yres / 2, "Center");
if(perform_calibration (&cal)) {
LOGE("Calibration constants: ");
for (i = 0; i < 7; i++)
LOGE("%d ", cal.a [i]);
if ((calfile = getenv("TSLIB_CALIBFILE")) != NULL) {
cal_fd = open (calfile, O_CREAT | O_RDWR,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
LOGE("getenv(TSLIB_CALIBFILE) OK");
} else {
cal_fd = open (TS_POINTERCAL, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
LOGE("getenv(TSLIB_CALIBFILE) NULL");
}
sprintf (cal_buffer,"%d %d %d %d %d %d %d",cal.a[1], cal.a[2], cal.a[0],cal.a[4], cal.a[5], cal.a[3], cal.a[6]);
write (cal_fd, cal_buffer, strlen (cal_buffer) + 1);
close (cal_fd);
i = 0;
} else {
LOGE("Calibration failed...");
i = -1;
}
close_framebuffer();
goto end2;
end:
i = ret;
end2:
#if 1
strcpy(buffer,"END");
fd = open("/dev/myts",O_RDWR);
if(fd == -1)
{
// printf("...open device failed...\n");
LOGE("...open device failed 2...");
return -1;
}
printf("fd: %d\n",fd);
write(fd,buffer,3);
close(fd);
#endif
//---------------------------------------
return i;
}