去看一下monkey的代码吧,在development/cmds/monkey/src/com/android/commands/monkey.里面是通过inputmanager来搞的。不知道是否是你想要的东西,权当抛砖引玉吧

解决方案 »

  1.   

    用sendevent命令就好,如果有耐心,也可以把它写成JNI的
      

  2.   


    sendevent命令要怎么用?还有在哪可以找到它的源码.
      

  3.   

    sendevent /dev/input/eventX X X X
    http://blog.csdn.net/watson243671/article/details/6647334
      

  4.   


    出现新问题了.
    我现在有的是开发板,屏是800*480的
    但是我用getevent,并触摸屏的左上角到的的数据如下:
    /dev/input/event1: 0003 0000 0000005b
    /dev/input/event1: 0003 0001 000000f1
    /dev/input/event1: 0001 014a 00000001
    /dev/input/event1: 0000 0000 00000000
    /dev/input/event1: 0003 0000 0000005f
    /dev/input/event1: 0000 0000 00000000
    /dev/input/event1: 0003 0000 00000061
    /dev/input/event1: 0000 0000 00000000
    /dev/input/event1: 0003 0000 00000066
    /dev/input/event1: 0000 0000 00000000
    /dev/input/event1: 0003 0000 000002e9
    /dev/input/event1: 0003 0001 0000391f
    /dev/input/event1: 0001 014a 00000000
    /dev/input/event1: 0000 0000 00000000而触摸屏的右下角得到的数据是:
    /dev/input/event1: 0003 0000 00000f18
    /dev/input/event1: 0003 0001 00000e89
    /dev/input/event1: 0001 014a 00000001
    /dev/input/event1: 0000 0000 00000000
    /dev/input/event1: 0003 0000 00003c5c
    /dev/input/event1: 0003 0001 00000460
    /dev/input/event1: 0001 014a 00000000
    /dev/input/event1: 0000 0000 00000000这个数据得到的左上角坐标不在(0, 0)附近,右下角的坐标竟然达到了(3864, 3721).这个数远远超出了(800, 480)了啊.
    我又在模拟器上试了下,也是800*480的屏,结果却是在(0, 0)到(800, 480)之间.这是怎么回事啊?
      

  5.   


    我找到方法了.
    ioctl("/dev/input/event1", EVIOCGABS(ABS_X), &info);
    ioctl("/dev/input/event1", EVIOCGABS(ABS_Y), &info);
    可以获得这个范围.
    EVIOCGABS, ABS_X, ABS_Y和input_absinfo结构体都在<linux/input.h>下定义的.
      

  6.   


    牛!另外关于模拟器的sendevent 坐标数据正常,但是设备却不是的问题,看一下 :http://blog.csdn.net/yiyaaixuexi/article/details/6574001
      

  7.   


    还有一个小问题
    就像你说的:"qtouch-touchscreen"不是规定死的event几,话说1234567都有可能,看你设备了。
    我要确定哪个是触摸,哪个是按键才可以正常的操作.我现在还不知道怎么去确定呢.或许去看一下getevent代码能有所收获.
      

  8.   


    我这个用的是JNI的.而要ROOT权限.#include <stdlib.h>
    #include <android/log.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <linux/input.h>
    #include <dirent.h>
    #include <errno.h>
    //#include "nativemethod.h"#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, "EventEmulate", __VA_ARGS__)
    #define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, "EventEmulate", __VA_ARGS__)#define DEV_DIR "/dev/input"
    #define sizeof_bit_array(bits)  ((bits + 7) / 8)
    #define test_bit(bit, array)    (array[bit/8] & (1<<(bit%8)))
    #define ABS_MT_POSITION_X 0x35
    #define ABS_MT_POSITION_Y 0x36struct EVENT_INFO
    {
    int fd_touch;
    int fd_key;
    int screen_width;
    int screen_height;
    int abs_x_min;
    int abs_x_max;
    int abs_y_min;
    int abs_y_max;
    };int scan_dir(const char *dirname);
    int open_dev(const char *deviceName);
    int write_event(int fd, int type, int code, int value);
    void calculateXY(float x, float y, int *abs_x, int *abs_y);
    int containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex);struct EVENT_INFO ei;
    int initEVT = 0;int EVT_open(struct NATIVE_INFO *info)
    {
    struct input_absinfo absinfo; if(initEVT)
    return 0; if(info == NULL)
    {
    LOGE("info null point.");
    goto fail;
    } if(info->FB_width == 0 || info->FB_height == 0)
    {
    LOGE("error width %d and height %d.", info->FB_width, info->FB_height);
    goto fail;
    } memset(&ei, 0, sizeof(ei));
    ei.screen_width = info->FB_width;
    ei.screen_height = info->FB_height; scan_dir(DEV_DIR); if(ioctl(ei.fd_touch, EVIOCGABS(ABS_X), &absinfo)) {
    LOGI("Error reading absolute controller ABS_X[%d]: %s", errno, strerror(errno));
    return;
    }
    ei.abs_x_min = absinfo.minimum;
    ei.abs_x_max = absinfo.maximum; if(ioctl(ei.fd_touch, EVIOCGABS(ABS_Y), &absinfo)) {
    LOGI("Error reading absolute controller ABS_Y[%d]: %s", errno, strerror(errno));
    return;
    }
    ei.abs_y_min = absinfo.minimum;
    ei.abs_y_max = absinfo.maximum; initEVT = 1;
    return 0;fail:
    EVT_close();
    return -1;
    }int EVT_close()
    {
    if(ei.fd_key > 0)
    close(ei.fd_key);
    if(ei.fd_touch > 0)
    close(ei.fd_touch); initEVT = 0;
    return 0;
    }int EVT_touch(int action, float x, float y)
    {
    int abs_x, abs_y; if(initEVT == 0)
    {
    LOGE("event not inital");
    return -1;
    } switch(action)
    {
    case ACTION_DOWN:
    calculateXY(x, y, &abs_x, &abs_y);
    write_event(ei.fd_touch, 3, 0, abs_x);
    write_event(ei.fd_touch, 3, 1, abs_y);
    write_event(ei.fd_touch, 1, 330, 1);
    write_event(ei.fd_touch, 0, 0, 0);
    break;
    case ACTION_UP:
    write_event(ei.fd_touch, 1, 330, 0);
    write_event(ei.fd_touch, 0, 0, 0);
    break;
    case ACTION_MOVE:
    calculateXY(x, y, &abs_x, &abs_y);
    write_event(ei.fd_touch, 3, 0, abs_x);
    write_event(ei.fd_touch, 3, 1, abs_y);
    write_event(ei.fd_touch, 0, 0, 0);
    break;
    }
    return 0;
    }int EVT_key(int action, int key)
    {
    if(initEVT == 0)
    {
    LOGE("event not inital");
    return -1;
    } switch(action)
    {
    case ACTION_DOWN:
    write_event(ei.fd_key, 1, key, 1);
    break;
    case ACTION_UP:
    write_event(ei.fd_key, 1, key, 0);
    break;
    }
    return 0;
    }
    int scan_dir(const char *dirname)
    {
    char devname[PATH_MAX];
    char *filename;
    DIR *dir;
    struct dirent *de;
    dir = opendir(dirname);
    if(dir == NULL)
    return -1;
    strcpy(devname, dirname);
    filename = devname + strlen(devname);
    *filename++ = '/';
    while((de = readdir(dir))) {
    if(de->d_name[0] == '.' &&
       (de->d_name[1] == '\0' ||
    (de->d_name[1] == '.' && de->d_name[2] == '\0')))
    continue;
    strcpy(filename, de->d_name);
    open_dev(devname);
    }
    closedir(dir);
    return 0;
    }int open_dev(const char *deviceName)
    {
    int fd;
    int version;
    uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
    uint8_t abs_bitmask[sizeof_bit_array(ABS_MAX + 1)]; fd = open(deviceName, O_RDWR);
    if(fd < 0) {
    LOGI("could not open device[%d]: %s", errno, strerror(errno));
    return -1;
    } if(ioctl(fd, EVIOCGVERSION, &version)) {
    return -1;
    } memset(key_bitmask, 0, sizeof(key_bitmask));
    if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
    if (containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC))
    || containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_GAMEPAD),
    sizeof_bit_array(BTN_DIGI))
    || containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK),
    sizeof_bit_array(KEY_MAX + 1))) {
    ei.fd_key = fd;
    LOGI("get key input device: %s", deviceName);
    }
    } memset(abs_bitmask, 0, sizeof(abs_bitmask));
    if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0) {
    // Is this a new modern multi-touch driver?
    if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
    && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
    ei.fd_touch = fd;
    LOGI("get multi-touch input device: %s", deviceName); // Is this an old style single-touch driver?
    } else if (test_bit(BTN_TOUCH, key_bitmask)
    && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
    ei.fd_touch = fd;
    LOGI("get single-touch input device: %s", deviceName);
    }
    }
    }int write_event(int fd, int type, int code, int value)
    {
    struct input_event event; memset(&event, 0, sizeof(event));
    event.type = type;
    event.code = code;
    event.value = value;
    if(write(fd, &event, sizeof(event)) < sizeof(event)) {
    LOGI("write event failed[%d]: %s", errno, strerror(errno));
    return -1;
    }
    return 0;
    }void calculateXY(float x, float y, int *abs_x, int *abs_y)
    {
    *abs_x = ei.abs_x_min +
    (int)((x * (float)(ei.abs_x_max - ei.abs_x_min)) / ei.screen_width + 0.5);
    *abs_y = ei.abs_y_min +
    (int)((y * (float)(ei.abs_y_max - ei.abs_y_min)) / ei.screen_height + 0.5);
    }int containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex)
    {
        const uint8_t* end = array + endIndex;
        array += startIndex;
        while (array != end) {
            if (*(array++) != 0) {
                return 1;
            }
        }
        return 0;
    }其中struct NATIVE_INFO结构体是我自己定义的.里面包含了屏幕的宽和高.
      

  9.   


    这个只是给你们作为参考的.
    头文件中只有nativemethod.h是我自己写的之外,其它的应该都是有的.
      

  10.   

    楼主,能不能给下NATIVE_INFO的定义?
      

  11.   

    我参考尝试了一下,发现不同的设备上ACTION_DOWN ACTION_UP ACTION_MOVE需要发送的命令格式不同
    想问下 这个地方怎么加判断能写一个通用的希望有时间的话指点一下下面是我针对两个不同设备写的函数 ,不知道是否可以加些判断写成一个。三星的如下
        case AMOTION_EVENT_ACTION_DOWN:
            calculateXY(x, y, &abs_x, &abs_y);
            write_event(ei.fd_touch, 3, 57, 0);
            write_event(ei.fd_touch, 3, 53, abs_x);
            write_event(ei.fd_touch, 3, 54, abs_y);
            write_event(ei.fd_touch, 3, 48, 20);
            write_event(ei.fd_touch, 0, 0, 0);
            break;
        case AMOTION_EVENT_ACTION_UP:
            write_event(ei.fd_touch, 3, 57, -1);
            write_event(ei.fd_touch, 0, 0, 0);
            break;
        case AMOTION_EVENT_ACTION_MOVE:
            calculateXY(x, y, &abs_x, &abs_y);
            write_event(ei.fd_touch, 3, 53, abs_x);
            write_event(ei.fd_touch, 3, 54, abs_y);
            write_event(ei.fd_touch, 3, 48, 20);
            write_event(ei.fd_touch, 0, 0, 0);
            break;
        
    另外一个设备
        case AMOTION_EVENT_ACTION_DOWN:
            calculateXY(x, y, &abs_x, &abs_y);
            write_event(ei.fd_touch, 3, 53, abs_x);
            write_event(ei.fd_touch, 3, 54, abs_y);
            write_event(ei.fd_touch, 3, 48, 1);
            write_event(ei.fd_touch, 0, 2, 0);
            write_event(ei.fd_touch, 0, 0, 0);
            break;
        case AMOTION_EVENT_ACTION_UP:
            write_event(ei.fd_touch, 0, 2, 0);
            write_event(ei.fd_touch, 0, 0, 0);
            break;
        case AMOTION_EVENT_ACTION_MOVE:
            calculateXY(x, y, &abs_x, &abs_y);
            write_event(ei.fd_touch, 3, 53, abs_x);
            write_event(ei.fd_touch, 3, 54, abs_y);
            write_event(ei.fd_touch, 3, 48, 1);
            write_event(ei.fd_touch, 0, 2, 0);
            write_event(ei.fd_touch, 0, 0, 0);
            break;
      

  12.   

    楼主 你好, 能打包一个demo吗? 不胜感激。苦恼这个问题一个月了
      

  13.   

    你这样子模拟 点击以后可以弹起吗,
    我的手机 这样子写
    int touch(int device,int type,int x,int y)
    {
    switch(type)
    {
    case ACTION_DOWN:
    write_event(device, EV_ABS, ABS_MT_TRACKING_ID,0);
    write_event(device, EV_ABS, ABS_MT_POSITION_X, x);
    write_event(device, EV_ABS, ABS_MT_POSITION_Y, y);
    write_event(device, EV_ABS, ABS_MT_PRESSURE,0x50);
    break;
    case ACTION_UP:
    write_event(device, EV_ABS, ABS_MT_TRACKING_ID, 0xffffff);
    //write_event(device, EV_SYN, SYN_MT_REPORT, 0);
    //write_event(device, EV_SYN, SYN_REPORT, 0);
    break;
    }
    write_event(device, EV_SYN, SYN_REPORT, 0);//同步} 只是第一次触屏有效,后面第二次需要 手动点击一次屏幕才能正常
      

  14.   

    楼主的方法确认需要root权限吗?
      

  15.   

    楼主这种做法,其实就是向设备写入数据,通过设备向上层应用传送input消息单点触摸方式,这种操作设备的方式 至少需要system权限,没有system权限,则需要root权限改变设备的可读写状态(chmod 777  /dev/input/event* || chmod 777 /dev/uinput)