从AccessibilityService粘贴API22不起作用的API17

当我在API22上运行我的代码时,它工作得很好,在启动AccessibilityEvent的应用程序中,在我需要的EditText中粘贴“Testing Testing”。 但是,当我在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(); } } 

Solutions Collecting From Web of "从AccessibilityService粘贴API22不起作用的API17"

不幸的是, AccessibilityNodeInfo.ACTION_PASTE被添加到API级别18中,因此它不适用于API 17和更低版本。 AccessibilityNodeInfoCompat只是现有function的封装,它不提供缺less的function的自定义实现。

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

当您在AccessibilityNodeInfoCompat调用performAction时,支持库调用IMPL.performAction [1]

 public boolean performAction(int action) { return IMPL.performAction(mInfo, action); } 

当API级别为16和17时, IMPLAccessibilityNodeInfoJellybeanImpl [2]

 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(); } 

这是AccessibilityNodeInfoJellybeanImpl performAction [3]

 public static boolean performAction(Object info, int action, Bundle arguments) { return ((AccessibilityNodeInfo) info).performAction(action, arguments); } 

正如您可以看到支持库调用标准android.view.accessibility.AccessibilityNodeInfo performAction ,所以如果系统不支持ACTION_PASTE那么v4支持库也不支持ACTION_PASTE

您可以检查此代码是否支持ACTION_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")); 

也许你应该改进你的答案,并添加一些关于你的import的更多细节。


粘贴:正如你在你的评论中提到的那样,更重要的是从剪贴板再次获取这个东西?

从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; } } 

复制:

ClipBoardManager有两种不同的变体。 新的一个是与蜂窝介绍。 您必须确保您的代码使用正确的变体。

看看这个代码示例:

 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); } 

这只是一个假设,因为这个问题错过了一些信息。