如何使用UiAutomator关闭Android应用程序?

dwthyt8l  于 2022-12-09  发布在  Android
关注(0)|答案(7)|浏览(347)

如何使用UiAutomator API关闭特定的Android应用程序?例如,当您手动按下“最近使用”按钮并滑动您想关闭的应用程序时。

ztyzrc3y

ztyzrc3y1#

更好的方法(不针对设备、操作系统版本、UI或方向):

Runtime.getRuntime().exec(new String[] {"am", "force-stop", "pkg.name.of.your.app"});

在Android 6.0的Nexus 5X上进行了测试和工作

pb3s4cty

pb3s4cty2#

最好的选择是使用getUiDevice.pressRecentApps,这将为您加载最近的应用程序,然后使用uiautomator查看器进行截图,这样您就可以查看已加载的屏幕的xml。然后您可以使用此xml选择要使用滑动的对象

UiObject app = new UIObject(new UiSelector().resourceId("The id of the app");
app.swipeLeft(100);

或右侧
这应该能够关闭你的应用程序。xml将取决于你使用的android风格和设备。

umuewwlo

umuewwlo3#

这就是我如何杀死所有的Android应用程序一次与uiautomator:

public static void killApps()
{
    UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    try
    {
        device.pressHome();
        device.pressRecentApps();

        // Clear all isn't always visible unless you scroll all apps down
        int height = device.getDisplayHeight();
        int width = device.getDisplayWidth();
        device.swipe(width/2,height/2, width/2, height, 50);

        UiObject clear = device.findObject(new UiSelector()
            .resourceId("com.android.systemui:id/button")
            .text("CLEAR ALL")
        );
        if (clear.exists())
        {
            clear.click();
        }
    }
    catch (RemoteException e)
    {
        e.printStackTrace();
    }
    catch (UiObjectNotFoundException e)
    {
        e.printStackTrace();
    }
}
khbbv19g

khbbv19g4#

基于@user597159的解决方案,我得到了以下命令,以关闭泛指el 2 for Firebase测试实验室(即“walleye”设备类型)上的所有应用程序:

private void killAllApps() throws Exception {
    boolean keepSwiping = true;
    int maxSwipeAttempts = 10;
    uiDevice.pressRecentApps();

    for (int swipeAttempt=0; swipeAttempt<maxSwipeAttempts && keepSwiping; swipeAttempt++) {
        int height = uiDevice.getDisplayHeight();
        int width = uiDevice.getDisplayWidth();
        uiDevice.swipe(width / 2, height / 2, width, height / 2, 50);

        UiObject clearAll1 = uiDevice.findObject(new UiSelector().text("Clear all"));
        UiObject clearAll2 = uiDevice.findObject(new UiSelector().textStartsWith("Clear all"));
        UiObject clearAll3 = uiDevice.findObject(new UiSelector().textContains("Clear all"));
        UiObject clear = clearAll1.exists() ? clearAll1 :
                (clearAll2.exists() ? clearAll2 : clearAll3);

        if (clear.exists()) {
            Logger.debug(TAG, "Attempting to close app by killAllApps and found clear=all button on swipeAttempt=" + swipeAttempt);
            clear.click();
            keepSwiping = false;
        } else {
            Logger.debug(TAG, "Attempting to close app by killAllApps but have to keep swiping swipeAttempt=" + swipeAttempt);
            keepSwiping = true;
        }
    }
}

请注意,像素2上的拼写为“Clear all”,而不是“CLEAR ALL”。
我无法让其他一些解决方案工作。我得到了UiObjectNotFoundException的以下内容:

app = uiDevice.findObject(new UiSelector().textContains("SDK Test App"));

并且还为:

app = uiDevice.findObject(new UiSelector().className(com.locuslabs.android.sdk.SdkTestApplication.class));

换句话说,对于尝试在应用上向上滑动以关闭像素2的这些方法,app.exists()返回false。

krugob8w

krugob8w5#

当只有一个应用程序将出现在最近的应用程序列表中时,这对我很有效。

if(mDevice.pressRecentApps()) {
            Thread.sleep(1000);
            int startX = 300; int startY =835; int endX = 1000; int endY = 835; // co-ordinates refer to x-axis from left of screen to right.
            int steps = 8;// speed at which the app closes
            mDevice.swipe(startX,startY,endX,endY,steps);
        }
krugob8w

krugob8w6#

这里有一个类似于this answer的Kotlin答案。它向UiDevice添加了一个扩展函数来清除所有任务。我在泛指el 2模拟器上测试了这个。

fun UiDevice.clearAllTasks(swipeAttempts: Int = 10 ) {
    pressRecentApps()

    var currentAttempt = 1
    val centerScreenX = displayWidth / 2
    val centerScreenY = displayHeight / 2
    while (currentAttempt <= swipeAttempts) {
        Timber.d("Clear all tasks attempt $currentAttempt")
        swipe(centerScreenX, centerScreenY, displayWidth, centerScreenY, 50)
        val uiObject = findObject(UiSelector().text("Clear all"))
        if (uiObject.exists()) {
            uiObject.click()
            break
        } else {
            currentAttempt++
        }
    }
}
oo7oh9g9

oo7oh9g97#

因此,我采取了一个更全面的方法,这在它似乎相当不可靠的其他答案。我使用了很多自定义扩展,所以会尝试张贴他们中的大部分:

fun UiDevice.clearTasks(swipes: Int = 2) {
    logInfo { message("clearTasks swipes:$swipes") }
    pressHome()
    wait()
    pressRecentApps()
    wait()
    repeat(swipes) {
        if (context.isPortrait)
            swipe(centerScreenX, centerScreenY, centerScreenX, 50, 10)
        else
            swipe(centerScreenX, centerScreenY, 25, centerScreenY, 10)
        wait()
    }
}

fun UiDevice.wait(seconds: Int = defaultWaitTime) {
    logInfo { message("wait:$seconds") }
    waitForWindowUpdate(null, seconds * SecondLong)
    waitForMoreIdle()
}

fun UiDevice.waitForMoreIdle(times: Int = 3) {
    logInfo { message("waitForMoreIdle times:$times") }
    repeat(times) { waitForIdle() }
}

val UiDevice.centerScreenX get() = displayWidth / 2

val UiDevice.centerScreenY get() = displayHeight / 2

val Context.isPortrait get() = resources.configuration.orientation == ORIENTATION_PORTRAIT

val context: Context get() = ApplicationProvider.getApplicationContext()

注:我不太喜欢一些文字,因为它取决于手机上的语言,可以是不同的。我也更喜欢这种自定义滑动时间的方法,因为我知道有多少任务大约我需要清除了大部分时间。有显示应用程序启动器的副作用,但谁在乎。没有找到一种方法来检测它取消滑动尚未。

相关问题