Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simulate a tap at a specific coordinate in an android webview?

I am able to simulate tap events on typical android views (textbox, button, etc.) using MotionEvent.obtain, like this:

 int meta_state = 0;
    MotionEvent motionEvent = MotionEvent.obtain(
            SystemClock.uptimeMillis(),
            SystemClock.uptimeMillis(),
            MotionEvent.ACTION_DOWN,
            x,
            y,
            meta_state
    );
    motionEvent.recycle();

    view_tapped.dispatchTouchEvent(motionEvent);

view_tapped is a reference to the view I want to sent the event to. However, when I call dispatchTouchEvent on a webview, it doesn't seem to tap any element inside.

I've also put an onTouchListener inside the webview, and then dumped all the information related to the motionevent when the view is actually tapped by a finger, and then created a new motionevent with all of the same information and dispatched it to the webview, and it isn't tapping the screen. The onTouchListener is still fired, but the element on the screen isn't tapped.

I also tried doing it with Javascript, by trying to figure out which element was at the specific coordinate and then firing the click event by injecting javascript, but no luck either.

Any ideas as to what I'm doing wrong?

like image 747
seibelj Avatar asked Jan 02 '14 16:01

seibelj


People also ask

How do you simulate a touch event on android?

Valentin Rocher's method works if you've extended your view, but if you're using an event listener, use this: view. setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { Toast toast = Toast. makeText( getApplicationContext(), "View touched", Toast.

What is alternative of WebView in android?

Alternatives to WebView If you want to send users to a mobile site, build a progressive web app (PWA). If you want to display third-party web content, send an intent to installed web browsers. If you want to avoid leaving your app to open the browser, or if you want to customize the browser's UI, use Custom Tabs.


2 Answers

There is my solution:

private void simulateClick(float x, float y) {
    long downTime = SystemClock.uptimeMillis();
    long eventTime = SystemClock.uptimeMillis();
    MotionEvent.PointerProperties[] properties = new MotionEvent.PointerProperties[1];
    MotionEvent.PointerProperties pp1 = new MotionEvent.PointerProperties();
    pp1.id = 0;
    pp1.toolType = MotionEvent.TOOL_TYPE_FINGER;
    properties[0] = pp1;
    MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[1];
    MotionEvent.PointerCoords pc1 = new MotionEvent.PointerCoords();
    pc1.x = x;
    pc1.y = y;
    pc1.pressure = 1;
    pc1.size = 1;
    pointerCoords[0] = pc1;
    MotionEvent motionEvent = MotionEvent.obtain(downTime, eventTime,
            MotionEvent.ACTION_DOWN, 1, properties,
            pointerCoords, 0,  0, 1, 1, 0, 0, 0, 0 );
    dispatchTouchEvent(motionEvent);

    motionEvent = MotionEvent.obtain(downTime, eventTime,
            MotionEvent.ACTION_UP, 1, properties,
            pointerCoords, 0,  0, 1, 1, 0, 0, 0, 0 );
    dispatchTouchEvent(motionEvent);
}
like image 169
Fedir Tsapana Avatar answered Sep 18 '22 13:09

Fedir Tsapana


I think you just need one line of code. The below command is working fine for me.

Runtime.getRuntime().exec("/system/bin/input tap 100 400"); 

That's a much cleaner solution. Unfortunately, it doesn't have events like touch_down, touch_up, or move_to, etc.

like image 38
Elizabeth Harper Avatar answered Sep 18 '22 13:09

Elizabeth Harper