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
相关产品推荐
相关产品推荐

