¿Cómo hacer clic en el botón en la configuración mediante AccessibilityService?

Quiero hacer clic en el botón en la configuración de Android con AccessibilityService como lo hizo greenify, pero no puedo encontrar el botón específico. por favor, ayúdame.

MyAccessibilityService .java:

public class MyAccessibilityService extends AccessibilityService { private static final String TAG = MyAccessibilityService.class .getSimpleName(); @Override public void onAccessibilityEvent(AccessibilityEvent event) { Log.i(TAG, "ACC::onAccessibilityEvent: " + event.getEventType()); //TYPE_WINDOW_STATE_CHANGED = 32, if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event.getEventType()) { AccessibilityNodeInfo nodeInfo = event.getSource(); Log.i(TAG, "ACC::onAccessibilityEvent: nodeInfo=" + nodeInfo.getText()); List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId("com.android.settings:id/left_button"); for (AccessibilityNodeInfo node : list) { Log.i(TAG, "ACC::onAccessibilityEvent: " + event.getEventType() + " " + node); } 

EDITAR:

Sólo cuando el tipo es TYPE_WINDOW_STATE_CHANGED, podría obtener el objeto nodeInfo.

Abrir el Appinfo de una aplicación con el botón de cierre de la fuerza habilitado para probar:

 public class MyAccessibilityService extends AccessibilityService { private static final String TAG = MyAccessibilityService.class .getSimpleName(); @Override public void onAccessibilityEvent(AccessibilityEvent event) { Log.i(TAG, "ACC::onAccessibilityEvent: " + event.getEventType()); //TYPE_WINDOW_STATE_CHANGED == 32 if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event .getEventType()) { AccessibilityNodeInfo nodeInfo = event.getSource(); Log.i(TAG, "ACC::onAccessibilityEvent: nodeInfo=" + nodeInfo); if (nodeInfo == null) { return; } List<AccessibilityNodeInfo> list = nodeInfo .findAccessibilityNodeInfosByViewId("com.android.settings:id/left_button"); for (AccessibilityNodeInfo node : list) { Log.i(TAG, "ACC::onAccessibilityEvent: left_button " + node); node.performAction(AccessibilityNodeInfo.ACTION_CLICK); } list = nodeInfo .findAccessibilityNodeInfosByViewId("android:id/button1"); for (AccessibilityNodeInfo node : list) { Log.i(TAG, "ACC::onAccessibilityEvent: button1 " + node); node.performAction(AccessibilityNodeInfo.ACTION_CLICK); } } } @Override public void onServiceConnected() { Log.i(TAG, "ACC::onServiceConnected: "); } @Override public void onInterrupt() { // TODO Auto-generated method stub } } 

La respuesta seleccionada funciona en la API 18 y superior ya que se retransmite en findAccessibilityNodeInfosByViewId que se agregó en la API 18. Terminé escribiendo esta clase para admitir API 17 y siguientes.

ResourcesCompat clase ResourcesCompat encuentra los recursos identificados con la actividad dada que en nuestro caso debería ser la actividad de configuración de Android. Puede obtener la actividad ComponentName de los parámetros llamando a esta función al manejar el evento de accesibilidad en el Servicio de accesibilidad.

  public static ComponentName getForegroundActivity(Context context) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); ComponentName topActivity = taskInfo.get(0).topActivity; return topActivity; } 

Un buen lugar para llamar a init(...) está en onAccessibilityEvent cuando maneja el evento TYPE_WINDOW_STATE_CHANGED como se describe thecr0w .

 public class ResourcesCompat { private final static String RESOURCE_TYPE = "string"; private String mResourcesPackageName; private Resources mResources; /** * Find the resource file for a specific activity * * @param context * @param settingsPackageName * @param settingsClassName */ public void init(Context context, String settingsPackageName, String settingsClassName) { try { mResourcesPackageName = settingsPackageName; ComponentName settingsComponentName = new ComponentName(settingsPackageName, settingsPackageName + settingsClassName); mResources = context.getPackageManager().getResourcesForActivity(settingsComponentName); } catch (PackageManager.NameNotFoundException e) { } } /** * Return the localised string for the given resource name. * @param resourceName The name of the resource definition in strings.xml */ public String getString(String resourceName) { int resourceId = getIdentifier(resourceName); return resourceId > 0 ? mResources.getString(resourceId) : null; } /** * Return a resource identifier for the given resource name. * @param resourceName The name of the desired resource. * @return int The associated resource identifier. Returns 0 if no such resource was found. (0 is not a valid resource ID.) */ private int getIdentifier(String resourceName) { return mResources.getIdentifier(resourceName, RESOURCE_TYPE, mResourcesPackageName); } } 

Algunos fabricantes les gusta mover las clases y cambiar el nombre de las cadenas por defecto ( tos Tos Toshiba Tos Xiomi) Así que asegúrese de cubrir todos los casos y manejar errores y excepciones.

Finalmente, busque su opinión por su nombre. aquí, id puede ser 'force_stop' por ejemplo

 private List<AccessibilityNodeInfo> findAccessibilityNodeInfosByName(AccessibilityNodeInfo source, String id) { String nodeText = mResourcesCompat.getString(id); if (nodeText != null) { return source.findAccessibilityNodeInfosByText(nodeText); } return null; } 
  • Enfoque en movimiento dentro de un FrameLayout
  • Activar / desactivar mediante programación la configuración de accesibilidad en un dispositivo Android
  • AccessibilityNodeInfo - enviar texto
  • Cómo utilizar AccessibilityService para establecer texto en un EditText dentro de un navegador
  • Accesibilidad de Android com.android.settings: id / left_button sobre la fuerza no funciona
  • ¿Qué debo poner en el atributo contentDescription para las imágenes decorativas como el separador de campo?
  • Cómo dirigir a los usuarios para habilitar el servicio de accesibilidad para mi aplicación
  • ¿Cómo codificar Android para los discapacitados visuales?
  • Eliminar el foco de ActionBar android Accessibility
  • Cómo comprobar si Talkback está activo en JellyBean
  • Imagebutton me da error: Falta el atributo contentDescription en la imagen
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.