[android] Get text from AccessibilityEvent

android os version < 4.3

 

public static boolean isContainedInAccessbility(Context $context)
{
  AccessibilityManager accessibilityManager = (AccessibilityManager) $context.getSystemService(Context.ACCESSIBILITY_SERVICE);
  List<AccessibilityServiceInfo> serviceList = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
  return serviceList.toString().contains($context.getPackageName());
}

 

if (!isContainedInAccessbility(getApplicationContext()))
{
  Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
  startActivityForResult(intent, 111);
}

 

 

public class AccessibilityServiceForBeforeJellybeanMR2 extends AccessibilityService
{
  @Override
  public void onAccessibilityEvent(AccessibilityEvent event)
  {
    String msg = null;

    if (TextUtils.isEmpty(event.getText().toString().replace("[", "").replace("]", "").trim()))
      msg = getText(event);
    else
      msg = event.getText().toString();

    Log.i("###", "msg = " + msg);
  }

  private String getText(AccessibilityEvent event)
  {
    try
    {
      Notification notification = (Notification) event.getParcelableData();
      RemoteViews views = notification.contentView;
      Class<?> secretClass = views.getClass();
      
      Field outerFields[] = secretClass.getDeclaredFields();
      for (int i = 0; i < outerFields.length; i++)
      {
        if (!outerFields[i].getName().equals("mActions"))
          continue;
        
        outerFields[i].setAccessible(true);
        
        int count = 0;
        
        @SuppressWarnings("unchecked")
        ArrayList<Object> actions = (ArrayList<Object>) outerFields[i].get(views);
        for (Object action : actions)
        {
          Field innerFields[] = action.getClass().getDeclaredFields();
          
          Object value = null;
          Integer type = null;
          
          for (Field field : innerFields)
          {
            field.setAccessible(true);
            
            if (field.getName().equals("value"))
              value = field.get(action);
            else if (field.getName().equals("type"))
              type = field.getInt(action);
          }
          
          if (type != null && (type == 9 || type == 10))
          {
            count++;
            
            if (count == 2)
              return value.toString();
          }
        }
      }
    }
    catch (Exception e)
    {
//      e.printStackTrace();
    }
    
    return null;
  }

  @Override
  protected void onServiceConnected()
  {
    AccessibilityServiceInfo info = new AccessibilityServiceInfo();
    info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
    info.notificationTimeout = 0;
    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
    setServiceInfo(info);
  }

  @Override
  public void onInterrupt()
  {

  }
}

 

 

<service
    android:name="kr.mint.test.services.AccessibilityServiceForBeforeJellybeanMR2"
    android:enabled="true"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
    <intent-filter android:priority="2147483647" >
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>

    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibilityservice" />
</service>

 

 

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackSpoken|feedbackHaptic|feedbackAudible|feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_msg"
    android:notificationTimeout="0"
    android:settingsActivity="com.google.android.marvin.voicify.VoicifyActivity" />