首页 » 技术文章 » 技能进阶:Android 屏幕操作原理

技能进阶:Android 屏幕操作原理

 

本文将介绍下AndroidonTouchEvent的实现原理以及调用流程。

android Activity或View 里有 onTouchEvent() 事件,当我们对手机的屏幕进行操作,如点击、移动、抬起,都会触发 onTouchEvent 事件。

一、onTouchEvent事件常用的几种操作

onTouchEvent事件常用的几种操作,可使用 switch(event.getAction() & MotionEvent.ACTION_MASK)进行区分:

@Override
public boolean onTouchEvent(MotionEvent event)
{
    switch(event.getAction() & MotionEvent.ACTION_MASK)
    {
        case MotionEvent.ACTION_DOWN: 
        {
            // 屏幕接到单点触碰事件
            // do someting
            break;
        }
        case MotionEvent.ACTION_POINTER_DOWN:
        {
            // 当屏幕接收到屏幕1点以上(多点)触碰,都会响应到此事件
            // do smoeting
            break;
        }
        case MotionEvent.ACTION_UP:
        {
            // 屏幕点击的最后一个点都抬起,就会触发此事件
            // do smoeting
            break;
        }
        case MotionEvent.ACTION_POINTER_UP:
        {
            // 抬起后还有多于1个点在屏幕的都会触发此事件
            // do smoeting
            break;
        }
        case MotionEvent.ACTION_MOVE:
        {
            // 所有的接触点移动都会触发此事件
            // do smoeting
            break;
        }
    }
}

 

二、多点触控使用 event.getAction() & MotionEvent.ACTION_MASK 原因:

我们首先来看看MotionEvent下的一些常量值:

ACTION_MASK = 0xff;
ACTION_DOWN = 0x0;
ACTION_UP = 0x1;
ACTION_MOVE = 0x2;
ACTION_POINTER_DOWN = 0x5;
ACTION_POINTER_UP = 0x6;
// 以下属性在api level 8(即android 2.2)已经过时,不再使用 
// 已改用上面的 ACTION_POINTER_DOWN和 ACTION_POINTER_UP
ACTION_POINTER_1_DOWN = ACTION_POINTER_DOWN |0x0000;
ACTION_POINTER_2_DOWN = ACTION_POINTER_DOWN | 0x0100;
ACTION_POINTER_3_DOWN = ACTION_POINTER_DOWN | 0x0200;
ACTION_POINTER_1_UP  = ACTION_POINTER_UP | 0x0000;
ACTION_POINTER_2_UP  = ACTION_POINTER_UP | 0x0100;
ACTION_POINTER_3_UP  = ACTION_POINTER_UP | 0x0200;

例如:ACTION_MASK &ACTION_POINTER_2_DOWN 即: 0xff & 0x05 =5; 所以触发的是ACTION_POINTER_DOWN件事。

三、当我们触控屏幕的时候会发现什么事呢?

我们可以通过adb查看我们对屏幕所做的一切记录,下面我们就说说如何解读even的操作。

adb 查看event可以查看到所有关于此手机的一些操作,但我们只关注屏幕操作的一些事件,可以通过 adb shell getevent -p 查看信息,看到像下面的字样,这样你就可以找到屏幕操作在那个事件里:

// 当你看到有像以下这样的字段,那么就证明你的屏幕操作事件在event3里 
add device 5: /dev/input/event3
  name:     "mtk-tpd"
  events:
    KEY (0001):008b  009e  00ac 0145  0148  014a 014d  014e
               014f
    ABS (0003):0000  : value 0, min 0, max 1080, fuzz 0,flat 0, resolution 1080
               0001  : value 0, min 0, max 1920,fuzz 0, flat 0, resolution 1920
               0018  : value 0, min 0, max 255,fuzz 0, flat 0, resolution 0
               002f  : value 0, min 0, max 9,fuzz 0, flat 0, resolution 0
               0030  : value 0, min 0, max 100,fuzz 0, flat 0, resolution 0
               0031  : value 0, min 0, max 100,fuzz 0, flat 0, resolution 0
               0035  : value 0, min 0, max 1080,fuzz 0, flat 0, resolution 0
               0036  : value 0, min 0, max 1920,fuzz 0, flat 0, resolution 0
               0039  : value 0, min 0, max 65535,fuzz 0, flat 0, resolution 0
               003a  : value 0, min 0, max 255,fuzz 0, flat 0, resolution 0
  input props:
   INPUT_PROP_POINTER
   INPUT_PROP_DIRECT

那么我们就可以去查看对应的事件内容了。

使用adb shell getevent/dev/input/event3,这时候你试下点击一下手机屏幕,你就会看到会刷新出类型下面的内容:

130|shell@hermes:/ $ getevent /dev/input/event3
0003 0039 00000b25
0003 003a 00000052
0003 0030 00000003
0003 0035 00000385
0003 0036 00000437
0001 014a 00000001
0000 0000 00000000
0003 003a 00000051
0000 0000 00000000
0003 0039 ffffffff
0001 014a 00000000
0000 0000 00000000

是不是看着有点晕,下面我们更改一下命令:

130|shell@hermes:/ $ getevent -l /dev/input/event3
EV_ABS      ABS_MT_TRACKING_ID   00000b21
EV_ABS      ABS_MT_PRESSURE      0000007f
EV_ABS      ABS_MT_TOUCH_MAJOR   00000006
EV_ABS      ABS_MT_POSITION_X    0000038f   // x坐标
EV_ABS      ABS_MT_POSITION_Y    00000421   // y坐标
EV_KEY      BTN_TOUCH            DOWN       // MotionEvent.ACTION_DOWN事件触发
EV_SYN      SYN_REPORT           00000000   //同步事件
EV_ABS      ABS_MT_PRESSURE      0000007e
EV_SYN      SYN_REPORT           00000000   //同步事件
EV_ABS      ABS_MT_TRACKING_ID   ffffffff
EV_KEY      BTN_TOUCH            UP         // MotionEvent.ACTION_UP事件触发
EV_SYN      SYN_REPORT           00000000   //同步事件

这次好看多了吧!

接着我们来说说上面的一些关键字是什么意思:

EV_SYN[0000] :同步事件
EV_KEY[0001] :按键事件
EV_ABS[0003] :绝对值事件
ABS_MT_TOUCH_MAJOR[0030] :接触面长轴值  {有效值范围[0, 255]}
ABS_MT_POSITION_X[0035]: (x轴坐标) {有效值范围[0, 1080]} (MAX根据屏幕长宽决定,在getevent -p 里能看到)
ABS_MT_POSITION_Y [0036]: (y轴坐标) {有效值范围[0, 1920]}

有了上面的了解,我们是否也可以通过adb进行屏幕的一些操作呢?答案是肯定的。

四、通过adb模拟滑动、按键、点击事件:

在进入adb模式下输入input,则可以看到以下命令的说明:

The commands and default sources are:
      text<string> (Default: touchscreen)
      keyevent[--longpress] <key code number or name> ... (Default: keyboard)
      tap <x><y> (Default: touchscreen)
      swipe<x1> <y1> <x2> <y2> [duration(ms)] (Default:touchscreen)
      press(Default: trackball)
      roll<dx> <dy> (Default: trackball)

1、 text 在手机的搜索输入框中输入关键字进行搜索,如:需要搜索aaa相关的所有内容:

    adb shell input text aaa

2、keyevent 手机的按键操作,如:home键、返回键、菜单键、锁屏等。

    例如你需要点击一下home键,那么你可以这么输入:

    adb shell input keyevent 3  或者 adb shell input keyevent KEYCODE_HOME

3、tap 是模拟touch屏幕的事件,以下命令就是点击屏幕300,300位置:

    adb shell input tap 300 300

4、swipe 是滑动事件,以下命令表示从屏幕300,300 移动到400,400

    adb shell input swipe 300 300 400 400

5、press 按下滚球(现在已经没用了,因为现在手机都没有那个滚球了)

    adb shell input trackball press

6、roll 移动滚球(现在也已经没用了)

    adb shell input trackball roll <dx><dy>

本文作者:蔡大侠

原文链接:技能进阶:Android 屏幕操作原理,转载请注明来源!

8