MotionEvent.obtain(…); not working as on screen ta

2019-07-20 23:40发布

This is a continuation of my first topic here, about how to use code to mimic an on screen touch.

I wanted to incorporate this function to a floating, onscreen, chat-head (like what facebook did). So basically, when I tap the chat-head this service will mimic taps a certain amounts of times and at a certain rates. (Which are predefined somewhere else.) It will also mimic the tap at a certain spot x, y. (which are also predefined.) I want the service to tap whatever is behind (on the screen).

Here is my full code but it doesn't work and it doesn't show any errors. It is a bit long and lengthy, if you don't have much time, then just skip to the runnable section. I am pretty confident there isn't any errors before the runnable section.

public class TapService extends Service{

    private WindowManager windowManager;
    private ImageView chatHead;

    boolean mHasDoubleClicked = false;
    long lastPressTime;
    private Boolean _enable = true;

    int x = 0;
    int y = 0;

    int tapTimes;
    long delayInterval;

    @Override
    public IBinder onBind(Intent intent) {
        // Not Used
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        //////////////Chathead Core Section
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        chatHead = new ImageView(this);
        chatHead.setImageResource(R.drawable.floating2);

        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.TOP | Gravity.LEFT;
        params.x = 0;
        params.y = 100;

        windowManager.addView(chatHead, params);
        //////////Chathead Core Section

        getTapInformation();

        try {
            chatHead.setOnTouchListener(new View.OnTouchListener() {
                private WindowManager.LayoutParams paramsF = params;
                private int initialX;
                private int initialY;
                private float initialTouchX;
                private float initialTouchY;

                @Override public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:

                            // Get current time in nano seconds.
                            long pressTime = System.currentTimeMillis();


                            // If double click...
                            if (pressTime - lastPressTime <= 300) {


                                // Do something else here
                                mHasDoubleClicked = true;
                            }
                            else {     // If not double click....
                                mHasDoubleClicked = false;
                            }
                            lastPressTime = pressTime;
                            initialX = paramsF.x;
                            initialY = paramsF.y;
                            initialTouchX = event.getRawX();
                            initialTouchY = event.getRawY();
                            x = paramsF.x;
                            y = paramsF.y;
                            break;
                        case MotionEvent.ACTION_UP:
                            break;
                        case MotionEvent.ACTION_MOVE:
                            paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
                            paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
                            x = paramsF.x;
                            y = paramsF.y;
                            windowManager.updateViewLayout(chatHead, paramsF);
                            break;
                    }
                    return false;
                }
            });
        } catch (Exception e) {
            // TODO: handle exception
        }

        chatHead.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                _enable = false;
                handler.post(runnable);
                //              Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                //              intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                //              getApplicationContext().startActivity(intent);
            }
        });
    }

    private Handler handler = new Handler();

    private final Runnable runnable = new Runnable() {
        @Override
        public void run() {
            long downTime;
            long eventTime;

            Log.v("Screen Tapper", "Start Tapping");

            for(int i = 0; i <tapTimes; i++) {
                downTime = eventTime = SystemClock.uptimeMillis();
                MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);
                chatHead.onTouchEvent(event);
                Log.v("Screen Tapper", "touchDown ----- "+x+","+y);

                handler.postDelayed(runnable, 10);

                downTime = eventTime = SystemClock.uptimeMillis();
                MotionEvent event2 = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
                chatHead.onTouchEvent(event2);
                Log.v("Screen Tapper", "touchUp ----- "+x+","+y);

                handler.postDelayed(runnable, delayInterval);
            }
        }
    };

    private void getTapInformation() {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        tapTimes = prefs.getInt("TAP_TIMES", 1);
        delayInterval = prefs.getLong("Rate", 1);
        Log.v("Screen Tapper", "Get Information");
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (chatHead != null) windowManager.removeView(chatHead);
    }

}

I don't see anything wrong with my code but I have a feeling that the chatHead.onTouchEvent(...); is not correct

Any help is appreciated. Thanks in advance

1条回答
趁早两清
2楼-- · 2019-07-20 23:43

I beleive you need to run touch events on the UI thread for them to work, try this out

view.post(new Runnable() {
   @Override
   public void run() {
      onTouchEvent(event);
   }
});
查看更多
登录 后发表回答