2012-06-15 9 views
6

Como he entendido esto es posible, desde aquí Detecting toast messages Pero no puedo ver ningún evento con fragmento de código del enlace.Catch toast event (desde cualquier aplicación) y obtener mensaje tostado

MyAccessibilityService.java

package com.test.toasts2; 

import android.accessibilityservice.AccessibilityService; 
import android.accessibilityservice.AccessibilityServiceInfo; 
import android.app.Notification; 
import android.os.Parcelable; 
import android.view.accessibility.AccessibilityEvent; 
import android.widget.Toast; 

public class MyAccessibilityService extends AccessibilityService { 

    @Override 
    public void onAccessibilityEvent(AccessibilityEvent event) { 
     System.out.println("event catched"); 
     Toast.makeText(this, "catched " + "!", Toast.LENGTH_SHORT).show(); 
     if(event.getEventType() != AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) 
      return; // event is not a notification 

     String sourcePackageName = (String)event.getPackageName(); 

     Parcelable parcelable = event.getParcelableData(); 
     if(parcelable instanceof Notification){ 
      // Statusbar Notification 
     } 
     else{ 
      // something else, e.g. a Toast message 
      String log = "Message: "+event.getText().get(0)+" [Source: "+sourcePackageName+"]"; 
      System.out.println(log); 
      // write `log` to file... 
     } 
    } 

       @Override 
       public void onInterrupt() { 
        // TODO Auto-generated method stub 
       } 

       @Override 
       protected void onServiceConnected() { 
        // TODO Auto-generated method stub 
        super.onServiceConnected(); 
        AccessibilityServiceInfo info = new AccessibilityServiceInfo(); 
        info.feedbackType = AccessibilityServiceInfo.DEFAULT; 
        setServiceInfo(info); 
       } 


} 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.test.toasts2" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk android:minSdkVersion="15" /> 

    <application> 
    <service android:name=".MyAccessibilityService" 
     android:label="label"> 
    <intent-filter> 
     <action android:name="android.accessibilityservice.AccessibilityService" /> 
    </intent-filter> 

    </service> 
</application> 

</manifest> 

parece que simplemente no se pone en marcha este servicio. ¿Que estoy haciendo mal?

Por qué estoy haciendo esto: Estoy instalando muchos accesos directos en el iniciador de stock desde mi aplicación. Tengo el problema de que estos accesos directos se colocan uno encima del otro en una celda (incluso Sleep 500 no ayudó). Así que estoy buscando la forma de instalarlos uno por otro. Pero, ¿cómo saber cuándo se instaló correctamente el acceso directo? Solo he encontrado un mensaje que ics launcher muestra al usuario.

+0

falta el permiso – njzk2

Respuesta

0

crear una actividad que construirá un intento y lo utilizará para comenzar su servicio.

algo así será el código dentro de la actividad.

Intent i = new Intent(YourActivity.this, MyAccessibilityService.class); 
startService(i); 

En su manifestará las intenciones de filtro para la actividad desempeñará la principal y lanzador de éste modo que lo hará la actividad que se ejecuta cuando el usuario (o ADB) se inicia la aplicación. La actividad comenzará su servicio para usted.

EDIT: Supongo que vio esta nota de la publicación que ha vinculado. ¿Y que no estás probando esto en 2.2?

Nota: Esto no funcionó para mí en Android 2.2 (parece que no detecta las tostadas), pero funcionó en Android 4.0.

+0

Estoy probando Android 4.0.3. Todavía no puede hacer que esto funcione, incluso con su código. – POMATu

+1

Esto no funcionará, no puede iniciar su propio servicio de accesibilidad o NO recibirá ningún evento de accesibilidad. – Tom

0

En primer lugar no debe estar tratando de coger el pan tostado, ya que es una llamada asincrónica que aparezca un pan tostado en la pantalla y se mantendrá en la pantalla dependiendo del momento, es posible dejar la aplicación y todavía tienen la tostada aparecen. NO debe preocuparse cuando termine la tostada ya que esto es irrelevante. Todo lo que se debe usar para tostar es SOLO para proporcionar al usuario información sobre un proceso en particular que está en proceso/hecho o simplemente información. No es para lo que estás tratando de hacer.

¿Por qué no solo envía una transmisión interna a su aplicación y la captura a través de un filtro de intención y luego de recibir esa transmisión, debe comenzar el servicio.

+0

No soy un autor de la aplicación que envía brindis. Así que no puedo modificarlo para ver la transmisión – POMATu

+0

Estoy instalando muchos accesos directos en el iniciador de stock desde mi aplicación. Tengo el problema de que estos accesos directos se colocan uno encima del otro en una celda (incluso Sleep 500 no ayudó). Así que estoy buscando la forma de instalarlos uno por otro. Pero, ¿cómo saber cuándo se instaló correctamente el acceso directo? Solo he encontrado un mensaje que ics launcher muestra al usuario. – POMATu

+0

Intente leer el código fuente de Android para ver si hay algún tipo de emisión después de que se haya producido ese evento en particular. Estoy bastante seguro de que no hay nada, pero no he visto el código fuente de ICS para los accesos directos del iniciador, es probable que sea lo mismo que GB, que solo tiene el propósito y lo pone en el iniciador y nada más. – JoxTraex

2

TYPE_NOTIFICATION_STATE_CHANGED generalmente se refiere a NotificationManager e iconos colocados en la barra de estado. No obstante, el siguiente código debería ayudar a arrojar algo de luz sobre el origen de un mensaje de Toast. En Android 4.0.4 ICS, Toast tiene una clase de android.widget.Toast, por lo que getClassName debería ser el truco.

Por lo que vale, el cambio parece haberse realizado en Android 4.0.3 para agregar y utilizar el siguiente método en Toast.TN

private void trySendAccessibilityEvent() { 
     AccessibilityManager accessibilityManager = 
       AccessibilityManager.getInstance(mView.getContext()); 
     if (!accessibilityManager.isEnabled()) { 
      return; 
     } 
     // treat toasts as notifications since they are used to 
     // announce a transient piece of information to the user 
     AccessibilityEvent event = AccessibilityEvent.obtain(
       AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED); 
     event.setClassName(getClass().getName()); 
     event.setPackageName(mView.getContext().getPackageName()); 
     mView.dispatchPopulateAccessibilityEvent(event); 
     accessibilityManager.sendAccessibilityEvent(event); 
    } 

Se puede ver la clase Toast en todas las versiones de Android here.

private final String getEventType(AccessibilityEvent event) { 
    switch (event.getEventType()) { 
     case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: 
      return "TYPE_NOTIFICATION_STATE_CHANGED"; 
     case AccessibilityEvent.TYPE_VIEW_CLICKED: 
      return "TYPE_VIEW_CLICKED"; 
     case AccessibilityEvent.TYPE_VIEW_FOCUSED: 
      return "TYPE_VIEW_FOCUSED"; 
     case AccessibilityEvent.TYPE_VIEW_LONG_CLICKED: 
      return "TYPE_VIEW_LONG_CLICKED"; 
     case AccessibilityEvent.TYPE_VIEW_SELECTED: 
      return "TYPE_VIEW_SELECTED"; 
     case AccessibilityEvent.TYPE_VIEW_SCROLLED: 
      return "TYPE_VIEW_SCROLLED"; 
     case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: 
      return "TYPE_VIEW_HOVER_EXIT"; 
     case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: 
      return "TYPE_VIEW_HOVER_ENTER"; 
     case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START: 
      return "TYPE_TOUCH_EXPLORATION_GESTURE_START"; 
     case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END: 
      return "TYPE_TOUCH_EXPLORATION_GESTURE_END"; 
     case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: 
      return "TYPE_WINDOW_STATE_CHANGED"; 
     case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: 
      return "TYPE_WINDOW_CONTENT_CHANGED"; 
     case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: 
      return "TYPE_VIEW_TEXT_SELECTION_CHANGED"; 
     case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: 
      return "TYPE_VIEW_TEXT_CHANGED"; 
    } 

    return "default"; 
} 

private final String getEventText(AccessibilityEvent event) { 
    StringBuilder sb = new StringBuilder(); 
    for (CharSequence s : event.getText()) { 
     sb.append(s); 
     sb.append('\n'); 
    } 
    return sb.toString(); 
} 

@Override 
public void onAccessibilityEvent(AccessibilityEvent event) 
{ 
    Log.v(TAG, String.format(
     "onAccessibilityEvent: [type] %s [class] %s [package] %s [time] 
     %s [fullscreen] %s [text] %s", getEventType(event), event.getClassName(), 
     event.getPackageName(), event.getEventTime(), Boolean.toString(
     event.isFullScreen()), getEventText(event))); 

    if (android.os.Build.VERSION.SDK_INT >= 14) 
     Log.v(TAG, "Window ID: " + Integer.toString(event.getWindowId()) + "."); 
} 

private void setServiceInfo(int feedbackType) 
{ 
    final AccessibilityServiceInfo info = new AccessibilityServiceInfo(); 
    // We are interested in all types of accessibility events. 
    info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; 
    // We want to provide specific type of feedback. 
    info.feedbackType = feedbackType; 
    // We want to receive events in a certain interval. 
    // info.notificationTimeout = EVENT_NOTIFICATION_TIMEOUT_MILLIS; 
    // We want to receive accessibility events only from certain packages. 
    // info.packageNames = PACKAGE_NAMES; 
    setServiceInfo(info); 
} 

private boolean isInfrastructureInitialized = false; 

@Override 
public void onServiceConnected() 
{ 
    if (isInfrastructureInitialized) return; 

    // Claim the events with which to listen to. 
    setServiceInfo(AccessibilityServiceInfo.FEEDBACK_ALL_MASK); 

    // We are in an initialized state now. 
    isInfrastructureInitialized = true; 
} 

Fuente: experiencia personal.

+0

Todavía no funciona. ¿Puedes compartir un proyecto con este código? Tal vez estoy haciendo algo mal ... – POMATu

+0

Lo siento, eso fue copiado de una aplicación mía y no estoy pegando la fuente completa. Puedo asegurarle que en Android 4.0.4 con Slim ICS en mi Verizon Galaxy Nexus, esto funciona, pero NO funciona en versiones anteriores de Android. No estoy seguro de que lo use en una aplicación, considerando lo poco confiable que es. – Tom

+0

Estoy usando android 4.0.3 en archos 80 g9. ¿Puede por favor también publicar su manifiesto? Shoud, comienzo el servicio con startservice()? – POMATu

Cuestiones relacionadas