给android增加屏幕校准

news/2024/10/22 7:25:43/

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()函数来实现的。所以只需要将该函数移植过来就可以。这里将该函数及用到的数据结构代码贴出来如下:

 

有了上面的基础,接下来就是将上面的代码移植到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文件代码如下

 


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

相关文章

Android屏幕校准

android原始版本里是没有屏幕校准功能的&#xff0c;tp坐标到lcd坐标是完全按照线性关系来转换的。例如&#xff0c;tp坐标是(Xt ,Yt )分辨率是&#xff08;Wt x Ht &#xff09;&#xff0c;lcd坐标是(X,Y)&#xff0c;分辨率是(W x H)&#xff0c;则 X(Xt *W)/Wt&#xff0c;…

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