如何用Java获取安卓设置菜单全部元素而非仅可见元素?
问题:获取安卓设置菜单全部选项名称而非仅可见元素
我需要获取安卓设置菜单中的所有选项名称,当前编写的Appium Java代码只能拿到屏幕上可见的10个元素,希望能获取菜单中的全部元素。
当前代码
public static void main(String[] args) throws MalformedURLException, InterruptedException { DesiredCapabilities dc = new DesiredCapabilities(); dc.setCapability(MobileCapabilityType.AUTOMATION_NAME, "Appium"); dc.setCapability(MobileCapabilityType.DEVICE_NAME, "Redmi Note 9 Pro"); dc.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); dc.setCapability(MobileCapabilityType.PLATFORM_VERSION, "12.0"); dc.setCapability("appPackage", "com.android.settings"); dc.setCapability("appActivity", "com.android.settings.Settings"); URL url = new URL("http://127.0.0.1:4723/wd/hub"); AndroidDriver<WebElement> driver = new AndroidDriver<WebElement>(url, dc); MobileElement list = (MobileElement) driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView("+ "new UiSelector().text(\"Services & feedback\"));" )); Thread.sleep(5000); List <WebElement> list2 = driver.findElementsById("android:id/title"); System.out.println(list2.size()); for (WebElement i : list2) { System.out.println(i.getText()); } }
当前输出
10 Apps Additional settings Digital Wellbeing & parental controls Special features Mi Account Google Accounts & sync Privacy Location Services & feedback
解决方案
安卓设置菜单采用滚动加载机制,只有当前可见区域的元素会被渲染,因此需要循环滚动页面,逐步加载所有元素并去重,直到没有新元素出现。
修改后的代码如下:
import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.MobileCapabilityType; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; import java.net.MalformedURLException; import java.net.URL; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import com.google.common.collect.ImmutableMap; public class SettingsScraper { public static void main(String[] args) throws MalformedURLException, InterruptedException { DesiredCapabilities dc = new DesiredCapabilities(); // 改用UiAutomator2引擎,稳定性更好 dc.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator2"); dc.setCapability(MobileCapabilityType.DEVICE_NAME, "Redmi Note 9 Pro"); dc.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); dc.setCapability(MobileCapabilityType.PLATFORM_VERSION, "12.0"); dc.setCapability("appPackage", "com.android.settings"); dc.setCapability("appActivity", "com.android.settings.Settings"); URL url = new URL("http://127.0.0.1:4723/wd/hub"); AndroidDriver<WebElement> driver = new AndroidDriver<>(url, dc); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); // 用HashSet存储标题,自动去重 Set<String> allSettingsTitles = new HashSet<>(); int previousCount = 0; // 循环滚动加载,直到没有新元素 while (true) { // 获取当前所有可见的设置项标题 List<WebElement> currentElements = driver.findElementsById("android:id/title"); for (WebElement element : currentElements) { allSettingsTitles.add(element.getText().trim()); } // 如果元素数量不再增加,说明已加载全部 if (allSettingsTitles.size() == previousCount) { break; } previousCount = allSettingsTitles.size(); // 执行向下滚动操作 driver.executeScript("mobile: scrollGesture", ImmutableMap.of( "left", 500, "top", 1500, "width", 100, "height", 1000, "direction", "down", "percent", 1.0 )); Thread.sleep(1000); // 等待滚动加载完成 } // 输出结果 System.out.println("全部设置项数量:" + allSettingsTitles.size()); for (String title : allSettingsTitles) { System.out.println(title); } driver.quit(); } }
关键说明
- 滚动加载逻辑:通过循环滚动+对比元素数量,确保所有设置项都被加载到DOM中
- 去重处理:使用
HashSet存储标题,避免重复获取已加载的元素 - 引擎优化:更换为
UiAutomator2自动化引擎,兼容性和稳定性优于旧版Appium引擎 - 滚动方式:使用
scrollGesture执行滚动,比UiScrollable更适合循环滚动场景
内容的提问来源于stack exchange,提问作者user20468552
相关产品推荐
相关产品推荐

