Android屏幕校准

news/2024/11/30 15:47:38/

 

android原始版本里是没有屏幕校准功能的,tp坐标到lcd坐标是完全按照线性关系来转换的。例如,tp坐标是(Xt ,Yt )分辨率是(Wt x Ht ),lcd坐标是(X,Y),分辨率是(W x H),则 X=(Xt *W)/Wt, Y=(Yt *H)/Ht 。但是一般触摸屏不是完全线性的,自然转换关系也就不一样了,好在有tslib,能帮我们解决这个问题。但是android里没有tslib,我们也不需 要完全将tslib移植过来,只需要其中根据采样点生成转换矩阵的部分,这部分是由ts_calibrate.c文件中的 perform_calibration()函数来实现的。所以只需要将该函数移植过来就可以。这里将该函数及用到的数据结构代码贴出来如下:

typedef struct{

       int x[5], xfb[5];      //x[5],y[5]是分别是tp五个点的x,y坐标,xfb[5],yfb[5]是lcd五个点的x,y坐标。

       int y[5], yfb[5];

       int a[7];                //a[7]是生成的7个转换参数,tp到lcd坐标转换方程是: Xlcd = (Xtp *a[1] + Ytp *a[2] + a[0])/a[6]

}calibration;               //  Ylcd = (Xtp *a[4] + Ytp *a[5] + a[3])/a[6]

int perform_calibration(calibration *cal) {
          int j;
         float n, x, y, x2, y2, xy, z, zx, zy;
         float det, a, b, c, e, f, i;
         float scaling = 65536.0;
 
 // Get sums for matrix
         n = x = y = x2 = y2 = xy = 0;
         for(j=0;j<5;j++) {
                 n += 1.0;
                 x += (float)cal->x[j];
                 y += (float)cal->y[j];
                 x2 += (float)(cal->x[j]*cal->x[j]);
                 y2 += (float)(cal->y[j]*cal->y[j]);
                 xy += (float)(cal->x[j]*cal->y[j]);
         }
 
 // Get determinant of matrix -- check if determinant is too small
         det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2);
         if(det < 0.1 && det > -0.1) {
                 printf("ts_calibrate: determinant is too small -- %f/n",det);
                 return 0;
         }
 
 // Get elements of inverse matrix
         a = (x2*y2 - xy*xy)/det;
         b = (xy*y - x*y2)/det;
         c = (x*xy - y*x2)/det;
         e = (n*y2 - y*y)/det;
         f = (x*y - n*xy)/det;
         i = (n*x2 - x*x)/det;
 
 // Get sums for x calibration
         z = zx = zy = 0;
         for(j=0;j<5;j++) {
                 z += (float)cal->xfb[j];
                 zx += (float)(cal->xfb[j]*cal->x[j]);
                 zy += (float)(cal->xfb[j]*cal->y[j]);
         }
 // Now multiply out to get the calibration for framebuffer x coord
         cal->a[0] = (int)((a*z + b*zx + c*zy)*(scaling));
         cal->a[1] = (int)((b*z + e*zx + f*zy)*(scaling));
         cal->a[2] = (int)((c*z + f*zx + i*zy)*(scaling));

         printf("%f %f %f/n",(a*z + b*zx + c*zy),
                                 (b*z + e*zx + f*zy),
                                 (c*z + f*zx + i*zy));

 // Get sums for y calibration
         z = zx = zy = 0;
         for(j=0;j<5;j++) {
                 z += (float)cal->yfb[j];
                 zx += (float)(cal->yfb[j]*cal->x[j]);
                 zy += (float)(cal->yfb[j]*cal->y[j]);
         }
 
 // Now multiply out to get the calibration for framebuffer y coord
         cal->a[3] = (int)((a*z + b*zx + c*zy)*(scaling));
         cal->a[4] = (int)((b*z + e*zx + f*zy)*(scaling));
         cal->a[5] = (int)((c*z + f*zx + i*zy)*(scaling));

         printf("%f %f %f/n",(a*z + b*zx + c*zy),
                                 (b*z + e*zx + f*zy),
                                 (c*z + f*zx + i*zy));
 
 // If we got here, we're OK, so assign scaling to a[6] and return
         cal->a[6] = (int)scaling;
         return 1;

有了上面的基础,接下来就是将上面的代码移植到android中并在setting里面添加屏幕校准入口,要完成这些,需要修改的文件有:

1. frameworks/base/services/java/com/android/server/InputDevice.java

2. packages/apps/Settings/AndroidManifest.xml

3. packages/apps/Settings/res/xml/settings.xml

另外在Setting源码目录里再添加一个Calibration.java文件。

frameworks/base/services/java/com/android/server/InputDevice.java修改的地方如下(红色 表示添加,蓝色 表示删除):

public class InputDevice {
     static final boolean DEBUG_POINTERS = false;
     static final boolean DEBUG_HACKS = false;
 
     /** Amount that trackball needs to move in order to generate a key event. */
     static final int TRACKBALL_MOVEMENT_THRESHOLD = 6;
 
     /** Maximum number of pointers we will track and report. */
     static final int MAX_POINTERS = 10;
 
     static final String CALIBRATION_FILE="/data/pointercal"; 
 
     final int id;
     final int classes;
     final String name;
     final AbsoluteInfo absX;
     final AbsoluteInfo absY;
     final AbsoluteInfo absPressure;
     final AbsoluteInfo absSize;

     ....................

            final AbsoluteInfo absX = device.absX;
             final AbsoluteInfo absY = device.absY;
             final AbsoluteInfo absPressure = device.absPressure;
             final AbsoluteInfo absSize = device.absSize;
 
             float tmpX = 0;    
             float tmpY = 0;
             String prop = SystemProperties.get("sys.config.calibrate", "noset");
 
             if ( !prop.equalsIgnoreCase("loaded") )
             {
                     if ( prop.equalsIgnoreCase("start") )
                     {
                         TransformInfo.xs =  0;
                         TransformInfo.ys =  0;
                     }
                     else if ( prop.equalsIgnoreCase("done") )
                     {
                         readCalibrate();
                     }
 
                     if ( TransformInfo.xs == 0 && absX != null )
                     {
                         TransformInfo.x1 = w;
                         TransformInfo.y1 = 0;
                         TransformInfo.z1 = 0-absX.minValue*w;
                         TransformInfo.xs =  absX.range;
                     }
                     if ( TransformInfo.ys == 0 && absY != null )
                     {
                         TransformInfo.x2 = 0;
                         TransformInfo.y2 = h;
                         TransformInfo.z2 = 0-absY.minValue*h;
                         TransformInfo.ys =  absY.range;
                     }
                     SystemProperties.set("sys.config.calibrate", "loaded");
             }

            for (int i=0; i<numPointers; i++) {
                 final int j = i * MotionEvent.NUM_SAMPLE_DATA;

                 tmpX = reportData[j + MotionEvent.SAMPLE_X];
                 tmpY = reportData[j + MotionEvent.SAMPLE_Y];
                 if (absX != null ) {
                    reportData[j + MotionEvent.SAMPLE_X] =
                             ((reportData[j + MotionEvent.SAMPLE_X]-absX.minValue)
                                 / absX.range) * w; 

                      reportData[j + MotionEvent.SAMPLE_X] = (TransformInfo.x1 * tmpX + TransformInfo.y1 * tmpY + TransformInfo.z1) / TransformInfo.xs;
                 }
                 if (absY != null ) {
                    reportData[j + MotionEvent.SAMPLE_Y] =
                             ((reportData[j + MotionEvent.SAMPLE_Y]-absY.minValue)
                                 / absY.range) * h;

                      reportData[j + MotionEvent.SAMPLE_Y] = (TransformInfo.x2 * tmpX + TransformInfo.y2 * tmpY + TransformInfo.z2) / TransformInfo.ys;
                 }
                 if (absPressure != null) {
                     reportData[j + MotionEvent.SAMPLE_PRESSURE] =
                             ((reportData[j + MotionEvent.SAMPLE_PRESSURE]-absPressure.minValue)
                                 / (float)absPressure.range);
                 }
                 if (absSize != null) {
                     reportData[j + MotionEvent.SAMPLE_SIZE] =
                             ((reportData[j + MotionEvent.SAMPLE_SIZE]-absSize.minValue)
                                 / (float)absSize.range);
                 }

    ..................................

     static class AbsoluteInfo {
         int minValue;
         int maxValue;
         int range;
      int flat;
         int fuzz;
      };
 
      static class TransformInfo {
         static int x1;
         static int y1;
         static int z1;
         static int x2;
         static int y2;
         static int z2;
         static int xs;
         static int ys;
     };
 
     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;
 
         TransformInfo.xs =  0;
         TransformInfo.ys =  0;
         readCalibrate();

 } 
    static void readCalibrate(){
             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, len));
 
                 TransformInfo.x1 = Integer.parseInt(st.nextToken());
                 TransformInfo.y1 = Integer.parseInt(st.nextToken());
                 TransformInfo.z1 = Integer.parseInt(st.nextToken());
                 TransformInfo.x2 = Integer.parseInt(st.nextToken());
                 TransformInfo.y2 = Integer.parseInt(st.nextToken());
                 TransformInfo.z2 = Integer.parseInt(st.nextToken());
                 TransformInfo.xs = Integer.parseInt(st.nextToken());
                 TransformInfo.ys = TransformInfo.xs;
                 SystemProperties.set("sys.config.calibrate", "loaded");
             } catch (java.io.FileNotFoundException e) {
                 Log.i("InputDevice", "calibration file not found exception");
             } catch (java.io.IOException e) {
                 Log.i("InputDevice", "io exception");
             } catch (java.lang.NumberFormatException e) {
                Log.i("InputDevice", "number format exception");
             }
   }

};

packages/apps/Settings/AndroidManifest.xml文件修改地方如下:

         <activity android:name=".fuelgauge.PowerUsageDetail"
                 android:label="@string/details_title">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
 
         <activity android:name="Calibration" 
                 android:label="@string/screen_calibration_settings">
               <intent-filter>
                   <action android:name="android.intent.action.MAIN" />
                   <category android:name="android.intent.category.DEFAULT" />
               </intent-filter>
         </activity> 
 
         <receiver android:name=".widget.SettingsAppWidgetProvider" android:label="@string/gadget_title">
             <intent-filter>
                 <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />

packages/apps/Settings/res/xml/settings.xml文件修改地方如下:

        <com.android.settings.IconPreferenceScreen
             settings:icon="@drawable/ic_settings_date_time"
             android:title="@string/date_and_time_settings_title">
             <intent
                 android:action="android.intent.action.MAIN"
                 android:targetPackage="com.android.settings"
                 android:targetClass="com.android.settings.DateTimeSettings" />
         </com.android.settings.IconPreferenceScreen>
 
         <!-- touchscreen Calibration -->
         <com.android.settings.IconPreferenceScreen
              settings:icon="@drawable/ic_settings_privacy"
              android:title="@string/screen_calibration_settings">
              <intent 
                 android:action="android.intent.action.MAIN"
                 android:targetPackage="com.android.settings"
                 android:targetClass="com.android.settings.Calibration"/>
         </com.android.settings.IconPreferenceScreen>
 
 
         <!-- About Device -->
 
         <com.android.settings.IconPreferenceScreen
             settings:icon="@drawable/ic_settings_about"
             android:title="@string/about_settings">
             <intent
                 android:action="android.intent.action.MAIN"
                 android:targetPackage="com.android.settings"
                 android:targetClass="com.android.settings.DeviceInfoSettings" />
         </com.android.settings.IconPreferenceScreen>

Calibration.java文件代码如下

 

view plain copy to clipboard print ?
  1. package com.android.settings;    
  2. import java.io.FileNotFoundException;    
  3. import java.io.FileOutputStream;    
  4. import java.io.IOException;    
  5. import android.app.Activity;    
  6. import android.content.Context;    
  7. import android.graphics.Bitmap;    
  8. import android.graphics.Canvas;    
  9. import android.graphics.Color;    
  10. import android.graphics.Paint;    
  11. import android.os.Bundle;    
  12. import android.os.RemoteException;    
  13. import android.os.ServiceManager;    
  14. import android.util.Log;    
  15. import android.view.Display;    
  16. import android.view.IWindowManager;    
  17. import android.view.MotionEvent;    
  18. import android.view.View;    
  19. import android.view.Window;    
  20. import android.view.WindowManager;    
  21. import android.widget.Toast;    
  22. import android.os.SystemProperties;    
  23. public class Calibration extends Activity {    
  24. static final int SAMPLE_COUNTS = 5;    
  25. static final int POINT_DEGREE = 2;    
  26. static final int FACTOR_COUNTS = 7;    
  27. static final int TOP_LEFT = 0;    
  28. static final int TOP_RIGHT = 1;    
  29. static final int BOTTOM_RIGHT = 2;    
  30. static final int BOTTOM_LEFT = 3;    
  31. static final int CENTER = 4;    
  32. static final int X_AXIS = 0;    
  33. static final int Y_AXIS = 1;    
  34. static final int EDGE_GAP = 50;    
  35.      
  36. static final String CALIBRATION_FILE = "/data/pointercal";    
  37. static final String TAG = "Calibration";    
  38. static final boolean DEBUG = true;    
  39.       
  40. private int X_RES;    
  41. private int Y_RES;    
  42. private Display dpy;    
  43.        
  44. class calibration {    
  45.      int x[] = new int[5];    
  46.      int y[] = new int[5];    
  47.      int xfb[] = new int[5];    
  48.      int yfb[] = new int[5];    
  49.      int a[] = new int[7];    
  50. };    
  51. private calibration cal;    
  52. @Override    
  53. protected void onCreate(Bundle savedInstanceState) {    
  54.     super.onCreate(savedInstanceState);    
  55.     SystemProperties.set("sys.config.calibrate""start");    
  56.     cal = new calibration();    
  57.         
  58.     dpy = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();    
  59.     X_RES = dpy.getWidth();    
  60.     Y_RES = dpy.getHeight();    
  61.           
  62.     this.initScreenPoints();    
  63.          
  64.     setContentView(new MyView(this));    
  65. }    
  66.           
  67. // TopLeft-->TopRight-->BottomRight-->BottomLeft-->Center    
  68. // For 240 * 320 resolution, we use 50 pixel as edge gap    
  69.  private boolean initScreenPoints() {    
  70.     cal.xfb[TOP_LEFT] = EDGE_GAP;               // TopLeft    
  71.     cal.yfb[TOP_LEFT] = EDGE_GAP;    
  72.           
  73.     cal.xfb[TOP_RIGHT] = X_RES - EDGE_GAP;      // TopRight    
  74.     cal.yfb[TOP_RIGHT] = EDGE_GAP;    
  75.         
  76.     cal.xfb[BOTTOM_RIGHT] = X_RES - EDGE_GAP;   // BottomRight    
  77.     cal.yfb[BOTTOM_RIGHT] = Y_RES - EDGE_GAP;    
  78.         
  79.     cal.xfb[BOTTOM_LEFT] = EDGE_GAP;            // BottomLeft    
  80.     cal.yfb[BOTTOM_LEFT] = Y_RES - EDGE_GAP;    
  81.         
  82.     cal.xfb[CENTER] = X_RES / 2;                // Center    
  83.     cal.yfb[CENTER] = Y_RES / 2;            
  84.     return true;    
  85. }    
  86.         
  87.  private boolean perform_calibration() {    
  88.     float n, x, y, x2, y2, xy, z, zx, zy;    
  89.     float det, a, b, c, e, f, g;    
  90.     float scaling = (float)65536.0;    
  91.           
  92.     n = x = y = x2 = y2 = xy = 0;    
  93.     for (int i = 0; i < SAMPLE_COUNTS; i++) {    
  94.         n += 1.0;    
  95.         x += (float)cal.x[i];    
  96.         y += (float)cal.y[i];    
  97.         x2 += (float)(cal.x[i] * cal.x[i]);    
  98.         y2 += (float)(cal.y[i] * cal.y[i]);    
  99.         xy += (float)(cal.x[i] * cal.y[i]);    
  100.     }    
  101.             
  102.     det = n * (x2 * y2 - xy * xy) + x * (xy * y - x * y2) + y * (x * xy - y * x2);    
  103.     if (det < 0.1 && det > -0.1) {    
  104.         Log.w("bigcren""determinant is too small, det =" + det);    
  105.         return false;    
  106.     }    
  107.       
  108.     if (DEBUG) {    
  109.         Log.i("bigcren""(n,x,y,x2,y2,xy,det)=("    
  110.             + n + ","    
  111.             + x + ","    
  112.             + y + ","    
  113.             + x2 + ","    
  114.             + y2 + ","    
  115.             + xy + ","    
  116.             + det + ")");    
  117.         }    
  118.       
  119.     a = (x2 * y2 - xy * xy) / det;    
  120.     b = (xy * y - x * y2) / det;    
  121.     c = (x * xy - y * x2) / det;    
  122.     e = (n * y2 - y * y) / det;    
  123.     f = (x * y - n * xy) / det;    
  124.     g = (n * x2 - x * x) / det;    
  125.           
  126.     Log.i("bigcren""(a,b,c,e,f,g)=("    
  127.         + a + ","    
  128.         + b + ","    
  129.         + c + ","    
  130.         + e + ","    
  131.         + f + ","    
  132.         + g + ")");    
  133.            
  134.     // Get sums for x calibration    
  135.     z = zx = zy = 0;    
  136.     for(int i = 0; i < SAMPLE_COUNTS; i++) {    
  137.         z += (float)cal.xfb[i];    
  138.         zx += (float)(cal.xfb[i] * cal.x[i]);     
  139.         zy += (float)(cal.xfb[i] * cal.y[i]);    
  140.     }    
  141.       
  142.     // Now multiply out to get the calibration for X coordination    
  143.     cal.a[0] = (int)((a * z + b * zx + c * zy) * (scaling));    
  144.     cal.a[1] = (int)((b * z + e * zx + f * zy) * (scaling));    
  145.     cal.a[2] = (int)((c * z + f * zx + g * zy) * (scaling));    
  146.     // Get sums for y calibration    
  147.     z = zx = zy = 0;    
  148.     for(int i = 0;i < SAMPLE_COUNTS; i++) {    
  149.         z += (float)cal.yfb[i];    
  150.         zx += (float)(cal.yfb[i] * cal.x[i]);    
  151.         zy += (float)(cal.yfb[i] * cal.y[i]);    
  152.     }    
  153.       
  154.     // Now multiply out to get the calibration for Y coordination    
  155.     cal.a[3] = (int)((a * z + b * zx + c * zy) * (scaling));    
  156.     cal.a[4] = (int)((b * z + e * zx + f * zy) * (scaling));    
  157.     cal.a[5] = (int)((c * z + f * zx + g * zy) * (scaling));    
  158.               
  159.     cal.a[6] = (int)scaling;        
  160.              
  161.     return true;    
  162.     }       
  163.       
  164.     private boolean saveCalibrationResult() {    
  165.         FileOutputStream os;    
  166.         String res = "";    
  167.           
  168.     // save the calibration factor in file system for InputDevice    
  169.     try {    
  170.         os = new FileOutputStream(CALIBRATION_FILE);    
  171.         res = String.format("%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]);    
  172.             
  173.         if (DEBUG) {    
  174.             Log.i("bigcren""calibration result=" + res);    
  175.         }    
  176.           
  177.         os.write(res.getBytes());    
  178.         os.close();    
  179.     } catch (FileNotFoundException e1) {    
  180.     // TODO Auto-generated catch block    
  181.         e1.printStackTrace();    
  182.         Log.w(TAG, "open calibration file write error: " + CALIBRATION_FILE );    
  183.     } catch (IOException e) {    
  184.     // TODO Auto-generated catch block    
  185.     e.printStackTrace();    
  186.     }    
  187.     return true;    
  188.  }       
  189.              
  190. public class MyView extends View {    
  191.     private Canvas cv;    
  192.     private Paint paint;    
  193.     private Bitmap bmp;     
  194.     private int screen_pos;    
  195.     private Context mContext;    
  196.     public MyView(Context c) {    
  197.     super(c);    
  198.     // set full screen and no title    
  199.     requestWindowFeature(Window.FEATURE_NO_TITLE);    
  200.     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,    
  201.             WindowManager.LayoutParams.FLAG_FULLSCREEN);    
  202.     mContext=c;    
  203.     paint = new Paint();    
  204.     paint.setDither(true);    
  205.     paint.setAntiAlias(true);    
  206.     paint.setStrokeWidth(2);    
  207.     paint.setColor(Color.WHITE);    
  208.     paint.setStyle(Paint.Style.STROKE);    
  209.     bmp = Bitmap.createBitmap(X_RES, Y_RES, Bitmap.Config.ARGB_8888);    
  210.     cv = new Canvas(bmp);    
  211.     screen_pos = 0;    
  212.     drawCalibrationCross(screen_pos);    
  213. }    
  214.                
  215. protected void onDraw(Canvas canvas) {    
  216.         canvas.drawColor(Color.BLACK);    
  217.         canvas.drawBitmap(bmp, 00null);    
  218. }           
  219.          
  220. private boolean drawCalibrationCross(int pos) {    
  221.     if (DEBUG) {    
  222.         Log.i("bigcren""draw cross at pos " + pos);    
  223.     }    
  224.              
  225.     cv.drawColor(Color.BLACK);    
  226.          
  227.     // draw X line    
  228.     cv.drawLine(cal.xfb[pos] - 10, cal.yfb[pos],    
  229.         cal.xfb[pos] - 2, cal.yfb[pos], paint);    
  230.     cv.drawLine(cal.xfb[pos] + 2, cal.yfb[pos],    
  231.         cal.xfb[pos] + 10, cal.yfb[pos], paint);    
  232.         
  233.     // draw Y line    
  234.     cv.drawLine(cal.xfb[pos], cal.yfb[pos] - 10,    
  235.         cal.xfb[pos], cal.yfb[pos] - 2, paint);    
  236.     cv.drawLine(cal.xfb[pos], cal.yfb[pos] + 2,    
  237.         cal.xfb[pos], cal.yfb[pos] + 10, paint);                
  238.     invalidate();    
  239.     return true;    
  240. }  
  241.     
  242. public boolean onTouchEvent(MotionEvent event) {    
  243.     float tmpx, tmpy;    
  244.     boolean ret;    
  245.     if (screen_pos > SAMPLE_COUNTS - 1) {    
  246.         Log.i("bigcren""get sample ok");    
  247.         return true;    
  248.     }    
  249.         
  250.     if (event.getAction() == MotionEvent.ACTION_UP) {    
  251.         tmpx = event.getX();    
  252.         tmpy = event.getY();    
  253.         if(Math.abs(cal.xfb[screen_pos]-tmpx)>15&&    
  254.             Math.abs(cal.yfb[screen_pos]-tmpy)>15){    
  255.                 Toast.makeText(mContext, R.string.calibration_error,Toast.LENGTH_SHORT).show();    
  256.         return false;    
  257.     }    
  258.          
  259.     cal.x[screen_pos] = (int)(event.getX()*4096.0/(float)X_RES + 0.5);    
  260.     cal.y[screen_pos] = (int)(event.getY()*4096.0/(float)Y_RES + 0.5);    
  261.          
  262.     if (screen_pos == 4) {    
  263.         ret = perform_calibration();    
  264.         if (ret) {    
  265.             saveCalibrationResult();     
  266.             SystemProperties.set("sys.config.calibrate""done");    
  267.             finish();    
  268.             return true;    
  269.             } else {    
  270.             screen_pos = 0;    
  271.             Log.w(TAG, "Calibration failed");    
  272.             }    
  273.         } else {    
  274.             screen_pos++;    
  275.             drawCalibrationCross(screen_pos);    
  276.             }    
  277.         }    
  278.         return true;    
  279.         }           
  280.     }    
  281. }    

 

转自:

http://blog.csdn.net/king_sundi/archive/2011/01/19/6152865.aspx

 

http://blogold.chinaunix.net/u3/90973/showart_2162315.html

 

 

http://blog.csdn.net/cpuwolf/archive/2011/01/11/6130010.aspx

http://blog.csdn.net/dafeifly/archive/2009/10/13/4662498.aspx


http://www.ppmy.cn/news/430944.html

相关文章

6.Sentincl控制台 规则 实战

一、流控规则 流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。一条限流规则主要由下面几个因素组成,我们可以组合这些元素来实现不同的限流效果: Fiel…

百度网盘转存腾讯微云

https://www.zhihu.com/question/21879203

程序下载微云

https://share.weiyun.com/5OxmUiI

全速下载微云方法

下载tim 测试版 版本TIM_2.5.8.apk https://www.lanzous.com/iaroy3i 登陆QQ小号 转储文件至微云 QQ小号登陆tim 文件-》微云文件 找到文件 点进去 点右上角转发到qq大号上 &#xff0c;全速下载

教你怎样无需微云会员满速下载文件

本方法可以无需微云会员满速下载微云文件&#xff0c;但是只限电脑端。 第一步&#xff1a;先把要下载的文件保存到自己微云里 第二步&#xff1a;然后打开手机QQ聊天框->点击文件 选择微云->其他->找到要下载的文件点击发送 第三步&#xff1a;然后打开电脑QQ接收…

腾讯微云免费领取一个月会员

腾讯微云免费领取一个月会员 手机下载腾讯微云->登录后->我的->免费试用->连续包月->显示0元就开->没显示试用就别开了或者换号->开了后去关闭自动续费 关闭自动续费&#xff1a; 苹果&#xff1a;去设置->Apple ID->订阅->找到微云会员->…

share.weiyun.com 微云无法打开 解决办法

修改文件&#xff1a; C:\Windows\System32\drivers\etc在末尾添加&#xff1a; 220.194.91.237 share.weiyun.com

华为系统gps定位服务器地址,华为手机gps在哪里打开 华为手机gps打开方法

是手机中必备的定位服务&#xff0c;打开GPS后大家的手机会被准确定位&#xff0c;所以了解当前手机的GPS位置也是很有必要的&#xff0c;这里为大家带来有关GPS的位置&#xff0c;看一下在哪里打开吧。 定位服务为基于位置的应用收集和提供手机的位置信息&#xff0c;比如&…