Search code examples
androidandroid-activitytouch-event

Detect every touch events without overriding dispatchTouchEvent()?


I am developing Android library which needs to track all touch events on app that uses it. For now Users should override theirs Activity’s dispatchTouchEvent() on their’s every activity. as shown below

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    MyLib.dispatchTouchEvent(event);
    return super.dispatchTouchEvent(event);
}

But Appsee detects touch events with Appsee.start(“key”); on onCreate method integrated in First activity where app starts. How is this possible. Any help??


Solution

  • Answering as this may be helpful to others. Answer will be helpful for library that requires to intercept touch events.

    If you dont want to overrride dispatchTouchEvent() (Imp in case you are coding for library) method of activity then we can use Window.Callback class. Create your own implementation of Window.Callback as code below and then set it as callback to Window object from your activity.

    Do as in below code snippet for Activity context instance you get.

    //set Window.Callback for getting touch event
            final Window win = context.getWindow();
            final Window.Callback localCallback = win.getCallback();
            win.setCallback(new MyWindowCallback(localCallback));
    

    Class MyWindowCallback will be as :

    You will get TouchEvent on dispatchTouchEventMethod() of MyWindowCallback where you can use these as required.

    import android.annotation.SuppressLint;
    import android.util.Log;
    import android.view.ActionMode;
    import android.view.KeyEvent;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.view.accessibility.AccessibilityEvent;
    
    public class MyWindowCallback implements Window.Callback{
    
        Window.Callback localCallback;
    
        public MyWindowCallback(Window.Callback localCallback) {
            this.localCallback = localCallback;
        }
    
        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            return localCallback.dispatchKeyEvent(event);
        }
    
        @SuppressLint("NewApi")
        @Override
        public boolean dispatchKeyShortcutEvent(KeyEvent event) {
            return localCallback.dispatchKeyShortcutEvent(event);
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            //YOU WILL GET TOUCH EVENTS HERE>> USE AS REQUIRED>>
            return localCallback.dispatchTouchEvent(event);
        }
    
        @Override
        public boolean dispatchTrackballEvent(MotionEvent event) {
            return localCallback.dispatchTrackballEvent(event);
        }
    
        @SuppressLint("NewApi")
        @Override
        public boolean dispatchGenericMotionEvent(MotionEvent event) {
            return localCallback.dispatchGenericMotionEvent(event);
        }
    
        @Override
        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
            return localCallback.dispatchPopulateAccessibilityEvent(event);
        }
    
        @Override
        public View onCreatePanelView(int featureId) {
            return localCallback.onCreatePanelView(featureId);
        }
    
        @Override
        public boolean onCreatePanelMenu(int featureId, Menu menu) {
            return localCallback.onCreatePanelMenu(featureId, menu);
        }
    
        @Override
        public boolean onPreparePanel(int featureId, View view, Menu menu) {
            boolean ret = localCallback.onPreparePanel(featureId, view, menu);
            return ret;
        }
    
        @Override
        public boolean onMenuOpened(int featureId, Menu menu) {
            return localCallback.onMenuOpened(featureId, menu);
        }
    
        @Override
        public boolean onMenuItemSelected(int featureId, MenuItem item) {
            return localCallback.onMenuItemSelected(featureId, item);
        }
    
        @Override
        public void onWindowAttributesChanged(WindowManager.LayoutParams attrs) {
            localCallback.onWindowAttributesChanged(attrs);
        }
    
        @Override
        public void onContentChanged() {
            localCallback.onContentChanged();
        }
    
        @Override
        public void onWindowFocusChanged(boolean hasFocus) {
            Log.d("","ttest onfocus changed called");
            localCallback.onWindowFocusChanged(hasFocus);
        }
    
        @Override
        public void onAttachedToWindow() {
            localCallback.onAttachedToWindow();
        }
    
        @Override
        public void onDetachedFromWindow() {
            localCallback.onDetachedFromWindow();
        }
    
        @Override
        public void onPanelClosed(int featureId, Menu menu) {
            localCallback.onPanelClosed(featureId, menu);
        }
    
        @Override
        public boolean onSearchRequested() {
            return localCallback.onSearchRequested();
        }
    
        @SuppressLint("NewApi")
        @Override
        public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
            return localCallback.onWindowStartingActionMode(callback);
        }
    
        @SuppressLint("NewApi")
        @Override
        public void onActionModeStarted(ActionMode mode) {
            localCallback.onActionModeStarted(mode);
    
        }
    
        @SuppressLint("NewApi")
        @Override
        public void onActionModeFinished(ActionMode mode) {
            localCallback.onActionModeFinished(mode);
    
        }
    }