2016-04-22 1 views
2

Je suis en train d'écrire un service d'accessibilité Android qui se base sur l'obtention de l'identifiant de la vue actuellement sélectionnée, cependant sur certains appareils (Nexus 6P 6.0.1, Samsung Galaxy S6 edge + 5 + 6.0.1) Je ne reçois aucun id de vue à travers et sur les autres (HTC One M8 5.0.1) ça passe bien. Parce que cela fonctionne bien sur certains appareils, je suis sûr qu'il n'y a pas de problème avec mon code, cependant j'ai posté un cas de test minimal ci-dessous.AccessibilityService ne retourne pas les ID de vue

Est-ce que n'importe qui peut m'aider à obtenir mes identifiants de rapport de service sur tous les appareils?

Le service a11y

public class ViewIdLoggingAccessibilityService extends AccessibilityService { 
    @Override 
    public void onAccessibilityEvent(AccessibilityEvent event) { 
     AccessibilityNodeInfo source = event.getSource(); 
     if (source == null) { 
      Log.d("onAccessibilityEvent", "source was null for: " + event); 
     } else { 
      String viewIdResourceName = source.getViewIdResourceName(); 
      Log.d("onAccessibilityEvent", "viewid: " + viewIdResourceName); 
     } 
    } 

    @Override 
    public void onInterrupt() { 
     Log.d("!# onInterrupt", "called"); 
    } 
} 

Le AndroidManifest.xml

<manifest package="com.example.a11yservice" 
      xmlns:android="http://schemas.android.com/apk/res/android" 
    > 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" 
     > 

    <service 
     android:name=".ViewIdLoggingAccessibilityService" 
     android:label="@string/view_id_logging_service_label" 
     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> 

    </application> 

</manifest> 

serviceconfig.xml

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" 
    android:accessibilityEventTypes="typeViewClicked|typeViewFocused" 
    android:accessibilityFeedbackType="feedbackGeneric" 
    android:accessibilityFlags="flagReportViewIds" 
    android:canRetrieveWindowContent="true" 
    android:notificationTimeout="100" /> 

Répondre

3

Il est connu question et a été affecté au problème PSBA Tracker il y a quelque temps. Vous pouvez vérifier l'état du problème ici: "Accessibility Issue: flagReportViewIds has no effect on real devices in Android M".

Malheureusement, le problème existe même sur Android 7.0, mais j'ai trouvé une solution de contournement simple. Vous pouvez appeler la méthode refresh() sur l'objet AccessibilityNodeInfo pour le rafraîchir et collecter toutes les données manquantes y compris l'identifiant.

Quelque chose comme ça:

public void onAccessibilityEvent(AccessibilityEvent event) { 
    AccessibilityNodeInfo ani = event.getSource(); 
    if (ani != null) { 
     ani.refresh(); // to fix issue with viewIdResName = null on Android 6+ 
    } 
} 
+0

Perfect Answer! –

+0

Est-il possible d'obtenir le nom ** activity ** de la source de l'événement? Je veux envoyer un récepteur à cette activité, est-ce possible ?? s'il vous plaît, faites-moi savoir –

1

Je trouve que si le viewId n'est pas disponible, interroger l'élément focalisé semble fonctionner:

AccessibilityNodeInfo source = findFocus(AccessibilityNodeInfo.FOCUS_INPUT); 
    viewIdResourceName = source.getViewIdResourceName(); 

renvoie l'ID de vue correcte