I've been searching for a View/Component in Android Studio that I could use for creating a touchpad. I need the ability to track mouse movements, so that I use that information on the server side to handle it and emulate mouse movements.
What would be the best fit for that purpose?
Unfortunately, Shishdem's answer didn't satisfy me. What I basically was trying to achieve is to make a prototype of a touchpad for a school project. ScrollView
contains elements that are to be scrolled within, and I needed to track finger movements information that is suitable to be handled for moving cursor on PC by my server application.
I found solution here: Track touch and pointer movements
I needed to create an android.view.VelocityTracker
and track touch velocity to further send that data to my PC server and simulate mouse movements via java.awt.Robot
within onTouchEvent
. The component could be anything, a Button
in my case.
Here's the working code for the class that handles touch event of a touchpad view:
private VelocityTracker mVelocityTracker = null;
@Override
public boolean onTouchEvent(MotionEvent event) {
int index = event.getActionIndex();
int action = event.getActionMasked();
int pointerId = event.getPointerId(index);
switch(action) {
case MotionEvent.ACTION_DOWN:
if(mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
else {
mVelocityTracker.clear();
}
mVelocityTracker.addMovement(event);
break;
case MotionEvent.ACTION_MOVE:
mVelocityTracker.addMovement(event);
mVelocityTracker.computeCurrentVelocity(1000);
// Log velocity of pixels per second
// Those values can be used to be sent to the server
Log.d("Velocity", "X velocity: " + mVelocityTracker.getXVelocity(pointerId));
Log.d("Velocity", "Y velocity: " + mVelocityTracker.getYVelocity(pointerId));
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mVelocityTracker.recycle();
mVelocityTracker = null;
break;
}
return true;
}
Note that in the example of the link above there isn't this line:
mVelocityTracker.recycle();
mVelocityTracker = null; // this line
But in my case, if I didn't assign mVelocityTracker
to null
every recycle, it would crash with the following errors:
2021-10-05 09:30:21.711 4385-4385/com.example.javaapp E/InputEventReceiver: Exception dispatching input event.
2021-10-05 09:30:21.711 4385-4385/com.example.javaapp E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
2021-10-05 09:30:21.713 4385-4385/com.example.javaapp E/MessageQueue-JNI: java.lang.IllegalStateException: Already in the pool!
at android.util.Pools$SimplePool.release(Pools.java:120)
at android.util.Pools$SynchronizedPool.release(Pools.java:179)
at android.view.VelocityTracker.recycle(VelocityTracker.java:87)
More on that issue: VelocityTracker causes crash on Android 4.4