2015-05-03 12 views
18

Quando eseguo il mio codice su API22 funziona perfettamente, incollando il "Testing Test" nel mio richiesto EditText nell'app che ha avviato il AccessibilityEvent. Ma quando lo eseguo su API 17, non funziona. Copia i dati in clip ma non è in grado di incollarli. Richiedo che il meccanismo funzioni su API 16 e successive.Paste da AccessibilityService funziona in API22 non funziona in API17

Questo è il mio codice finora:

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

Sono state prese a questa domanda [AccessibilityService è avviato, ma non riceve AccessibilityEvents su Jellybean] (http://stackoverflow.com/questions/12019848/accessibilityservice-è-iniziato-ma-accessibilityevents-on-Jell non-non-ricevere-)? – Sufian

risposta

8

Sfortunatamente AccessibilityNodeInfo.ACTION_PASTE viene aggiunto nel livello API 18, per questo motivo non funziona con API 17 e versioni precedenti. AccessibilityNodeInfoCompat è solo un wrapper per le funzionalità esistenti, non fornisce un'implementazione personalizzata delle funzionalità mancanti.

Le fonti della libreria di supporto v4 sono abbastanza chiare:

Quando si chiama performAction nella AccessibilityNodeInfoCompat la libreria di supporto chiama IMPL.performAction[1]

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

IMPL è AccessibilityNodeInfoJellybeanImpl quando il livello di API è 16 e 17 [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(); 
} 

Questo è performAction in AccessibilityNodeInfoJellybeanImpl[3]

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

Come si può vedere la la libreria di supporto chiamata performAction dello standard android.view.accessibility.AccessibilityNodeInfo, quindi, se il sistema non supporta ACTION_PASTE anche la libreria di supporto v4 non supporta ACTION_PASTE.

È possibile controllare se ACTION_PASTE è supportato con questo codice:

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")); 
+0

Lo scopo della libreria Android di compatibilità è consentire allo sviluppatore di produrre funzionalità nelle sue app, che non sono disponibili nella versione precedente. Quindi AccessibilityNodeInfoCompat dovrebbe fornire le funzionalità disponibili dopo API18, in Android API 17. [AccessibilityNodeInfoCompat] (http://developer.android.com/reference/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.html) la documentazione lo conferma – RehanZahoor

+0

So qual è lo scopo della libreria Android di compatibilità, purtroppo questo non è il caso. Come puoi vedere nel link che hai appena condiviso nella panoramica della classe _ "Helper per accedere a AccessibilityNodeInfo introdotto dopo il livello API 4 in modalità compatibile con le versioni precedenti." _. AccessibilityNodeInfoCompat non fornisce alcuna funzionalità aggiuntiva, ti aiuta ad accedere alle funzionalità esistenti. –

+0

Il codice fornito per verificare se ACTION_PASTE è supportato non funziona. Flag di Android Studio supportatiActions. – RehanZahoor

2

forse si dovrebbe migliorare la vostra risposta e aggiungere qualche dettaglio in più sui tuoi importazioni.


incollare: Come lei ha ricordato nel tuo commento, è più su come ottenere la cosa dagli appunti di nuovo?

Alla Android Copy and Paste Documentation è possibile ottenere il contenuto copiato come testo come questo:

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

Copia:

Ci sono due diverse varianti del ClipBoardManager. Il nuovo è stato introdotto con Honeycomb. Devi assicurarti che il tuo codice utilizzi la variante corretta.

Guardate questo esempio di codice:

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

Questa è solo una supposizione, come la questione manca alcune informazioni.

+0

Non è un problema correlato al metodo di copia. Voglio che il mio codice funzioni su API16 e versioni successive. HoneyComb è API11. Inoltre, quando eseguo la mia app e provo a incollare nel campo Dire indirizzo browser, incolla ciò che viene incollato da AccessibilityService. Questo è il AccessibilityService ha copiato il testo richiesto negli appunti. ed è solo una questione di 'source.performAction (AccessibilityNodeInfoCompat.ACTION_PASTE);' non funziona. – RehanZahoor

+0

@RehanZahoor puoi fornire una piccola app di esempio che consente alcuni test? – mikepenz