I have created my own accessibility service where I want to record events like app open and clicked for selected apps. This is working fine for xml views but for Compose views I don’t get AccessibilityEvent.TYPE_VIEW_CLICKED
event in onAccessibilityEvent(). Whenever Compose button is clicked I do get AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGE
. And if look at the node hierarchy I see a ComposeView which might be representing the Button but it has isClickable as false
.
Another observation is whenever I try this with TalkBack accessibility. I get clicked event for the Compose button in my onAccessibilityEvent()
and this time isClickable
is true
.
My compose views have all the required content description set up. But to be sure I also tried this with JetNews app from google’s code samples here. It gave the same result i.e. no click events.
Sharing my code here. How to make this work for Compose views?
override fun onServiceConnected() {
super.onServiceConnected()
Timber.d("$LOG_PREFIX Service connected")
val info = AccessibilityServiceInfo().apply {
eventTypes = getSupportedEventTypes()
packageNames = arrayOf(
"com.example.jetnews")
feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC
flags =
AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS or
AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS or
AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
notificationTimeout = 100
}
this.serviceInfo = info
}
override fun onAccessibilityEvent(event: AccessibilityEvent) {
if (RecordingState.isRecording.value != true) return
val source: AccessibilityNodeInfo? = event.source
source?.let {
if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED ) {
if (loggedAppLaunch) {
return
} else {
loggedAppLaunch = true
}
}
val eventType = event.eventType
val viewId = it.viewIdResourceName ?: "Unknown"
val text = extractText(it)
val packageName = event.packageName?.toString() ?: "Unknown"
val className = event.className?.toString() ?: "Unknown"
val eventTime = event.eventTime
val contentDescription = it.contentDescription?.toString() ?: "Unknown"
val eventData = EventData(
eventType = EventType.fromInt(eventType),
viewId = viewId,
text = text,
packageName = packageName,
className = className,
eventTime = eventTime,
contentDescription = contentDescription
)
Timber.d("$LOG_PREFIX EVENT data: $eventData")
}
}