Android API22中AccessibilityService的粘贴在API17中不起作用

Android API22中AccessibilityService的粘贴在API17中不起作用,android,android-support-library,Android,Android Support Library,当我在API22上运行代码时,它工作正常,在启动访问事件的应用程序中,将“测试”粘贴到我所需的EditText。但当我在API 17上运行它时,它不起作用。它将数据复制到剪辑,但无法粘贴。我需要该机制在API 16及以上版本上工作 这是我目前的代码: public class MyAccessibilityService extends AccessibilityService { @Override public void onAccessibilityEvent(Access

当我在API22上运行代码时,它工作正常,在启动
访问事件的应用程序中,将“测试”粘贴到我所需的
EditText
。但当我在API 17上运行它时,它不起作用。它将数据复制到剪辑,但无法粘贴。我需要该机制在API 16及以上版本上工作

这是我目前的代码:

public class MyAccessibilityService extends AccessibilityService {
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        AccessibilityNodeInfo nodeInf = null;
        AccessibilityNodeInfo nodeInfo = null;
        final int eventType = event.getEventType();
        String eventText = null;
        switch(eventType) {
            case AccessibilityEvent.TYPE_VIEW_CLICKED:
                eventText = "Clicked: ";
                nodeInf = this.getRootInActiveWindow();
                Log.d("AccessibilityNodeInfo", ""+ nodeInf.getChildCount());
                nodeInf.recycle();
                break;
            case AccessibilityEvent.TYPE_VIEW_FOCUSED:
                AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
                AccessibilityNodeInfoCompat source = record.getSource();

                ClipboardManager clipboard = (ClipboardManager) this.getSystemService(Context.CLIPBOARD_SERVICE);
                ClipData clip = ClipData.newPlainText("label", "TESTING TESTING");
                clipboard.setPrimaryClip(clip);

                source.performAction(AccessibilityNodeInfoCompat.ACTION_PASTE);
                //}

                Log.d("AccessibilityNodeInfo", ""+ source.getClassName());
                Intent intent = new Intent(MyAccessibilityService.this, TestActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
                startActivity(intent);
                break;
        }


        eventText = eventText + event.getText();

        // Do something nifty with this text, like speak the composed string
        // back to the user.
        Log.d("Information", eventText);
        Toast.makeText(getApplicationContext(), eventText + " " + android.os.Build.VERSION.SDK_INT,
                Toast.LENGTH_LONG).show();
    }
}

也许您应该改进您的答案,并添加有关导入的更多详细信息


粘贴: 正如你在评论中提到的,更多的是关于从剪贴板中再次获取内容

从Android开始,您可以将复制的内容作为文本,如下所示:

// Examines the item on the clipboard. If getText() does not return null, the clip item contains the
// text. Assumes that this application can only handle one item at a time.
 ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);

// Gets the clipboard as text.
pasteData = item.getText();

// If the string contains data, then the paste operation is done
if (pasteData != null) {
    return;

// The clipboard does not contain text. If it contains a URI, attempts to get data from it
} else {
    Uri pasteUri = item.getUri();

    // If the URI contains something, try to get text from it
    if (pasteUri != null) {

        // calls a routine to resolve the URI and get data from it. This routine is not
        // presented here.
        pasteData = resolveUri(Uri);
        return;
    } else {

    // Something is wrong. The MIME type was plain text, but the clipboard does not contain either
    // text or a Uri. Report an error.
    Log.e("Clipboard contains an invalid data type");
    return;
    }
}

复制:

剪贴簿管理器有两种不同的变体。新的是蜂窝状的。您必须确保您的代码使用了正确的变体

看看这个代码示例:

int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
    android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    clipboard.setText("text to clip");
} else {
    android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); 
    android.content.ClipData clip = android.content.ClipData.newPlainText("text label","text to clip");
    clipboard.setPrimaryClip(clip);
}
intsdk=android.os.Build.VERSION.sdk\u int;
如果(sdk
这只是一个假设,因为该问题遗漏了一些信息。

不幸的是,它添加到API级别18中,因此不适用于API 17及更低版本
AccessibilityNodeInfoCompat
只是现有功能的包装,它不提供缺失功能的自定义实现

v4支持库的来源非常清楚:

AccessibilityNodeInfoCompat
中调用
performAction
时,支持库调用
IMPL.performAction

当API级别为16和17时,
IMPL
accessibilitynodeinfogelybeanimpl

这是
accessibilitynodeinfogelybeanimpl

正如您所看到的,标准的
android.view.accessibility.AccessibilityNodeInfo
的支持库调用
performAction
,因此如果系统不支持
操作粘贴
,v4支持库也不支持
操作粘贴

您可以检查此代码是否支持
ACTION\u PASTE

AccessibilityNodeInfoCompat source = record.getSource();
int supportedActions = source.getActions();
boolean isSupported = (supportedActions & AccessibilityNodeInfoCompat.ACTION_PASTE) == AccessibilityNodeInfoCompat.ACTION_PASTE;
Log.d(TAG, String.format("AccessibilityNodeInfoCompat.ACTION_PASTE %1$s supported", isSupported ? "is" : "is NOT"));

与复制方法无关。我希望我的代码能在API16及以上版本上运行。蜂巢是API11。此外,当我运行我的应用程序并尝试粘贴到浏览器地址字段时,它会粘贴AccessibilityService粘贴的内容。即AccessibilityService已将所需文本复制到剪贴板上。这只是“source.performation(AccessibilityNodeInfoCompat.ACTION_PASTE)”的问题不工作。@Rehanzahor您能提供一个小样本应用程序来进行一些测试吗?您检查过这个问题吗?兼容Android库的目的是允许开发人员在其应用程序中生成以前版本中不可用的功能。因此,AccessibilityNodeInfoCompat应该在API17 android中提供API18之后可用的功能。文档向itI确认了Android库兼容性的目的,不幸的是,事实并非如此。正如您刚才在类概述中共享的链接“用于访问API级别4之后以向后兼容方式引入的AccessibilityNodeInfo的帮助器”中所看到的。AccessibilityNodeInfoCompat不提供任何额外功能,帮助您访问现有功能。您提供的用于检查是否支持操作粘贴的代码无效。Android Studio标记supportedActions。我已经使用AccessibilityNodeInfoCompat的getActions方法进行了检查。事实证明,您是对的,AccessibilityNodeInfoCompat不支持API小于18的操作。谢谢
if (Build.VERSION.SDK_INT >= 22) {
    IMPL = new AccessibilityNodeInfoApi22Impl();
} else if (Build.VERSION.SDK_INT >= 21) {
    IMPL = new AccessibilityNodeInfoApi21Impl();
} else if (Build.VERSION.SDK_INT >= 19) { // KitKat
    IMPL = new AccessibilityNodeInfoKitKatImpl();
} else if (Build.VERSION.SDK_INT >= 18) { // JellyBean MR2
    IMPL = new AccessibilityNodeInfoJellybeanMr2Impl();
} else if (Build.VERSION.SDK_INT >= 16) { // JellyBean
    IMPL = new AccessibilityNodeInfoJellybeanImpl();
} else if (Build.VERSION.SDK_INT >= 14) { // ICS
    IMPL = new AccessibilityNodeInfoIcsImpl();
} else {
    IMPL = new AccessibilityNodeInfoStubImpl();
}
public static boolean performAction(Object info, int action, Bundle arguments) {
    return ((AccessibilityNodeInfo) info).performAction(action, arguments);
}
AccessibilityNodeInfoCompat source = record.getSource();
int supportedActions = source.getActions();
boolean isSupported = (supportedActions & AccessibilityNodeInfoCompat.ACTION_PASTE) == AccessibilityNodeInfoCompat.ACTION_PASTE;
Log.d(TAG, String.format("AccessibilityNodeInfoCompat.ACTION_PASTE %1$s supported", isSupported ? "is" : "is NOT"));