AccessibilityService events delayed by 1-2 seconds on Samsung devices during Fragment/Activity transitions


I am building a personal App Blocker with Claude's help that restricts access to the Settings -> Accessibility page using an AccessibilityService.

The scanning logic is heavily optimized (takes ~7ms to execute), but on Samsung devices (especially Samsung S25), there is a 1.5 to 2-second delay before my service even receives the AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED or TYPE_WINDOW_STATE_CHANGED event when navigating into the Accessibility menu. It seems Android/Samsung freezes event delivery while the screen-sliding animation plays. I'm not sure how to navigate this issue as I have tried setting notificationTimeout = 0 in AccessibilityServiceInfo, using event.source instead of rootInActiveWindow to bypass global window delays, trying to intercept TYPE_VIEW_CLICKED before the transition happens (didn't catch the tap reliably, likely because the tap lands on a wrapper ViewGroup rather than the TextView).

Here is the setup:

1. Service Configuration:

override fun onServiceConnected() {
    this.serviceInfo = AccessibilityServiceInfo().apply {
        eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED or 
                     AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED or
                     AccessibilityEvent.TYPE_VIEW_CLICKED
        feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC
        flags = AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS or 
                AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS
        notificationTimeout = 0 
    }
}

2. Event Interception:

override fun onAccessibilityEvent(event: AccessibilityEvent?) {
    val packageName = event?.packageName?.toString() ?: return
    
    // Only scan if we are inside a Settings app
    if (packageName.contains("settings", ignoreCase = true) || 
        packageName.contains("accessibility", ignoreCase = true)) {
        
        val rootNode = event.source ?: rootInActiveWindow
        if (isRestrictedSettingsPage(rootNode)) {
            performGlobalAction(GLOBAL_ACTION_HOME)
        }
    }
}

3. Node Scanning Logic (BFS):

private fun isRestrictedSettingsPage(rootNode: AccessibilityNodeInfo?): Boolean {
    if (rootNode == null) return false
    val queue = ArrayDeque<AccessibilityNodeInfo>()
    queue.add(rootNode)

    while (queue.isNotEmpty()) {
        val currentNode = queue.removeFirst()
        val text = currentNode.text?.toString() ?: currentNode.contentDescription?.toString()

        if (text != null && text.contains("Accessibility shortcuts", ignoreCase = true)) {
            return true
        }

        for (i in 0 until currentNode.childCount) {
            currentNode.getChild(i)?.let { queue.add(it) }
        }
    }
    return false
}

The Logs proving the OS delay:

Notice the 1.5-second gap between when the first screen finishes scanning and when the OS finally delivers the CONTENT_CHANGED event for the next screen.

22:45:51.985 D --- END UI TREE SCAN --- (Main settings menu) 22:45:51.985 D No banned keywords found on this scan. *(I click "Accessibility" here. The screen slides in. The service gets nothing until 1.5s later)* 22:45:53.551 D => EVENT FIRED: CONTENT_CHANGED 22:45:53.565 D Found Accessibility Keyword inside: 'Accessibility shortcuts' 22:45:53.565 D Match Found! Blocking settings page instantly 22:45:53.566 I performGlobalAction(GLOBAL_ACTION_HOME) triggered

I'm not sure if the problem stems from my code or it's a problem for that specific phone, since the app successfully detects the setting pages on other older Samsung devices like Note10 lite running on android 13. How can I block the "Accessibility" page in Samsung's settings successfully? For example, if you know any documentation on how other blocker apps navigate through this issue, I'd love to see it.

Update: I logged the entire process again and noticed that after I restart the phone, there are two processes that come before my accessibility function fires off. They are com.samsung.android.honeyboard | v0 Universal SwitchOn and com.samsung.android.honeyboard | v0 Voice Assistant On. My code blocks successfully right after that.

Update 2: I dug a little deeper and in the logs, I saw FreecessController and OLAF restriction. These weren't happening in the past versions of OneUI as much as I know, or at least they didn't cause any disturbances. Can these be the cause? Why would they appear and meddle with accessibility alerts?

0
Aug 4 at 4:47 AM
User AvatarBardia Kazemi
#android#kotlin#samsung-mobile#accessibilityservice

No answer found for this question yet.