javaandroidaccessibilityservice

android accessibility service accessibility button not working


I am attempting create an android accessibility service that uses the on screen accessibility button function as described here https://developer.android.com/guide/topics/ui/accessibility/service#button when the code from this article is ran on my test device (moto z4) running android 10. The function accessibilityButtonController.isAccessibilityButtonAvailable(); returns false. although according to the link provided above the only reason that this function should return false is on a device without software rendered navigation which my test device has. This is the sample I am using:


import android.accessibilityservice.AccessibilityButtonController;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;

public class MyAccessibilityService extends AccessibilityService {
    private AccessibilityButtonController accessibilityButtonController;
    private AccessibilityButtonController
            .AccessibilityButtonCallback accessibilityButtonCallback;
    private boolean mIsAccessibilityButtonAvailable;

    @Override
    protected void onServiceConnected() {
        Log.d("info", "connect");
        accessibilityButtonController = getAccessibilityButtonController();
        mIsAccessibilityButtonAvailable =
                accessibilityButtonController.isAccessibilityButtonAvailable();

        if (!mIsAccessibilityButtonAvailable) {
            Log.d("info", "not supported");
            return;
        }

        AccessibilityServiceInfo serviceInfo = getServiceInfo();
        serviceInfo.flags
                |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
        setServiceInfo(serviceInfo);

        accessibilityButtonCallback =
                new AccessibilityButtonController.AccessibilityButtonCallback() {
                    @Override
                    public void onClicked(AccessibilityButtonController controller) {
                        Log.d("MY_APP_TAG", "Accessibility button pressed!");

                        // Add custom logic for a service to react to the
                        // accessibility button being pressed.
                    }

                    @Override
                    public void onAvailabilityChanged(
                            AccessibilityButtonController controller, boolean available) {
                        if (controller.equals(accessibilityButtonController)) {
                            mIsAccessibilityButtonAvailable = available;
                        }
                    }
                };

        if (accessibilityButtonCallback != null) {
            accessibilityButtonController.registerAccessibilityButtonCallback(
                    accessibilityButtonCallback, null);
        }
    }
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    }

    @Override
    public void onInterrupt() {
    }


}

Solution

  • Did you define the flag FLAG_REQUEST_ACCESSIBILITY_BUTTON?

    According to the AccessibilityServiceInfo documentation, the flag FLAG_REQUEST_ACCESSIBILITY_BUTTON must be defined in accessibilityFlags of the metadata of the service if targeting APIs greater than API 29

    <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_description"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagDefault|flagReportViewIds|flagRetrieveInteractiveWindows|flagRequestAccessibilityButton"
    android:accessibilityFeedbackType="feedbackVisual"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"/>