You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Appium 2.5.1版本Android长按操作失效问题求助

问题:Appium 2.5.1远程执行长按操作报错,求替代方案

本地正常运行的代码(Appium 2.0.1)

这段长按代码在本地Appium 2.0.1环境下可正常执行:

WebElement element = assertElement(new AppiumBy.ByAndroidUIAutomator("new UiSelector().resourceId(\"" + resourceId + "\")"));
// 长按待办项逻辑
TouchAction action = new TouchAction(driver);
action.longPress(ElementOption.element(element)).release().perform();

远程Jenkins运行报错(Appium 2.5.1)

在Jenkins远程环境的Appium 2.5.1版本中执行上述代码,出现以下错误:

org.openqa.selenium.UnsupportedCommandException: The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource
Build info: version: '4.9.1', revision: 'eb2032df7f'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '14.0', java.version: '20.0.2'
Driver info: io.appium.java_client.android.AndroidDriver
Command: [34caf98b-9993-44bb-8b5b-06f8db975aec, performTouchAction {actions=[{action=longPress, options={duration=2000, element=00000000-0000-0144-0000-0110000000af}}, {action=release, options={}}]}]
Capabilities {appium:app: /Users/testlaptopmac/Downlo..., appium:appPackage: com.xelion8.android.debug, appium:applicationName: xcover5, appium:autoGrantPermissions: true, appium:automationName: UiAutomator2, appium:databaseEnabled: false, appium:desired: {app: /Users/testlaptopmac/Downlo..., applicationName: xcover5, autoGrantPermissions: true, automationName: UiAutomator2, deviceName: xcover5, platformName: ANDROID, udid: R58T70RWNTZ}, appium:deviceApiLevel: 33, appium:deviceManufacturer: samsung, appium:deviceModel: SM-G525F, appium:deviceName: R58T70RWNTZ, appium:deviceScreenDensity: 340, appium:deviceScreenSize: 720x1480, appium:deviceUDID: R58T70RWNTZ, appium:javascriptEnabled: true, appium:locationContextEnabled: false, appium:networkConnectionEnabled: true, appium:pixelRatio: 2.125, appium:platformVersion: 13, appium:statBarHeight: 51, appium:takesScreenshot: true, appium:udid: R58T70RWNTZ, appium:viewportRect: {height: 1429, left: 0, top: 51, width: 720}, appium:warnings: {}, appium:webStorageEnabled: false, platformName: ANDROID, se:bidiEnabled: false, se:cdpEnabled: false}
Session ID: 34caf98b-9993-44bb-8b5b-06f8db975aec

我的配置

UiAutomator2Options options = new UiAutomator2Options().setApp(androidInfo.apkUrl())
                                                     .setAutoGrantPermissions(androidInfo.autoGrantPermissions())
                                                     .setDeviceName(androidInfo.device());

driver = new AndroidDriver(testGridInfo.url(), options);

补充:已实现点击操作,需改为长按

目前已实现点击逻辑,需要将其修改为长按操作:

int x = element.getLocation().getX() + (size.width / 2);
int y = element.getLocation().getY() + (size.height / 2);
PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence tap = new Sequence(finger, 1);
tap.addAction(finger.createPointerMove(Duration.ofMillis(0), PointerInput.Origin.viewport(), x, y));
tap.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
waitForTime(2000); // 模拟长按
tap.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
driver.perform(Arrays.asList(tap));

解决方案

问题原因

Appium 2.x版本后,旧的TouchAction API被逐步弃用,远程环境的Appium 2.5.1已不再支持该API,因此抛出UnsupportedCommandException。官方推荐使用W3C标准的PointerInput + Sequence API来实现触摸动作。

修改后的长按实现

基于你已有的点击代码,调整为标准的长按实现(替换掉waitForTime的不合理方式):

WebElement element = assertElement(new AppiumBy.ByAndroidUIAutomator("new UiSelector().resourceId(\"" + resourceId + "\")"));
Dimension size = element.getSize();
int x = element.getLocation().getX() + (size.width / 2);
int y = element.getLocation().getY() + (size.height / 2);

PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence longPressSequence = new Sequence(finger, 1);

// 1. 瞬间移动到元素中心位置
longPressSequence.addAction(finger.createPointerMove(Duration.ofMillis(0), PointerInput.Origin.viewport(), x, y));
// 2. 按下触摸点
longPressSequence.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
// 3. 保持按下状态2000毫秒(核心:通过move动作的duration实现长按,而非sleep)
longPressSequence.addAction(finger.createPointerMove(Duration.ofMillis(2000), PointerInput.Origin.viewport(), x, y));
// 4. 抬起触摸点,完成长按
longPressSequence.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));

// 执行动作序列
driver.perform(Arrays.asList(longPressSequence));

关键说明

  • 不要使用waitForTime阻塞线程,这会导致动作序列中断,不符合W3C动作API的原子性要求。
  • 通过createPointerMove的Duration参数指定长按持续时间,这是Appium 2.x支持的标准方式,兼容本地和远程环境。

内容的提问来源于stack exchange,提问作者rosu alin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:55:53