Search code examples
androidandroid-activityandroid-event

onAccessibityEvent not called in Android


i tried to get some tutorials on accessibility events. and i found one accessibility tutorial. it is good & i implemented in eclipse & running in my tablet 5.1.1, nexus.

Coding.

MyAccessibilityService.java

    public class MyAccessibilityService extends AccessibilityService {
        public static final String TAG = "volumeMaster";
        @Override
        public void onAccessibilityEvent(AccessibilityEvent event)
        {
            Log.v(TAG, "***** onAccessibilityEvent");
            Toast.makeText(getApplicationContext(), "Got event from: " + event.getPackageName(), Toast.LENGTH_LONG).show();
            String s=String.valueOf(event.getEventType());
            Toast.makeText(MyAccessibilityService.this, s, Toast.LENGTH_LONG).show();
            Toast.makeText(MyAccessibilityService.this, getEventText(event), Toast.LENGTH_LONG).show();
            Log.v(TAG, String.format(
                    "onAccessibilityEvent: [type] %s [class] %s [package] %s [time] %s [text] %s",
                    getEventType(event), event.getClassName(), event.getPackageName(),
                    event.getEventTime(), getEventText(event)));
        }   `
        private 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_WINDOW_STATE_CHANGED:
                    return "TYPE_WINDOW_STATE_CHANGED";
                case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
                    return "TYPE_VIEW_TEXT_CHANGED";
            }
            return "default";
        }
        private String getEventText(AccessibilityEvent event) {
            StringBuilder sb = new StringBuilder();
            for (CharSequence s : event.getText()) {
                sb.append(s);
            }
            return sb.toString();
           }
        @Override
        public void onInterrupt()
        {
            Log.v(TAG, "***** onInterrupt");
        }
        @Override
        public void onServiceConnected()
        {
            Log.v(TAG, "***** onServiceConnected");      
            AccessibilityServiceInfo info = new AccessibilityServiceInfo();
            info.eventTypes =   AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
            info.notificationTimeout = 100;
            info.feedbackType = AccessibilityEvent.TYPES_ALL_MASK;
            setServiceInfo(info);
        }

}

In this code if i remove getEventType & getEventtext function it showing event type as 64 something. if i add these two function i cant get the event actions. i tried several time and i switched on my app to listen events in accessibility tap.

My manifest file is below Androidmanifest.xml

     <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name" 
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <service android:name=".MyAccessibilityService" android:label="@string/app_name" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
             <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility" />
         </service>
            <activity
                android:name=".Toast2Activity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>

can any one help me to find out the defects which i made in this code. thanks in advance.


Solution

  • Just tried this on Android 4.4 and 5.0 a few days ago, it worked fine. If you already defined everything in the config-xml("@xml/accessibility"), then there's no need to set AccessibilityServiceInfo in onServiceConnected(). And in AndroidManifest.xml you set “android:permission” in Application, I don't know if it's ok.

    public class MyAccessibilitySvc extends AccessibilityService {
        private static final String TAG = "MyAccessibilitySvc";
    
        @Override
        protected void onServiceConnected() {
            super.onServiceConnected();
        }
    
        @Override
        public void onAccessibilityEvent(AccessibilityEvent event) {
            AccessibilityNodeInfo nodeInfo = event.getSource();
            if (null == nodeInfo) return;
            Log.i(TAG, "onAccessibilityEvent: event=" + event);
        }
    
        @Override
        public void onInterrupt() {
    
        }
    }
    

    In AndroidManifest.xml:

        <service android:name=".MyAccessibilitySvc"
            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/accessibilitysvc_config"/>
        </service>
    

    xml config:

    <?xml version="1.0" encoding="utf-8"?>
    <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
        android:accessibilityEventTypes="typeViewFocused|typeViewClicked"
        android:accessibilityFeedbackType="feedbackAllMask"
        android:notificationTimeout="100"
        android:canRetrieveWindowContent="true"
        />