appium 九宫格解锁招商银行手机客户端app
之前研究了一段时间的appium for native app 相应的总结如下:
appium测试环境搭建 :http://www.cnblogs.com/tobecrazy/p/4562199.html
知乎Android客户端登陆:http://www.cnblogs.com/tobecrazy/p/4579631.html
appium实现截图和清空EditText:http://www.cnblogs.com/tobecrazy/p/4592405.html
appium 滑动处理:http://www.cnblogs.com/tobecrazy/p/4612133.html
最近有人问我怎么使用web driver,所以特来研究一下:
appium for mobile web 之使用 ChromeDriver:http://www.cnblogs.com/tobecrazy/p/4836995.html
今天搞一下appium实现手势解锁。
效果如下:
首先看一下招行手机客户端app手势解锁的element,使用uiautomatorviewer看一下
可以看出,该手势解锁共有9个 android.widget.ImageView 构成,使用findelements获取实际上九宫格类似
0 1 2
3 4 5
6 7 8
如果实现九宫格解锁,就需要绘制解锁内容的手势,我在设置的手势是Z
就是0->1->2->4->6->7->8
第一步,使用appium(Android Studio)解析apk包,获取到package和activity
我的PC OS是win 10 ,appium 也是最新的1.4.x,很诡异的是只能获取到package 却获取不到activity。 这里有一个小小的tricky
第二步,代码实现
package com.dbyl.core; import org.apache.commons.io.FileUtils; import org.openqa.selenium.By; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.remote.DesiredCapabilities; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import io.appium.java_client.MobileDriver; import io.appium.java_client.TouchAction; import io.appium.java_client.android.AndroidDriver; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.List; import java.util.concurrent.TimeUnit; public class slideToUnlock { private MobileDriver driver; @BeforeMethod(alwaysRun = true) public void setUp() throws Exception { // set up appium DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(CapabilityType.BROWSER_NAME, ""); capabilities.setCapability("platformName", "Android"); capabilities.setCapability("deviceName", "Android Emulator"); capabilities.setCapability("platformVersion", "5.1"); // if no need install don't add this capabilities.setCapability("appPackage", "cmb.pb"); // no need sign capabilities.setCapability("noSign", "True"); capabilities.setCapability("appActivity", ".ui.PBInitActivity"); driver = new AndroidDriver<WebElement>(new URL( "http://127.0.0.1:4723/wd/hub"), capabilities); } @Test(groups = "swipeTest", priority = 1) public void swipeTest() { driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); // swipe to right System.out.println(driver.getPageSource()); // swipeToRight(driver, 2000); driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); driver.findElement(By.id("cmb.pb:id/item_funcIcon")).click(); driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); List<WebElement> pic = driver .findElements(By .xpath("//android.widget.FrameLayout/android.widget.ImageView")); for (int i = 0; i < pic.size(); i++) { System.out.println(pic.size()); pic.get(i).click(); } final TouchAction touchAction = new TouchAction(driver); touchAction.press(pic.get(0)).waitAction(1500).moveTo(pic.get(1)) .moveTo(pic.get(2)).moveTo(pic.get(4)).moveTo(pic.get(6)) .moveTo(pic.get(7)).moveTo(pic.get(8)).release(); touchAction.perform(); String username = driver.findElement(By.id("cmb.pb:id/gTvMenuTitle")) .getText(); System.out.println(username); } @AfterClass(alwaysRun = true) public void tearDown() throws Exception { driver.quit(); } /** * This Method create for take screenshot * * @author Young * @param drivername * @param filename */ public static void snapshot(TakesScreenshot drivername, String filename) { // this method will take screen shot ,require two parameters ,one is // driver name, another is file name String currentPath = System.getProperty("user.dir"); // get current work // folder File scrFile = drivername.getScreenshotAs(OutputType.FILE); // Now you can do whatever you need to do with it, for example copy // somewhere try { System.out.println("save snapshot path is:" + currentPath + "/" + filename); FileUtils .copyFile(scrFile, new File(currentPath + "\\" + filename)); } catch (IOException e) { System.out.println("Can't save screenshot"); e.printStackTrace(); } finally { System.out.println("screen shot finished, it's in " + currentPath + " folder"); } } public void swipeToRight(MobileDriver driver, int during) { int width = driver.manage().window().getSize().width; int height = driver.manage().window().getSize().height; driver.swipe(width / 4, height / 2, width * 5 / 6, height / 2, during); // wait for page loading } @AfterClass(alwaysRun = true) public void stopAppiumServer() { } }
/** * @see TouchShortcuts#swipe(int, int, int, int, int) */ @Override public void swipe(int startx, int starty, int endx, int endy, int duration) { TouchAction touchAction = new TouchAction(this); // appium converts press-wait-moveto-release to a swipe action touchAction.press(startx, starty).waitAction(duration) .moveTo(endx, endy).release(); touchAction.perform(); }
使用这个原理就能实现滑动,九宫格滑动解锁.
那么问题就来了,我是使用的是moveTo传入的是WebElement,而swipe是使用的X,Y坐标。
由于不同的app使用的九宫格并不同,有app使用的和招行app不同的,不能是单个的imageView,该怎么实现?
由于对坐标的滑动还没完全理解,所以接下来会继续研究。

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义