[置顶] android触摸屏校正详解

最近一段时间在搞android的触摸屏校正,想把心得记下来与大家分享,废话不多说,开始讲解.

注:调试使用的是伟研科技(www.gzweiyan.com)210开发板,android版本 2.2 ,内核是2.6.32

一、修改内核驱动

  修改触摸屏驱动(kernel/drivers/input/touchscreen/s3c-ts.c)

      -input_set_abs_params(ts->dev, ABS_X, X_COOR_MIN, X_COOR_MAX, X_COOR_FUZZ, 0); -input_set_abs_params(ts->dev, ABS_Y, Y_COOR_MIN, Y_COOR_MAX, Y_COOR_FUZZ, 0); +input_set_abs_params(ts->dev, ABS_X, 0, 0xFFF, 0, 0); +input_set_abs_params(ts->dev, ABS_Y, 0, 0xFFF, 0, 0); -input_set_abs_params(ts->dev, ABS_MT_POSITION_X, X_COOR_MIN,X_COOR_MAX, 0, 0); -input_set_abs_params(ts->dev, ABS_MT_POSITION_Y, Y_COOR_MIN,Y_COOR_MAX, 0, 0); +input_set_abs_params(ts->dev, ABS_MT_POSITION_X, 0, 0xFFF, 0, 0); +input_set_abs_params(ts->dev, ABS_MT_POSITION_Y, 0, 0xFFF, 0, 0); if(m_status == 1){ input_report_abs(ts->dev, ABS_MT_TOUCH_MAJOR, 500); input_report_abs(ts->dev, ABS_MT_POSITION_X, m_lx); input_report_abs(ts->dev, ABS_MT_POSITION_Y, m_ly); +input_report_abs(ts->dev, ABS_PRESSURE, 1); printk("X1:%d Y1:%d/n",m_lx,m_ly); input_mt_sync(ts->dev); input_report_abs(ts->dev, ABS_MT_TOUCH_MAJOR, 500); input_report_abs(ts->dev, ABS_MT_POSITION_X, press_x); input_report_abs(ts->dev, ABS_MT_POSITION_Y, press_y); + input_report_abs(ts->dev, ABS_PRESSURE, 1); input_mt_sync(ts->dev); } else { input_report_abs(ts->dev, ABS_MT_TOUCH_MAJOR, 500); input_report_abs(ts->dev, ABS_MT_POSITION_X, x); input_report_abs(ts->dev, ABS_MT_POSITION_Y, y); + input_report_abs(ts->dev, ABS_PRESSURE, 1); printk("X2:%d Y2:%d/n",x,y); input_mt_sync(ts->dev); } #if 1 + input_report_abs(ts->dev, ABS_PRESSURE, 0); #endif /* !CONFIG_ANDROID */ 

  这样做的目的是根据使内核不使用限定好的坐标范围,x,y的坐标范围还原成0-4095

二、修改property_service.c(android2_2/system/core/init/property_service.c)  

 

在property_perms增加

 { "ts.config.calibrate" , AID_SYSTEM, 0 }

这样做的目的是为可以了后面使用触摸屏校正程序可以对ts.config.calibrate这个系统属性进行操作,后面会说到.

三、修改InputDevice.java(android2_2/frameworks/base/services/java/com/android/server/InputDevice.java)

 

在generateAbsMotion函数中增加

String prop = SystemProperties.get("ts.config.calibrate"); if (prop!=null) { if (prop.equalsIgnoreCase("start")){ Slog.d("XXW prop", prop); Slog.d("XXW", "prop.equalsIgnoreCase start"); device.tInfo = null; } else if (prop.equalsIgnoreCase("done")){ Slog.d("XXW prop", prop); Slog.d("XXW", "prop.equalsIgnoreCase done"); readCalibrate(); device.tInfo=tInfo; SystemProperties.set("ts.config.calibrate", "end"); } else{ Slog.i("XXW prop", prop); Slog.i("XXW", "prop.equalsIgnoreCase else"); } } 

这里使用到系统属性ts.config.calibrate,当系统判断为现在处于触摸屏校正模式的时候(也就是ts.config.calibrate值为start的时候),不对驱动传递上来的坐标值进行转换.

上面第二点在在property_perms增加{ "ts.config.calibrate" , AID_SYSTEM, 0 }是为了系统有权限可以设置/读取这个属性

增加函数

static void readCalibrate(){ //xxw added Slog.i("XXW","readCalibrate!"); TransformInfo t = null; try { FileInputStream is = new FileInputStream(CALIBRATION_FILE); byte[] mBuffer = new byte[64]; int len = is.read(mBuffer); is.close(); if (len > 0) { int i; for (i = 0 ; i < len ; i++) { if (mBuffer[i] == '/n'||mBuffer[i] == 0) { break; } } len = i; } StringTokenizer st = new StringTokenizer( new String(mBuffer, 0, 0, len)); t = new TransformInfo (); t.x1 = Integer.parseInt( st.nextToken() ); t.y1 = Integer.parseInt( st.nextToken() ); t.z1 = Integer.parseInt( st.nextToken() ); t.x2 = Integer.parseInt( st.nextToken() ); t.y2 = Integer.parseInt( st.nextToken() ); t.z2 = Integer.parseInt( st.nextToken() ); t.s = Integer.parseInt( st.nextToken() ); } catch (java.io.FileNotFoundException e) { Slog.i("XXW", "FileNotFound!"); } catch (java.io.IOException e) { Slog.i("XXW", "IOException"); } tInfo = t; Slog.i("XXW","readCalibrate done!"); } 

修改InputDevice函数

InputDevice(int _id, int _classes, String _name, AbsoluteInfo _absX, AbsoluteInfo _absY, AbsoluteInfo _absPressure, AbsoluteInfo _absSize) { id = _id; classes = _classes; name = _name; absX = _absX; absY = _absY; absPressure = _absPressure; absSize = _absSize; readCalibrate();  

 编译后生成services.jar,须替换android文件系统里面的system/framwork里面的services.jar

四、修改触摸屏校正程序
  修改onTouchEvent(CalibrationTest.java)
  CalibrationTest.java这里是我使用的触摸屏校正程序,我的屏的分辨率为800*480,所以改成
      mResultPts[(STEP -1) * mPtsLength] = event.getX()*4095/(800-1);
      mResultPts[(STEP -1) * mPtsLength + 1] = event.getY()*4095/(480-1);
     
修改AndroidManifest.xml 增加
 android:sharedUserId="android.uid.system"
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="touchscreen.test" android:sharedUserId="android.uid.system">
 修改 Android.mk增加
 LOCAL_CERTIFICATE := platform
   
五、修改init.rc增加
#create tslib
    mkdir /data/system/tslib/ 0777
    chmod 0666 /data/system/tslib/pointercal
触摸屏校正看来起貌似简单,但要改的东西确实太多,我自己也是摸索了好几天才搞定的,呵呵!

你可能感兴趣的:([置顶] android触摸屏校正详解)