androidaccessibilityservice

stopping Android Accessibility UI Component on softKey "HOME" Button pressed


Created "AccessibilityService" and am able to show Hints based on the Text Entered.The Problem is i want to stop the activity service when the Host application Home Pressed. I have tried Adding

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
                  android:accessibilityEventTypes="typeAllMask|typeViewClicked|typeViewFocused"
                      android:canRequestFilterKeyEvents="true"
                    android:accessibilityFlags="flagRequestFilterKeyEvents"
                     android:description="@string/accessibility_service_description" />

With this am able to solve issue with phones which has Physical Button For "HOME". How to Stop the Accessibility service When "HOME" event for Soft Buttons Like Nexus 5.


Solution

  • ANSWER TO ORIGINAL QUESTION: "Detecting when the software 'Home' button is pressed?"

    As per Android documentation, Soft keyboards are not required to send hardware keyboard events and in fact the Android samples don't, so pretty much every software keyboard on the app store does not. You can only rely on the events from external Bluetooth and hardware keyboards.

    Simply put, you can't reliably do what you want, the APIs don't support it.

    ANSWER TO QUESTION EDIT:

    Let me reiterate, THERE IS NO "RELIABLE" WAY TO DO THIS.

    What you could do is listen for Screen change related events, and detect when the screen content matches the Home screen. Now, this is still going to be a very fragile solution. There is no consistent way to detect the Launcher Activity, vs any other Activity, and also no way to determine if perhaps the matcher you set up might match something that's not a Launcher Activity. But, here is what I think to be the most reasonable approach.

    public void onAccessibilityEvent(AccessibilityEvent e) {
    
        switch (e.getEventType()) {
            case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
            case AccessibilityEvent.TYPE_VIEW_SCROLLED:
            case AccessibilityEvent.TYPE_WINDOWS_CHANGED:
            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: {
                if (detectHomeScreen(getRootInActiveWindow()) {
                    //We are now at the "home" screen, do what you want here.
                }    
            }
        }
    }
    //A List of package names you know to be associated with "launcher" activities.  Populate this list in your classes static initialization block.
    private static ArrayList<String> LAUNCHER_PACKAGE_NAMES;
    
    private static boolean detectHomeScreen(AccessibilityNodeInfo rootNodeInfo) {
        return LAUNCHER_PACKAGE_NAMES.contains(rootNodeInfo.getPackageName().toString())
    }
    

    XML Configuration

    <?xml version="1.0" encoding="utf-8"?>
    <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
        android:description="@string/accessibility_service_description"
        android:accessibilityEventTypes="typeAllMask"
        android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds"
        android:canRetrieveWindowContent="true"
        android:notificationTimeout="100"
        android:settingsActivity="com.example.SettingsActivity"
        />
    

    The last one is cool. It allows you to set an Activity that will open up via the "Settings" button in the top right corner of the Accessibility Service configuration screen.