Android 跨进程点击方法小结

写一些测试工具经常用到点击。本文总结了一些跨进程点击的几种方法。
由于要跨进程注入,所以本文讲的方法都是需要root权限的

1、使用adb命令input tap.

该命令用法很简单,后面直接接x、y坐标即可

input tap 100 100 //点击坐标(100,100)

2、使用sendevent命令

sendevent命令用起来稍微复杂一点,这个命令是用来给设备发送事件的,要使用这个命令,首先需要了解另一个命令getevent,下面是我用nexus 4执行getevent得到的结果。这里我加了-l参数,加上这个参数在触摸屏幕时我们就可以看到

1|shell@mako:/ $ getevent -l
add device 1: /dev/input/event0
  name:     "pmic8xxx_pwrkey"
add device 2: /dev/input/event1
  name:     "keypad_8064"
add device 3: /dev/input/event4
  name:     "apq8064-tabla-snd-card Headset Jack"
add device 4: /dev/input/event3
  name:     "apq8064-tabla-snd-card Button Jack"
add device 5: /dev/input/event5
  name:     "hs_detect"
add device 6: /dev/input/event2
  name:     "touch_dev"

由于我们需要的是点击,可以看到device 6的name时touch_dev,看样子就是触摸屏的设备了。为了确认猜测,我们可以点击一下屏幕。看到如下输出:

/dev/input/event2: EV_ABS       ABS_MT_TRACKING_ID   000004e0            
/dev/input/event2: EV_ABS       ABS_MT_POSITION_X    000003d2            
/dev/input/event2: EV_ABS       ABS_MT_POSITION_Y    0000042c            
/dev/input/event2: EV_ABS       ABS_MT_PRESSURE      0000002e            
/dev/input/event2: EV_ABS       ABS_MT_TOUCH_MAJOR   00000003            
/dev/input/event2: EV_SYN       SYN_REPORT           00000000            
/dev/input/event2: EV_ABS       ABS_MT_TRACKING_ID   ffffffff            
/dev/input/event2: EV_SYN       SYN_REPORT           00000000            

这里我们看EV_ABS,ABS_MT_TRACKING_ID就是前面-l参数的功劳了。这些参数大概的意思是(纯猜测,没找到文档):ABS_MT_TRACKING_ID //是用来追踪一次点击的标识,每次点击累加,与最后的ABS_MT_TRACKING_ID和SYN_REPORT 形成一个完整的点击事件。第二个参数就是点击的x坐标,第三个是y坐标,第四个参数是压力值。第五个参数没搞懂,死六个是同步标识,第七个是结束标识,第八个是同步标识。
综上,我们要使用sendevent完成一次点击事件,至少要完成以上的一串输入。那么我们还要知道哪些标识具体的值,这时再次执行getevent不加-l参数。点击屏幕,看到如下的输出

/dev/input/event2: 0003 0039 000004eb
/dev/input/event2: 0003 0035 0000043d
/dev/input/event2: 0003 0036 000004bf
/dev/input/event2: 0003 003a 0000002e
/dev/input/event2: 0003 0030 00000003
/dev/input/event2: 0000 0000 00000000
/dev/input/event2: 0003 0039 ffffffff
/dev/input/event2: 0000 0000 00000000

得到这些值后,我们就可以组织我们的点击事件了,注意这里输出的都是16进制的,使用命令时要使用十进制的数字。这种方法不同的手机都不同,下面给出我适配过得一些设备:

HM NOTE 1LTEW
sendevent /dev/input/event2 3 57 710
sendevent /dev/input/event2 3 53 x
sendevent /dev/input/event2 3 54 y
sendevent /dev/input/event2 0 0 0
sendevent /dev/input/event2 3 57 4294967295
sendevent /dev/input/event2 0 0 0

HM NOTE 1LTE
sendevent /dev/input/event2 3 57 710
sendevent /dev/input/event2 3 53 x
sendevent /dev/input/event2 3 54 y
sendevent /dev/input/event2 0 0 0
sendevent /dev/input/event2 3 57 4294967295
sendevent /dev/input/event2 0 0 0

GT-I9500
sendevent /dev/input/event1 3 57 89
sendevent /dev/input/event1 1 330 1
sendevent /dev/input/event1 3 53 x
sendevent /dev/input/event1 3 54 y
sendevent /dev/input/event1 0 0 0
sendevent /dev/input/event1 3 57 4294967295
sendevent /dev/input/event1 0 0 0

MI 4LTE-CMCC
sendevent /dev/input/event2 3 57 79
sendevent /dev/input/event2 3 53 x 
sendevent /dev/input/event2 3 54 y
sendevent /dev/input/event2 3 58 60
sendevent /dev/input/event2 3 48 3
sendevent /dev/input/event2 1 330 1
sendevent /dev/input/event2 0 0 0
sendevent /dev/input/event2 3 58 71
sendevent /dev/input/event2 3 48 7
sendevent /dev/input/event2 0 0 0
sendevent /dev/input/event2 3 57 4294967295
sendevent /dev/input/event2 1 330 0
sendevent /dev/input/event2 0 0 0

MI 4W
sendevent /dev/input/event2 3 57 79
sendevent /dev/input/event2 3 53 x 
sendevent /dev/input/event2 3 54 y
sendevent /dev/input/event2 3 58 60
sendevent /dev/input/event2 3 48 3
sendevent /dev/input/event2 1 330 1
sendevent /dev/input/event2 0 0 0
sendevent /dev/input/event2 3 58 71
sendevent /dev/input/event2 3 48 7
sendevent /dev/input/event2 0 0 0
sendevent /dev/input/event2 3 57 4294967295
sendevent /dev/input/event2 1 330 0
sendevent /dev/input/event2 0 0 0

Coolpad 9080W
sendevent /dev/input/event3 3 57 0
sendevent /dev/input/event3 1 330 1
sendevent /dev/input/event3 3 53 x
sendevent /dev/input/event3 3 54 y
sendevent /dev/input/event3 0 2 0
sendevent /dev/input/event3 0 0 0
sendevent /dev/input/event3 1 330 0
sendevent /dev/input/event3 0 2 0
sendevent /dev/input/event3 0 0 0

HUAWEI MT7-TL00
sendevent /dev/input/event5 3 58 47
sendevent /dev/input/event5 3 53 x
sendevent /dev/input/event5 3 54 y
sendevent /dev/input/event5 3 57 0
sendevent /dev/input/event5 0 2 0
sendevent /dev/input/event5 1 330 1
sendevent /dev/input/event5 0 0 0
sendevent /dev/input/event5 0 2 0
sendevent /dev/input/event5 1 330 0
sendevent /dev/input/event5 0 0 0

Nexus 6
sendevent /dev/input/event0 3 57 10
sendevent /dev/input/event0 3 53 x
sendevent /dev/input/event0 3 54 y
sendevent /dev/input/event0 3 58 53
sendevent /dev/input/event0 3 48 6
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 3 58 29
sendevent /dev/input/event0 3 48 2
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 3 57 4294967295
sendevent /dev/input/event0 0 0 0

XT1085
sendevent /dev/input/event1 3 57 120
sendevent /dev/input/event1 3 53 x
sendevent /dev/input/event1 3 54 y
sendevent /dev/input/event1 3 58 50
sendevent /dev/input/event1 3 48 6
sendevent /dev/input/event1 0 0 0
sendevent /dev/input/event1 3 57 4294967295
sendevent /dev/input/event1 0 0 0

NX601J
sendevent /dev/input/event0 3 57 80
sendevent /dev/input/event0 3 53 x
sendevent /dev/input/event0 3 54 y
sendevent /dev/input/event0 3 58 74
sendevent /dev/input/event0 3 48 8
sendevent /dev/input/event0 3 49 8
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 3 53 x
sendevent /dev/input/event0 3 54 y
sendevent /dev/input/event0 3 58 74
sendevent /dev/input/event0 3 48 6
sendevent /dev/input/event0 3 49 6
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 3 57 4294967295
sendevent /dev/input/event0 0 0 0

3 、使用jni写事件

方法2中我们使用了sendevent命令进行点击。翻看安卓的sendevent源码我们可以看到,其实现就是对event文件进行写入操作。那么我们也可以做同样的事情。具体的jni代码实现如下。在实现中,为了实现快速的点击,我只是第一次写事件时进行文件的打开操作,之后都用同一个文件句柄进行写入。用完了之后再通过jni接口释放掉该句柄。

#include <jni.h>
#include <fcntl.h>
#include <linux/input.h>
#include <stdlib.h>

extern "C" {
    JNIEXPORT int JNICALL Java_sogou_test_kpi_base_AndroidToCPP_sendevent(JNIEnv * env, jobject obj,int argc, jobjectArray strArray,int fd);
    JNIEXPORT int JNICALL Java_sogou_test_kpi_base_AndroidToCPP_closefilehandler(JNIEnv * env, jobject obj,int fd);
}
//static public int fd = 0;
JNIEXPORT int JNICALL Java_sogou_test_kpi_base_AndroidToCPP_sendevent(JNIEnv * env,jobject obj,int argc, jobjectArray strArray,int fd)
{
    jstring jstr;
    jsize len = argc;
    char **argv = (char **) malloc(len*sizeof(char *));

    jsize i=0;

    for (i=0 ; i<len; i++) {
        jstr = (jstring)env->GetObjectArrayElement(strArray, i);
        argv[i] = (char *)env->GetStringUTFChars(jstr, 0);

    }
    argc = len;
//      int fd;
        ssize_t ret;
        int version;
        struct input_event event;

        if(argc != 5) {
//          close(fd);//fprintf(stderr, "use: %s device type code value\n", argv[0]);
            return 1;
        }

        if(fd == 0) {
            fd = open(argv[1], O_RDWR);
        }
        if(fd < 0) {
            close(fd);//fprintf(stderr, "could not open %s, %s\n", argv[optind], strerror(errno));
            return -2;
        }
        if (ioctl(fd, EVIOCGVERSION, &version)) {
//          close(fd);//fprintf(stderr, "could not get driver version for %s, %s\n", argv[optind], strerror(errno));
            return -3;
        }
        memset(&event, 0, sizeof(event));
        event.type = atoi(argv[2]);
        event.code = atoi(argv[3]);
        event.value = atoi(argv[4]);
        ret = write(fd, &event, sizeof(event));
        if(ret < (ssize_t) sizeof(event)) {
//          close(fd);
            //fprintf(stderr, "write event failed, %s\n", strerror(errno));
            return -1;
        }
//      close(fd);

    return fd;
}


JNIEXPORT int JNICALL Java_sogou_test_kpi_base_AndroidToCPP_closefilehandler(JNIEnv * env,jobject obj,int fd)
{
//  fd
    if(fd>0)
        close(fd);

    return 0;
}

参考:
https://github.com/android/platform_system_core/blob/master/toolbox/sendevent.c

4、使用monkey进行点击

通常我们用monkey都是用来做压力测试,而monkey是在pc上执行的shell命令。所以monkey执行的点击必然也是通过把点击事件传给系统内某个进程实现的。这个进程就是

com.android.commands.monkey

首先我们需要启动这个进行,在shell下可以通过如下命令启动

monkey --port 3131

要与这个进程进行通信需要用到socket,只需要通过回路ip 127.0.0.1与端口3131就能与monkey进程建立通信。之后就可以发送点击命令,monkey里的点击分为down和up两部分。发送

touch down x y
touch up x y

完成一次点击操作。也可以发送系统keycode,可以从
http://developer.android.com/reference/android/view/KeyEvent.html#FLAG_FALLBACK
找到具体的值。

以上总结了用于安卓点击的四种方法,如果要在android直接执行都需要root权限,方法四也可以在pc上把monkey服务启动,安卓上就不需要root了。

当然还可以用谷歌提供给的自动化方法Instrumentation和UiAutomator实现点击。不过Instrument只能在被测进程点击。且这两个主要用于自动化测试。如果要集成到测试工具里做些简单的随机的点击不是很方便,需要提前编写脚本。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容