好的,所以我正在开发一个自动接受lyft请求的应用程序,但我的代码没有使用performAction(AccessibilityNodeInfo.ACTION_CLICK);正确。
public class AutoService extends AccessibilityService {
private static LyftAdapter lyftAdapter = new LyftAdapter();
// Automated Service (onAccessibilityEvent)
@TargetApi(16)
@Override
public void onAccessibilityEvent(AccessibilityEvent event)
{
AccessibilityNodeInfo source = event.getSource();
String lyftPackage = "com.lyft.android.driver";
String packageName = Tools.getPackage(source);
if (!packageName.equals(lyftPackage))
{
event.recycle();
return;
}
if (source == null)
{
event.recycle();
return;
}
processUI(event.getSource());
}
public void processUI(AccessibilityNodeInfo source)
{
source = getRootInActiveWindow();
if (Tools.getPackage(source).equals("com.lyft.android.driver") || Tools.getPackage(source).equals("me.lyft.android"))
{
if (!Lyft_Status.equals("OFFLINE"))
{
lyftAdapter.processEvent(source);
}
else
{
Log.v(TAG, "Can't process UI: " + Lyft_Status);
}
}
if (source != null)
source.recycle();
}
}
public abstract class RideshareAdapter {
public void processEvent(final AccessibilityNodeInfo source)
{
final StringBuilder sb = new StringBuilder();
processSubEvent(source, 0, sb);
final String string = sb.toString();
if (string == null)
{
Log.v(TAG, "String is NULL");
return;
}
processUIText(source, string.toLowerCase());
}
// PROCESS SECONDARY EVENT
private void processSubEvent(final AccessibilityNodeInfo source, final int n, final StringBuilder sb) {
for (int i = 0; i < n; ++i) {
sb.append("\t");
}
if (source != null)
{
sb.append(Tools.getText(source));
sb.append("\n");
final int childCount = source.getChildCount();
for (int j = 0; j < childCount; ++j) {
final AccessibilityNodeInfo child = source.getChild(j);
processSubEvent(child, n + 1, sb);
if (child != null) {
child.recycle();
}
}
}
}
// CLICK THE SCREEN
protected void clickScreen(AccessibilityNodeInfo source, final String text)
{
final AccessibilityNodeInfo s = source;
new Handler().postDelayed(new Runnable() {
List<AccessibilityNodeInfo> list = s.findAccessibilityNodeInfosByText(text);
@Override
public void run() {
for (final AccessibilityNodeInfo node : list) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}, 1000);
}
}
public class LyftAdapter
extends RideshareAdapter
{
// LYFT ADAPTER
protected void processUIText(AccessibilityNodeInfo source, String text)
{
// RIDE REQUEST
if (text.contains("tap here to accept"))
{
clickScreen(source, "Tap here to accept");
{
}
The string comes out as (Just like it is shown):
Lyft
11 mins
away
Passenger Name
New
Tap here to accept
但出于某种原因,它触发了它会点击“点击此处接受”textview,但它实际上从未实现过。有什么建议吗?
答案 0 :(得分:0)
说实话,你的帖子很难阅读。您拥有的功能纯粹是出于组织目的而定义的,而不是因为它们是要重复使用的。这使得在StackOverflow帖子的过程中解析和理解变得非常困难......但是你没有提供足够的东西来复制和粘贴并在Android Studio中理解。
当您在StackOverflow上发布代码时,您应该选择最小的复制示例,并且您绝对应该删除随机日志调用。您可能需要它们来帮助您了解发生了什么,但希望我们不会这样做:)它们只会使事情变得混乱并使您的代码更难以阅读。这就是说,请允许我专注于一点,
请注意,我已经清理了一些糟糕的样式和调试语句。答案在代码注释中!
protected void clickScreen(final AccessibilityNodeInfo source, final String text)
{
new Handler().postDelayed(new Runnable() {
//Find ALL of the nodes that match the "text" argument.
List<AccessibilityNodeInfo> list = source.findAccessibilityNodeInfosByText(text);
@Override
public void run() {
//Non discrliminintly click them, whether they're buttons, or text fields or links... just click them and hope they do something.
for (final AccessibilityNodeInfo node : list) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
//Delay it for a second AFTER the function has been called for no particularly good reason besides perhaps invalidating all of the nodes in the heirarchy... GOOD CALL!
}, 1000);
}
鉴于上述问题和上述通用代码质量问题,很难提供简明的答案。这篇文章留下了太多潜在的问题。任何提供的答案都会在黑暗中被刺伤。我觉得问题很可能在我的代码注释中有所涉及,但它绝对可能在其他地方。此外,我为sass道歉!
所有这些,你可以试试这个版本的功能!
static void clickFirstMatchingNode(AccessibilityService service, final String text) {
final List<AccessibilityNodeInfo> list = service.getRootInActiveWindow().findAccessibilityNodeInfosByText(text);
for (AccessibilityNodeInfo node : list) {
//Check if the action completely successfully. Also, only click one of them. This is kind of an assumption, it also simplifies the logic. You can certainly write a version of this that clicks everything that matches!
if (node.performAction(AccessibilityNodeInfo.ACTION_CLICK)) return;
}
//If no node is successfully clicked Log some stuff!
Log.wtf(YourService.class.getName(), "Failed to click any nodes! WTF?: " + text);
}
注意:以上均未提及您使用辅助功能API的任何内容!我认为这很有趣。