如何检测或监控另一个Android应用程序中的EditText触摸?

3

能否在另一个Android应用程序中监视触摸编辑文本的行为?例如,当触摸特定Android应用程序中的编辑文本时,自动粘贴预先设置的某些单词。 PS. 如果不可能,是否有任何方法接收软键盘弹出广播?

1个回答

4

即使 EditText 属于另一个应用程序,也可以检测到它被触摸。但是,这只能通过可访问性服务来完成。

首先,您需要在xml文件夹中创建一个serviceconfig.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_permission_desc"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    />

其次,您需要创建一个AccessibilityService,如下所示:
public class MyAccessibilityService extends AccessibilityService {

    ...

    @Override
    public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
        switch(accessibilityEvent.getEventType()) {
            case AccessibilityEvent.TYPE_VIEW_CLICKED:
            case AccessibilityEvent.TYPE_VIEW_FOCUSED:
                try {
                    Class className = Class.forName(accessibilityEvent.getClassName().toString());

                    if (EditText.class.isAssignableFrom(className)) {
                        // An EditText was Clicked or Focused
                        // Use other methods from the accessibilityEvent to do what 
                        // you need to do
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }                 
                break;
        }
    } 

    ...

}

第三步,你需要将服务添加到AndroidManifest.xml文件中:

<service android:name=".MyAccessibilityService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/serviceconfig" />
</service>

最后,您需要通过辅助功能设置启用AccessibilityService。您可以直接通过以下方式进入:

startActivity(new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS));

编辑:

你不能通过AccessibilityEvent获取EditText。相反,你需要获取一个AccessibilityNodeInfo,并通过这个AccessibilityNodeInfo执行典型的EditText功能。

要获取AccessibilityNodeInfo,你需要调用以下代码:

AccessibilityNodeInfo nodeInfo = accessibilityEvent.getSource()==null ? null : accessibilityEvent.getSource();

然后,您可以执行特定的操作,如setText(),如下所示:
if (nodeInfo != null) {
    nodeInfo.refresh();
    Bundle bundle = new Bundle();
    bundle.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, newString);
    nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, bundle);
}

注意我如何在AccessibilityNodeInfo上使用performAction(),并使用操作AccessibilityNodeInfo.ACTION_SET_TEXT并传递一个带有键AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE的bundle。
这与在EditText View上调用setText()几乎相同。
如果您不想使用setText(),而是想直接将文本粘贴到EditText中,可以使用:
if (nodeInfo != null) {
    nodeInfo.refresh();
    nodeInfo.performAction(AccessibilityNodeInfo.ACTION_PASTE);
}

还有一个问题,当设置完文本后,是否可以自动提交? - Leon
我不明白你的意思。 - Jackey
抱歉,我会更清楚地表达,例如像论坛一样,在完成帖子后自动提交而不是手动点击提交按钮。 - Leon
如果你的意思是要使用AccessibilityEvents来检测EditText的文本是否被编辑过,那么是可以的。AccessibiltyEvent有一个事件类型称为TYPE_VIEW_TEXT_CHANGED。如果你监听这个事件,那么当EditText中的文本发生改变时,你将能够得到通知,从而允许你进行必要的操作。 - Jackey
另一个问题是在另一个应用程序中,提交按钮被限制在特定时间内点击,可能是一秒钟,仍然不知道如何通过这个时间限制。调用系统时间并将系统时间设置提前一秒钟?这样可以通过这个时间限制吗? - Leon
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接