I am trying to simulate a zoom-in gesture using InputManager with Kotlin. But I could not find a way to perform it. I must use InputManager, because I will use it on a rooted device to control other apps.
I could only make a single-finger drag, and the code is as follows. However, I want to make a zoom-in gesture which requires two figures touching down at the same time. Event the AI could not help. Please accept my sincere gratitude if anyone can help me.
fun simulateSingleSwipe(
startX: Int, startY: Int, endX: Int, endY: Int, duration: Long
) {
try {
// get InputManager
val inputManagerClass = Class.forName("android.hardware.input.InputManager")
val getInstanceMethod: Method = inputManagerClass.getMethod("getInstance")
val inputManager = getInstanceMethod.invoke(null)
val injectInputEventMethod: Method = inputManagerClass.getMethod(
"injectInputEvent", InputEvent::class.java, Int::class.javaPrimitiveType
)
val downTime = SystemClock.uptimeMillis()
var eventTime = downTime
// touch down
var downEvent = MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_DOWN,
startX.toFloat(),
startY.toFloat(),
0
)
injectInputEventMethod.invoke(inputManager, downEvent, 0)
sleep(1000)
// touch move
val steps = 100
val stepDuration = duration / steps
val stepX = (endX - startX) / steps.toFloat()
val stepY = (endY - startY) / steps.toFloat()
for (i in 1 until steps) {
eventTime += stepDuration
val moveX = startX + stepX * i
val moveY = startY + stepY * i
// create movement
val moveEvent = MotionEvent.obtain(
downTime, eventTime, MotionEvent.ACTION_MOVE, moveX, moveY, 0
)
injectInputEventMethod.invoke(inputManager, moveEvent, 0)
moveEvent.recycle()
sleep(stepDuration)
}
// touch up
val upEvent = MotionEvent.obtain(
downTime, eventTime, MotionEvent.ACTION_UP, endX.toFloat(), endY.toFloat(), 0
)
injectInputEventMethod.invoke(inputManager, upEvent, 0)
// release
downEvent.recycle()
upEvent.recycle()
} catch (e: Exception) {
e.printStackTrace()
}
}
I am trying to simulate a zoom-in gesture using InputManager with Kotlin. But I could not find a way to perform it. I must use InputManager, because I will use it on a rooted device to control other apps.
I could only make a single-finger drag, and the code is as follows. However, I want to make a zoom-in gesture which requires two figures touching down at the same time. Event the AI could not help. Please accept my sincere gratitude if anyone can help me.
fun simulateSingleSwipe(
startX: Int, startY: Int, endX: Int, endY: Int, duration: Long
) {
try {
// get InputManager
val inputManagerClass = Class.forName("android.hardware.input.InputManager")
val getInstanceMethod: Method = inputManagerClass.getMethod("getInstance")
val inputManager = getInstanceMethod.invoke(null)
val injectInputEventMethod: Method = inputManagerClass.getMethod(
"injectInputEvent", InputEvent::class.java, Int::class.javaPrimitiveType
)
val downTime = SystemClock.uptimeMillis()
var eventTime = downTime
// touch down
var downEvent = MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_DOWN,
startX.toFloat(),
startY.toFloat(),
0
)
injectInputEventMethod.invoke(inputManager, downEvent, 0)
sleep(1000)
// touch move
val steps = 100
val stepDuration = duration / steps
val stepX = (endX - startX) / steps.toFloat()
val stepY = (endY - startY) / steps.toFloat()
for (i in 1 until steps) {
eventTime += stepDuration
val moveX = startX + stepX * i
val moveY = startY + stepY * i
// create movement
val moveEvent = MotionEvent.obtain(
downTime, eventTime, MotionEvent.ACTION_MOVE, moveX, moveY, 0
)
injectInputEventMethod.invoke(inputManager, moveEvent, 0)
moveEvent.recycle()
sleep(stepDuration)
}
// touch up
val upEvent = MotionEvent.obtain(
downTime, eventTime, MotionEvent.ACTION_UP, endX.toFloat(), endY.toFloat(), 0
)
injectInputEventMethod.invoke(inputManager, upEvent, 0)
// release
downEvent.recycle()
upEvent.recycle()
} catch (e: Exception) {
e.printStackTrace()
}
}
Share
Improve this question
asked Mar 17 at 11:11
DavidDavid
31 bronze badge
1 Answer
Reset to default 0ACTION_POINTER_DOWN is used to signify that a secondary pointer is in the down state. Add an ACTION_POINTER_DOWN event for the second finger. The first finger will be the ACTION_DOWN event. I noticed that you are a new user.
Found here: https://developer.android/reference/android/view/MotionEvent#ACTION_POINTER_DOWN
Sample code to add:
var secondaryDownEvent = MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_POINTER_DOWN,
startX.toFloat(),
startY.toFloat(),
0
)
injectInputEventMethod.invoke(inputManager, downEvent, 0)