
Android library enables view scraping through Accessibility Service, offering features like periodic view retrieval, tree debugging, DSL queries, and coordinated actions for enhanced interaction.
AnView is an android library which scrape android view with the help of Android Accessibility Service
Add this repository to the build.gradle.kts dependency on your android project.
Note: Get the latest version from the Maven Central (Available on top badge) and replace with <anview_version>.
// for multiplatform common module
implementation("com.jamshedalamqaderi.anview:anview:<anview_version>")
// or if you target other platform instead of android and jvm
// then add jvm module to the common module
implementation("com.jamshedalamqaderi.anview:anview-jvm:<anview_version>")
// only android project
implementation("com.jamshedalamqaderi.anview:anview-android:<anview_version>")Create a class and implement it with AnViewAccessibilityService instead of AccessibilityService or replace AccessibilityService with AnViewAccessibilityService
import com.jamshedalamqaderi.anview.services.AnViewAccessibilityService
class ExampleAccessibilityService : AnViewAccesibilityService{}Follow this docs to see how to setup an Accessibility Service with configurations
Make sure android:canRetrieveWindowContent="true" is true in the config.xml
Retrieve view node periodically.
import com.jamshedalamqaderi.anview.services.AnViewAccessibilityService
import kotlin.time.Duration.Companion.seconds
// Can be called from anywhere
// If service is not enabled by user then nothing will be observed by this observer
// On Every 1 second this callback function will be called with AccessibilityNodeInfo object
AnViewAccessibilityService.registerViewObserver("UNIQUE_TAG", 1.seconds){ nodeInfo ->
// do scrape operation here
}
// do not forget to remove observer from registered observers
fun onDestroy(){
AnViewAccessibilityService.removeViewObserver("UNIQUE_TAG")
}
Debug view tree for building query dsl using top to bottom tree structure
import com.jamshedalamqaderi.anview.ext.AccessibilityNodeInfoExt.toTreeString
// You can get latest view node
val nodeInfo : AccessibilityNodeInfo? = AnViewAccessibilityService.currentView()
// show nodeInfo with properties in a tree
// information can be used for building query dsl in next section
println(nodeInfo?.toTreeString())
Create query using DSL & find View node using extension functions
import com.jamshedalamqaderi.anview.dsl.anViewQuery
import com.jamshedalamqaderi.anview.ext.AccessibilityNodeInfoExt.*
val searchField = anViewQuery{
params{
param(ParamType.packageName, "com.jamshedalamqaderi.anview")
param(ParamType.className, "android.widget.ViewGroup")
param(ParamType.nodeIndex, "0") // selecting first index from same className's in the same list
}
query{
params{
param(ParamType.packageName, "com.jamshedalamqaderi.anview")
param(ParamType.className, "android.widget.EditText")
param(ParamType.text, "Search([a-z0-9A-Z])") // Regex is supported for some param type's
}
optionalQuery{ // Optional query will return parent node if no match found
param(ParamType.packageName, "com.jamshedalamqaderi.anview")
param(ParamType.className, "android.widget.TextView")
}
}
}
val matchedNode = nodeInfo?.findNode(searchField) // returns single node
val matchedNodeSkipFirst = nodeInfo?.findNode(searchField, skip = 0) // skip first matching result
val matchingNodes = nodeInfo?.findNodes(searchField) // return multiple matching node listUsing AnViewActions
import com.jamshedalamqaderi.anview.ext.AnViewActions.*
// extension functions for AccessibilityNodeInfo
// actions are made by the help of AccessibilityNodeInfo default actions
// you can perform more actions by using AccessibilityNodeInfo.performAction(actionId)
matchingNodeInfo.click() // clicking on a view node
matchingNodeInfo.longClick() // long click on a view node
matchingNodeInfo.swipeForward() // scroll node content to forward
matchingNodeInfo.swipeBackward() // scroll node content to backward
matchingNodeInfo.inputText("Hello, there!") // write text on editable widget
// Coordinated actions - requires api level (24+)
// same as Accessibility actions, but human like click with coordinated positions
matchingNodeInfo.tap() // clicking on a view node with center position
matchingNodeInfo.longTap() // long clicking on a view node with center position
matchingNodeInfo.swipeUp() // coordinated swipe up
matchingNodeInfo.swipeRight() // coordinated swipe right
matchingNodeInfo.swipeDown() // coordinated swipe down
matchingNodeInfo.swipeLeft() // coordinated swipe left
AnViewActions.swipe(startX, startY, endX, endY) // custom coordinated swipe function
AnViewActions.pressBack() // simulate back press on phone
AnViewActions.pressHome() // simulate home button press on phoneNeed help
AnView is an android library which scrape android view with the help of Android Accessibility Service
Add this repository to the build.gradle.kts dependency on your android project.
Note: Get the latest version from the Maven Central (Available on top badge) and replace with <anview_version>.
// for multiplatform common module
implementation("com.jamshedalamqaderi.anview:anview:<anview_version>")
// or if you target other platform instead of android and jvm
// then add jvm module to the common module
implementation("com.jamshedalamqaderi.anview:anview-jvm:<anview_version>")
// only android project
implementation("com.jamshedalamqaderi.anview:anview-android:<anview_version>")Create a class and implement it with AnViewAccessibilityService instead of AccessibilityService or replace AccessibilityService with AnViewAccessibilityService
import com.jamshedalamqaderi.anview.services.AnViewAccessibilityService
class ExampleAccessibilityService : AnViewAccesibilityService{}Follow this docs to see how to setup an Accessibility Service with configurations
Make sure android:canRetrieveWindowContent="true" is true in the config.xml
Retrieve view node periodically.
import com.jamshedalamqaderi.anview.services.AnViewAccessibilityService
import kotlin.time.Duration.Companion.seconds
// Can be called from anywhere
// If service is not enabled by user then nothing will be observed by this observer
// On Every 1 second this callback function will be called with AccessibilityNodeInfo object
AnViewAccessibilityService.registerViewObserver("UNIQUE_TAG", 1.seconds){ nodeInfo ->
// do scrape operation here
}
// do not forget to remove observer from registered observers
fun onDestroy(){
AnViewAccessibilityService.removeViewObserver("UNIQUE_TAG")
}
Debug view tree for building query dsl using top to bottom tree structure
import com.jamshedalamqaderi.anview.ext.AccessibilityNodeInfoExt.toTreeString
// You can get latest view node
val nodeInfo : AccessibilityNodeInfo? = AnViewAccessibilityService.currentView()
// show nodeInfo with properties in a tree
// information can be used for building query dsl in next section
println(nodeInfo?.toTreeString())
Create query using DSL & find View node using extension functions
import com.jamshedalamqaderi.anview.dsl.anViewQuery
import com.jamshedalamqaderi.anview.ext.AccessibilityNodeInfoExt.*
val searchField = anViewQuery{
params{
param(ParamType.packageName, "com.jamshedalamqaderi.anview")
param(ParamType.className, "android.widget.ViewGroup")
param(ParamType.nodeIndex, "0") // selecting first index from same className's in the same list
}
query{
params{
param(ParamType.packageName, "com.jamshedalamqaderi.anview")
param(ParamType.className, "android.widget.EditText")
param(ParamType.text, "Search([a-z0-9A-Z])") // Regex is supported for some param type's
}
optionalQuery{ // Optional query will return parent node if no match found
param(ParamType.packageName, "com.jamshedalamqaderi.anview")
param(ParamType.className, "android.widget.TextView")
}
}
}
val matchedNode = nodeInfo?.findNode(searchField) // returns single node
val matchedNodeSkipFirst = nodeInfo?.findNode(searchField, skip = 0) // skip first matching result
val matchingNodes = nodeInfo?.findNodes(searchField) // return multiple matching node listUsing AnViewActions
import com.jamshedalamqaderi.anview.ext.AnViewActions.*
// extension functions for AccessibilityNodeInfo
// actions are made by the help of AccessibilityNodeInfo default actions
// you can perform more actions by using AccessibilityNodeInfo.performAction(actionId)
matchingNodeInfo.click() // clicking on a view node
matchingNodeInfo.longClick() // long click on a view node
matchingNodeInfo.swipeForward() // scroll node content to forward
matchingNodeInfo.swipeBackward() // scroll node content to backward
matchingNodeInfo.inputText("Hello, there!") // write text on editable widget
// Coordinated actions - requires api level (24+)
// same as Accessibility actions, but human like click with coordinated positions
matchingNodeInfo.tap() // clicking on a view node with center position
matchingNodeInfo.longTap() // long clicking on a view node with center position
matchingNodeInfo.swipeUp() // coordinated swipe up
matchingNodeInfo.swipeRight() // coordinated swipe right
matchingNodeInfo.swipeDown() // coordinated swipe down
matchingNodeInfo.swipeLeft() // coordinated swipe left
AnViewActions.swipe(startX, startY, endX, endY) // custom coordinated swipe function
AnViewActions.pressBack() // simulate back press on phone
AnViewActions.pressHome() // simulate home button press on phoneNeed help