自动化工具 [appium][toast] windowmanager 自定义的 toast 消息,无法获取--已解决

bauul · 2017年10月11日 · 最后由 bauul 回复于 2017年10月13日 · 2487 次阅读

缘由

如题,对于开发人员使用 windowmanager 自定义的 toast 消息,无法获取

解决思路

在小伙伴@erickyang 的提示下,我又去看了一下 appium 下 ui2.0 服务获取 toast 的源码

private class Listener extends Thread{

    private long previousTime = currentTimeMillis();

    public void run() {

        while (true) {
            AccessibilityEvent accessibilityEvent = null;
            toastMessages = init();

            //return true if the AccessibilityEvent type is NOTIFICATION type
            UiAutomation.AccessibilityEventFilter eventFilter = new UiAutomation.AccessibilityEventFilter() {
                @Override
                public boolean accept(AccessibilityEvent event) {
                    return event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
                }
            };
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    // Not performing any event.
                }
            };

            try {
                //wait for AccessibilityEvent filter
                accessibilityEvent = UiAutomatorBridge.getInstance().getUiAutomation()
                        .executeAndWaitForEvent(runnable /*executable event*/, eventFilter /* event to filter*/, 500 /*time out in ms*/);
            } catch (Exception ignore) {}

            if (accessibilityEvent != null) {
                toastMessages = accessibilityEvent.getText();
                previousTime = currentTimeMillis();
                Logger.info("toastMessages getText:" + toastMessages);
                GetToastMessage.toastMessage = toastMessages.toString();// add by chenlg
            }
            if (stopLooping) {
                break;
            }
        }
    }

    public List<CharSequence> init(){
        if (currentTimeMillis() - previousTime  > TOAST_CLEAR_TIMEOUT) {
            return new ArrayList<CharSequence>();
        }
        return toastMessages;
    }
}

从这边可以看到是捕获的 AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED 事件,
然后和开发的同学沟通了一下,windowmanager 在弹窗的时候,发送的是什么样的事件?是否可以捕获?
开发的同学说他们可以主动发这个事件 AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED

主动发送事件的方法

AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
event.getText().add("hellowindowManager");
view.onPopulateAccessibilityEvent(event);
view.sendAccessibilityEventUnchecked(event);

拓展

以后对于不能捕获的 UI 无素,可以试试这种方法,捕获相关的信息,方便做自动化测试

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 8 条回复 时间 点赞

@Lihuazhang @xiaoli
请教下呢

bauul #1 回复

不好意思 这个我没用过呢

bauul #1 回复

自定义的 view,试试看直接用 xpath

恒温 #3 回复

怎么搞?可否举个例子呢?

试下监听 AccessibilityEvent 事件,可以抓取 Toast!

—— 来自 TesterHome 官方 安卓客户端

Crazyerick #5 回复

好的,谢谢

更新一下解决方法

@Lihuazhang
居然不能自己给自己点赞,哼

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册